Skip to content

Commit b338cea

Browse files
authored
Merge pull request #184 from AppsFlyerSDK/releases/6.x.x/6.17.x/6.17.8-rc2
Merge releases/6.x.x/6.17.x/6.17.8-rc2 into main
2 parents 2a2678a + efa48d1 commit b338cea

12 files changed

Lines changed: 173 additions & 125 deletions

File tree

.github/workflows/deploy-to-QA.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ jobs:
88
runs-on: ubuntu-latest
99
environment: Staging
1010
steps:
11-
- uses: actions/checkout@v3
11+
- uses: actions/checkout@v4
1212
with:
1313
token: ${{ secrets.CI_DEV_GITHUB_TOKEN }}
1414
persist-credentials: true
1515
- name: Setup Node.js
16-
uses: actions/setup-node@v3
16+
uses: actions/setup-node@v4
1717
with:
1818
node-version: 20.x
1919
- name: Install dependency
@@ -55,14 +55,13 @@ jobs:
5555
- name: Build Plugin
5656
run: |
5757
npm run build
58-
- name: Push to NPM
58+
- name: Publish to NPM (Token-based)
5959
env:
6060
CI_NPM_TOKEN: ${{ secrets.CI_NPM_TOKEN }}
6161
run: |
6262
echo "//registry.npmjs.org/:_authToken=$CI_NPM_TOKEN" > ~/.npmrc
6363
npm publish --tag QA
6464
65-
6665
- name: Generate and send slack report
6766
env:
6867
SLACK_TOKEN: ${{ secrets.CI_SLACK_TOKEN }}

.github/workflows/release-Production-workflow.yml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,21 @@ jobs:
2727
needs: [ Build-Sample-Apps ]
2828
if: github.event.pull_request.merged == true
2929
runs-on: ubuntu-latest
30+
permissions:
31+
id-token: write # Required for npm OIDC trusted publishing
32+
contents: read
3033
steps:
31-
- uses: actions/checkout@v3
34+
- uses: actions/checkout@v4
3235
with:
3336
token: ${{ secrets.CI_DEV_GITHUB_TOKEN }}
3437
persist-credentials: true
3538
- name: Setup Node.js
36-
uses: actions/setup-node@v3
39+
uses: actions/setup-node@v4
3740
with:
3841
node-version: 20.x
42+
registry-url: 'https://registry.npmjs.org'
43+
- name: Ensure latest npm (required for trusted publishing)
44+
run: npm install -g npm@latest
3945
- name: Install dependency
4046
run: |
4147
npm i rimraf
@@ -84,13 +90,10 @@ jobs:
8490
core.setFailed(error.message);
8591
}
8692
87-
- name: Push to NPM
88-
env:
89-
CI_NPM_TOKEN: ${{ secrets.CI_NPM_TOKEN }}
93+
- name: Publish to NPM (Trusted Publisher)
9094
run: |
91-
echo "//registry.npmjs.org/:_authToken=$CI_NPM_TOKEN" > ~/.npmrc
9295
npm run build
93-
npm publish
96+
npm publish --provenance --access public
9497
9598
- name: Generate and send slack report
9699
env:

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 6.17.8
2+
Release date: *2025-12-24*
3+
4+
5+
16
## 6.17.7
27
Release date: *2025-10-28*
38

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ To do so, please follow [this article](https://support.appsflyer.com/hc/en-us/ar
1313

1414
### <a id="plugin-build-for"> This plugin is built for:
1515

16-
<img src="https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/android/android.png" width="18" height="18"> Android AppsFlyer SDK **6.17.3**</br>
17-
<img src="https://icon.icepanel.io/Technology/svg/Apple.svg" width="18" height="18"> iOS AppsFlyer SDK **6.17.7**</br>
16+
<img src="https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/android/android.png" width="18" height="18"> Android AppsFlyer SDK **6.17.5**</br>
17+
<img src="https://icon.icepanel.io/Technology/svg/Apple.svg" width="18" height="18"> iOS AppsFlyer SDK **6.17.8**</br>
1818
<img src="https://icon.icepanel.io/Technology/svg/Capacitor.svg" width="18" height="18"> Capacitor 7</br>
1919

2020
## <a id="breaking-changes-6-17-0"> ❗❗ Breaking changes when updating to v6.17.0 ❗❗

android/src/main/java/capacitor/plugin/appsflyer/sdk/AppsFlyerPlugin.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,7 @@ class AppsFlyerPlugin : Plugin() {
399399
linkGenerator.generateLink(context, listener)
400400
}
401401

402+
@Deprecated("Use validateAndLogInAppPurchaseV2 instead")
402403
@PluginMethod
403404
fun validateAndLogInAppPurchaseAndroid(call: PluginCall) {
404405
val currency = call.getString(AF_CURRENCY)
@@ -439,6 +440,7 @@ class AppsFlyerPlugin : Plugin() {
439440
}
440441
}
441442

443+
@Deprecated("Use validateAndLogInAppPurchaseV2 instead")
442444
@PluginMethod
443445
fun validateAndLogInAppPurchaseIos(call: PluginCall) {
444446
call.unavailable()

docs/API.md

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ The list of available methods for this plugin is described below.
4040
* [`disableCollectASA`](#disablecollectasa)
4141
* [`setHost`](#sethost)
4242
* [`generateInviteLink`](#generateinvitelink)
43-
* [`validateAndLogInAppPurchaseAndroid`](#validateandloginapppurchaseandroid)
44-
* [`validateAndLogInAppPurchaseIos`](#validateandloginapppurchaseios)
45-
<!-- * [`validateAndLogInAppPurchaseV2`](#validateandloginapppurchasev2) - **Beta** - Since 6.17.3 -->
43+
* [`validateAndLogInAppPurchaseAndroid` (Deprecated)](#validateandloginapppurchaseandroid)
44+
* [`validateAndLogInAppPurchaseIos` (Deprecated)](#validateandloginapppurchaseios)
45+
* [`validateAndLogInAppPurchaseV2`](#validateandloginapppurchasev2) - Since 6.17.3
4646
* [`getSdkVersion`](#getsdkversion)
4747
* [`enableFacebookDeferredApplinks`](#enablefacebookdeferredapplinks)
4848
* [`sendPushNotificationData`](#sendpushnotificationdata)
@@ -673,7 +673,11 @@ Allowing your existing users to invite their friends and contacts as new users t
673673
--------------------
674674

675675

676-
### validateAndLogInAppPurchaseAndroid
676+
### validateAndLogInAppPurchaseAndroid (Deprecated)
677+
---
678+
> [!WARNING]
679+
> This API is deprecated since version 6.17.7. Please use `validateAndLogInAppPurchaseV2` instead.
680+
677681
* Android only
678682
```typescript
679683
validateAndLogInAppPurchaseAndroid(purchaseData: AFAndroidInAppPurchase) => Promise<void>
@@ -701,7 +705,11 @@ API for server verification of in-app purchases. An af_purchase event with the r
701705
--------------------
702706

703707

704-
### validateAndLogInAppPurchaseIos
708+
### validateAndLogInAppPurchaseIos (Deprecated)
709+
---
710+
> [!WARNING]
711+
> This API is deprecated since version 6.17.7. Please use `validateAndLogInAppPurchaseV2` instead.
712+
705713
* iOS only
706714
```typescript
707715
validateAndLogInAppPurchaseIos(purchaseData: AFIosInAppPurchase) => Promise<void>
@@ -725,16 +733,13 @@ validateAndLogInAppPurchaseIos(purchaseData: AFIosInAppPurchase) => Promise<void
725733
```
726734
--------------------
727735

728-
<!--
729-
### validateAndLogInAppPurchaseV2 (Recommended - BETA)
730-
731-
> ⚠️ **BETA Feature**: This API is currently in beta. While it's stable and recommended for new implementations, please test thoroughly in your environment before production use.
736+
### validateAndLogInAppPurchaseV2 (Recommended)
732737

733738
```typescript
734739
validateAndLogInAppPurchaseV2(purchaseDetails: AFPurchaseDetails, additionalParameters?: Record<string, string>) => Promise<Record<string, any>>
735740
```
736741

737-
API for server verification of in-app purchases V2 (Beta). An af_purchase event with the relevant values will be automatically logged if the validation is successful.
742+
API for server verification of in-app purchases V2. An af_purchase event with the relevant values will be automatically logged if the validation is successful.
738743

739744
**Parameters:**
740745
- `purchaseDetails` (AFPurchaseDetails): Purchase information object
@@ -771,7 +776,7 @@ const additionalParams = {
771776
};
772777

773778
AppsFlyer.validateAndLogInAppPurchaseV2(purchaseDetails, additionalParams)
774-
.then(result => {s
779+
.then(result => {
775780
console.log('Validation successful:', result);
776781
})
777782
.catch(error => {
@@ -786,7 +791,7 @@ AppsFlyer.validateAndLogInAppPurchaseV2(purchaseDetails, additionalParams)
786791
- Consistent data structure across platforms
787792
- Better debugging capabilities
788793

789-
-------------------- -->
794+
--------------------
790795

791796

792797
### getSdkVersion

docs/InAppEvents.md

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ Recording in-app events is performed by calling sendEvent with event name and va
66

77
Find more info about recording events [here](https://support.appsflyer.com/hc/en-us/articles/115005544169-Rich-in-app-events-guide#introduction).
88
- [Log Event](#LogEvent)
9-
- [Purchase Validation](#InAppPurchaseValidation)
9+
- [Purchase Validation (Recommended)](#InAppPurchaseValidationV2)
10+
- [Legacy Purchase Validation(Deprecated)](#InAppPurchaseValidation)
1011
- [Android](#validateAndLogInAppPurchaseAndroid)
1112
- [iOS](#validateAndLogInAppPurchaseIos)
1213

@@ -28,9 +29,43 @@ Find more info about recording events [here](https://support.appsflyer.com/hc/en
2829
.catch(err => alert('logEvent err ~~>' + err));
2930
```
3031

31-
## <a id="InAppPurchaseValidation"> In-app purchase validation
32+
## <a id="InAppPurchaseValidationV2"> In-app purchase validation (Recommended)
3233

33-
For In-App Purchase Receipt Validation, follow the instructions according to your operating system.
34+
AppsFlyer provides a unified API for server verification of in-app purchases across both Android and iOS. This API automatically logs an `af_purchase` event if the validation is successful.
35+
36+
```typescript
37+
import { AFPurchaseType } from 'appsflyer-capacitor-plugin';
38+
39+
const purchaseDetails = {
40+
purchaseType: AFPurchaseType.oneTimePurchase,
41+
purchaseToken: "purchase_token_here",
42+
productId: "com.example.product"
43+
};
44+
45+
const additionalParams = {
46+
"custom_param": "value"
47+
};
48+
49+
AppsFlyer.validateAndLogInAppPurchaseV2({
50+
purchaseDetails: purchaseDetails,
51+
additionalParameters: additionalParams
52+
})
53+
.then(result => {
54+
console.log('Validation successful:', result);
55+
})
56+
.catch(error => {
57+
console.error('Validation failed:', error);
58+
});
59+
```
60+
61+
See the [API documentation](/docs/API.md#validateandloginapppurchasev2) for more details.
62+
63+
## <a id="InAppPurchaseValidation"> Legacy In-app purchase validation (Deprecated)
64+
65+
> [!WARNING]
66+
> These APIs are deprecated since version 6.17.7. Please use [validateAndLogInAppPurchaseV2](#InAppPurchaseValidationV2) instead.
67+
68+
For legacy In-App Purchase Receipt Validation, follow the instructions according to your operating system.
3469

3570
**Notes**
3671
Calling validateReceipt automatically generates an af_purchase in-app event, so you don't need to send this event yourself.

examples/CapacitorReact/src/components/ExploreContainer.tsx

Lines changed: 44 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import './ExploreContainer.css';
22
import { IonButton, isPlatform } from '@ionic/react';
3-
import { AFEvent, AppsFlyer } from "appsflyer-capacitor-plugin";
3+
import { AFEvent, AFPurchaseDetailsV2, AFPurchaseType, AppsFlyer } from "appsflyer-capacitor-plugin";
44
import React from "react";
55

66
interface ContainerProps {
@@ -57,81 +57,49 @@ function generateInviteLink() {
5757
.catch(e => alert('user invite error: ' + e));
5858
}
5959

60-
function validateAndLogInAppPurchase() {
61-
if (isPlatform('android')) {
62-
AppsFlyer.validateAndLogInAppPurchaseAndroid({
63-
additionalParameters: { aa: 'cc' },
64-
currency: 'usd',
65-
price: '20',
66-
signature: 'the_signature',
67-
publicKey: 'your_public_key',
68-
purchaseData: 'the_purchase_data'
69-
})
70-
.then(r => alert('validateAndLogInAppPurchase success: ' + r.res))
71-
.catch(e => alert('validateAndLogInAppPurchase error: ' + e));
72-
} else if (isPlatform('ios')) {
73-
AppsFlyer.validateAndLogInAppPurchaseIos({
74-
additionalParameters: { aa: 'cc' },
75-
currency: 'usd',
76-
price: '20',
77-
inAppPurchase: 'productIdentifier',
78-
transactionId: 'transactionId'
79-
})
80-
.then(r => alert('validateAndLogInAppPurchase success: ' + r.res))
81-
.catch(e => alert('validateAndLogInAppPurchase error: ' + JSON.stringify(e)));
82-
}
83-
}
84-
8560
function validateAndLogInAppPurchaseV2() {
86-
alert('Not implemented yet');
87-
// const purchaseDetails: AFPurchaseDetails = {
88-
// purchaseType: AFPurchaseType.oneTimePurchase,
89-
// purchaseToken: isPlatform('android') ? 'android_purchase_token_example' : 'ios_transaction_id_example',
90-
// productId: 'com.example.product.premium'
91-
// };
92-
93-
// const additionalParams = {
94-
// 'test_param': 'test_value',
95-
// 'custom_data': 'example_data'
96-
// };
97-
//
98-
// AppsFlyer.validateAndLogInAppPurchaseV2({
99-
// purchaseDetails: purchaseDetails,
100-
// additionalParameters: additionalParams
101-
// })
102-
// .then(result => {
103-
// alert('validateAndLogInAppPurchaseV2 success: ' + JSON.stringify(result));
104-
// })
105-
// .catch(error => {
106-
// alert('validateAndLogInAppPurchaseV2 error: ' + JSON.stringify(error));
107-
// });
61+
const purchaseData: AFPurchaseDetailsV2 = {
62+
purchaseDetails: {
63+
purchaseType: AFPurchaseType.oneTimePurchase,
64+
purchaseToken: isPlatform('android') ? 'android_purchase_token_example' : 'ios_transaction_id_example',
65+
productId: 'com.example.product.premium'
66+
},
67+
additionalParameters: {
68+
'test_param': 'test_value',
69+
'custom_data': 'example_data'
70+
}
71+
};
72+
73+
AppsFlyer.validateAndLogInAppPurchaseV2(purchaseData)
74+
.then(result => {
75+
alert('validateAndLogInAppPurchaseV2 success: ' + JSON.stringify(result));
76+
})
77+
.catch(error => {
78+
alert('validateAndLogInAppPurchaseV2 error: ' + JSON.stringify(error));
79+
});
10880
}
10981

11082
function validateAndLogInAppPurchaseV2Subscription() {
111-
alert('Not implemented yet');
112-
// const purchaseDetails: AFPurchaseDetails = {
113-
// purchaseType: AFPurchaseType.subscription,
114-
// purchaseToken: isPlatform('android') ? 'android_subscription_token_example' : 'ios_subscription_transaction_id_example',
115-
// productId: 'com.example.subscription.monthly'
116-
// };
117-
118-
// const additionalParams = {
119-
// 'subscription_period': 'monthly',
120-
// 'test_subscription': 'true'
121-
// };
122-
//
123-
// AppsFlyer.validateAndLogInAppPurchaseV2({
124-
// purchaseDetails: purchaseDetails,
125-
// additionalParameters: additionalParams
126-
// })
127-
// .then(result => {
128-
129-
// alert('validateAndLogInAppPurchaseV2 (Subscription) success: ' + JSON.stringify(result));
130-
// })
131-
// .catch(error =>
132-
// {
133-
// alert('validateAndLogInAppPurchaseV2 (Subscription) error: ' + JSON.stringify(error));
134-
// });
83+
const purchaseData: AFPurchaseDetailsV2 = {
84+
purchaseDetails: {
85+
purchaseType: AFPurchaseType.subscription,
86+
purchaseToken: isPlatform('android') ? 'android_subscription_token_example' : 'ios_subscription_transaction_id_example',
87+
productId: 'com.example.subscription.monthly'
88+
},
89+
additionalParameters: {
90+
'subscription_period': 'monthly',
91+
'test_subscription': 'true'
92+
}
93+
};
94+
95+
AppsFlyer.validateAndLogInAppPurchaseV2(purchaseData)
96+
.then(result => {
97+
98+
alert('validateAndLogInAppPurchaseV2 (Subscription) success: ' + JSON.stringify(result));
99+
})
100+
.catch(error => {
101+
alert('validateAndLogInAppPurchaseV2 (Subscription) error: ' + JSON.stringify(error));
102+
});
135103
}
136104

137105
function setSharingFilterForAllPartners() {
@@ -220,12 +188,10 @@ const ExploreContainer: React.FC<ContainerProps> = () => {
220188
<IonButton color="primary" expand="block" onClick={() => stop()}>Stop SDK</IonButton>
221189
<IonButton color="primary" expand="block" onClick={() => generateInviteLink()}>generate Invite
222190
Link</IonButton>
223-
<IonButton color="primary" expand="block" onClick={() => validateAndLogInAppPurchase()}>validate And Log
224-
IAP (Legacy)</IonButton>
225-
<IonButton color="success" expand="block" onClick={() => validateAndLogInAppPurchaseV2()}>validate And Log
226-
IAP V2 (One-time Purchase) - BETA</IonButton>
227-
<IonButton color="success" expand="block" onClick={() => validateAndLogInAppPurchaseV2Subscription()}>validate And Log
228-
IAP V2 (Subscription) - BETA</IonButton>
191+
<IonButton color="primary" expand="block" onClick={() => validateAndLogInAppPurchaseV2()}>Validate IAP
192+
(One-time Purchase)</IonButton>
193+
<IonButton color="primary" expand="block" onClick={() => validateAndLogInAppPurchaseV2Subscription()}>Validate IAP
194+
(Subscription)</IonButton>
229195
<IonButton color="primary" expand="block" onClick={() => setSharingFilter()}>set Sharing Filter</IonButton>
230196

231197
<IonButton color="primary" expand="block" onClick={() => setSharingFilterForAllPartners()}>set Sharing

0 commit comments

Comments
 (0)