Skip to content

Commit 50d8ab8

Browse files
authored
Merge pull request #644 from guysarfatty-af/purchase_connector_documentation_updates
Moved testing to the end, moved consumable APIs to the section with p…
2 parents 056626d + d9c64dc commit 50d8ab8

File tree

1 file changed

+84
-85
lines changed

1 file changed

+84
-85
lines changed

Docs/RN_PurchaseConnector.md

Lines changed: 84 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ For more information please check the following pages:
2121
The Purchase Connector feature of the AppsFlyer SDK depends on specific libraries provided by Google and Apple for managing in-app purchases:
2222

2323
- For Android, it depends on the [Google Play Billing Library](https://developer.android.com/google/play/billing/integrate) (Supported versions: 5.x.x - 7.x.x).
24-
- For iOS, it depends on [StoreKit](https://developer.apple.com/documentation/storekit) (Supported versions: StoreKit1 and StoreKit2 (beta)).
24+
- For iOS, it depends on [StoreKit](https://developer.apple.com/documentation/storekit) (Supported versions: StoreKit1 and StoreKit2).
2525

2626
However, these dependencies aren't actively included with the SDK. This means that the responsibility of managing these dependencies and including the necessary libraries in your project falls on you as the consumer of the SDK.
2727

@@ -53,6 +53,19 @@ The files for the Purchase Validation feature are always included in the plugin.
5353

5454
In such cases, you'll likely experience errors or exceptions when trying to use functionalities provided by the Purchase Validation feature. To avoid these issues, ensure that you opt-in to the feature if you intend to use any related APIs.
5555

56+
57+
## <a id="proguard-rules-for-android"></a>ProGuard Rules for Android
58+
59+
If you are using ProGuard to obfuscate your APK for Android, you need to ensure that it doesn't interfere with the functionality of AppsFlyer SDK and its Purchase Connector feature.
60+
61+
Add following keep rules to your `proguard-rules.pro` file:
62+
63+
```groovy
64+
-keep class com.appsflyer.** { *; }
65+
-keep class kotlin.jvm.internal.Intrinsics{ *; }
66+
-keep class kotlin.collections.**{ *; }
67+
```
68+
5669
## <a id="basic-integration-of-the-connector"></a>Basic Integration Of The Connector
5770
### <a id="create-purchaseconnector-instance"></a>Create PurchaseConnector Instance
5871
The `PurchaseConnector` requires a configuration object of type `PurchaseConnectorConfig` at instantiation time. This configuration object governs how the `PurchaseConnector` behaves in your application.
@@ -225,6 +238,58 @@ const purchaseConnectorConfigSK2 = AppsFlyerPurchaseConnectorConfig.setConfig({
225238
});
226239
```
227240

241+
### <a id="logging-consumable-transactions"></a>Logging Consumable Transactions
242+
243+
On iOS 15 and above, consumable in-app purchases are handled via StoreKit 2. The behavior depends on your iOS version:
244+
245+
- **On iOS 18 and later:**
246+
Apple introduced a new Info.plist flag: `SKIncludeConsumableInAppPurchaseHistory`.
247+
- If you set `SKIncludeConsumableInAppPurchaseHistory` to `YES` in your Info.plist, automatic collection will happen.
248+
- If the flag is not present or is set to `NO`, you must manually log consumable transactions as shown below.
249+
250+
- **On iOS 15–17:**
251+
Consumable purchases must always be logged manually.
252+
253+
To manually log consumable transactions, use the `logConsumableTransaction` method after finishing the transaction:
254+
255+
```javascript
256+
import { Platform } from 'react-native';
257+
import { AppsFlyerPurchaseConnector } from 'react-native-appsflyer';
258+
259+
// Purchase update listener
260+
purchaseUpdatedListener((purchase) => {
261+
console.log("🛒 Purchase updated:", purchase.productId, "Transaction ID:", purchase.transactionId);
262+
const isConsumable = consumablesItems.includes(purchase.productId);
263+
264+
finishTransaction({ purchase, isConsumable })
265+
.then((res) => {
266+
console.log("✅ finishTransaction success:", res);
267+
console.log("🔍 Expecting AppsFlyer validation callback for:", purchase.productId);
268+
269+
// Log consumable transaction for iOS
270+
if (Platform.OS === 'ios' && isConsumable && purchase.transactionId) {
271+
AppsFlyerPurchaseConnector.logConsumableTransaction(purchase.transactionId);
272+
console.log("📝 Consumable transaction logged:", purchase.transactionId);
273+
}
274+
})
275+
.catch((error) => {
276+
console.warn("❌ Error finishing transaction:", error);
277+
});
278+
});
279+
```
280+
281+
### Method Signature
282+
283+
```javascript
284+
AppsFlyerPurchaseConnector.logConsumableTransaction(transactionId: string): void
285+
```
286+
287+
**Parameters:**
288+
- `transactionId` (string): The unique transaction identifier from the App Store transaction
289+
290+
**Note:** This method is iOS-specific and should only be called on iOS devices. On Android, consumable transactions are automatically handled by the Purchase Connector.
291+
292+
228293
## <a id="register-validation-results-listeners"></a>Register Validation Results Listeners
229294
You can register listeners to get the validation results once getting a response from AppsFlyer servers to let you know if the purchase was validated successfully.</br>
230295

@@ -304,37 +369,6 @@ const handleOnReceivePurchaseRevenueValidationInfo = (validationInfo, error) =>
304369
}, []);
305370
```
306371

307-
308-
## <a id="testing-the-integration"></a>Testing the Integration
309-
310-
With the AppsFlyer SDK, you can select which environment will be used for validation - either **production** or **sandbox**. By default, the environment is set to production. However, while testing your app, you should use the sandbox environment.
311-
312-
### <a id="android"></a>Android
313-
314-
For Android, testing your integration with the [Google Play Billing Library](https://developer.android.com/google/play/billing/test) should use the sandbox environment.
315-
316-
To set the environment to sandbox in React Native, just set the `sandbox` parameter in the `PurchaseConnectorConfig` to `true` when instantiating `PurchaseConnector`.
317-
318-
Remember to switch the environment back to production (set `sandbox` to `false`) before uploading your app to the Google Play Store.
319-
320-
### <a id="ios"></a>iOS
321-
322-
To test purchases in an iOS environment on a real device with a TestFlight sandbox account, you also need to set `sandbox` to `true`.
323-
324-
> *IMPORTANT NOTE: Before releasing your app to production please be sure to set `sandbox` to `false`. If a production purchase event is sent in sandbox mode, your event will not be validated properly! *
325-
326-
## <a id="proguard-rules-for-android"></a>ProGuard Rules for Android
327-
328-
If you are using ProGuard to obfuscate your APK for Android, you need to ensure that it doesn't interfere with the functionality of AppsFlyer SDK and its Purchase Connector feature.
329-
330-
Add following keep rules to your `proguard-rules.pro` file:
331-
332-
```groovy
333-
-keep class com.appsflyer.** { *; }
334-
-keep class kotlin.jvm.internal.Intrinsics{ *; }
335-
-keep class kotlin.collections.**{ *; }
336-
```
337-
338372
## <a id="full-code-example"></a>Full Code Example
339373
```javascript
340374
import appsFlyer, {
@@ -535,59 +569,6 @@ const setupPurchaseDataSources = () => {
535569
};
536570
```
537571

538-
539-
### <a id="logging-consumable-transactions"></a>Logging Consumable Transactions
540-
541-
On iOS 15 and above, consumable in-app purchases are handled via StoreKit 2. The behavior depends on your iOS version:
542-
543-
- **On iOS 18 and later:**
544-
Apple introduced a new Info.plist flag: `SKIncludeConsumableInAppPurchaseHistory`.
545-
- If you set `SKIncludeConsumableInAppPurchaseHistory` to `YES` in your Info.plist, automatic collection will happen.
546-
- If the flag is not present or is set to `NO`, you must manually log consumable transactions as shown below.
547-
548-
- **On iOS 15–17:**
549-
Consumable purchases must always be logged manually.
550-
551-
To manually log consumable transactions, use the `logConsumableTransaction` method after finishing the transaction:
552-
553-
```javascript
554-
import { Platform } from 'react-native';
555-
import { AppsFlyerPurchaseConnector } from 'react-native-appsflyer';
556-
557-
// Purchase update listener
558-
purchaseUpdatedListener((purchase) => {
559-
console.log("🛒 Purchase updated:", purchase.productId, "Transaction ID:", purchase.transactionId);
560-
const isConsumable = consumablesItems.includes(purchase.productId);
561-
562-
finishTransaction({ purchase, isConsumable })
563-
.then((res) => {
564-
console.log("✅ finishTransaction success:", res);
565-
console.log("🔍 Expecting AppsFlyer validation callback for:", purchase.productId);
566-
567-
// Log consumable transaction for iOS
568-
if (Platform.OS === 'ios' && isConsumable && purchase.transactionId) {
569-
AppsFlyerPurchaseConnector.logConsumableTransaction(purchase.transactionId);
570-
console.log("📝 Consumable transaction logged:", purchase.transactionId);
571-
}
572-
})
573-
.catch((error) => {
574-
console.warn("❌ Error finishing transaction:", error);
575-
});
576-
});
577-
```
578-
579-
### Method Signature
580-
581-
```javascript
582-
AppsFlyerPurchaseConnector.logConsumableTransaction(transactionId: string): void
583-
```
584-
585-
**Parameters:**
586-
- `transactionId` (string): The unique transaction identifier from the App Store transaction
587-
588-
**Note:** This method is iOS-specific and should only be called on iOS devices. On Android, consumable transactions are automatically handled by the Purchase Connector.
589-
590-
591572
### <a id="important-notes"></a>Important Notes
592573

593574
1. **iOS StoreKit2**: The StoreKit2 data source is only available on iOS 15.0 and later. Make sure to check the iOS version before using it.
@@ -622,3 +603,21 @@ setupPurchaseDataSources();
622603
// 3. Start observing transactions
623604
await AppsFlyerPurchaseConnector.startObservingTransactions();
624605
```
606+
607+
## <a id="testing-the-integration"></a>Testing the Integration
608+
609+
With the AppsFlyer SDK, you can select which environment will be used for validation - either **production** or **sandbox**. By default, the environment is set to production. However, while testing your app, you should use the sandbox environment.
610+
611+
### <a id="android"></a>Android
612+
613+
For Android, testing your integration with the [Google Play Billing Library](https://developer.android.com/google/play/billing/test) should use the sandbox environment.
614+
615+
To set the environment to sandbox in React Native, just set the `sandbox` parameter in the `PurchaseConnectorConfig` to `true` when instantiating `PurchaseConnector`.
616+
617+
Remember to switch the environment back to production (set `sandbox` to `false`) before uploading your app to the Google Play Store.
618+
619+
### <a id="ios"></a>iOS
620+
621+
To test purchases in an iOS environment on a real device with a TestFlight sandbox account, you also need to set `sandbox` to `true`.
622+
623+
> *IMPORTANT NOTE: Before releasing your app to production please be sure to set `sandbox` to `false`. If a production purchase event is sent in sandbox mode, your event will not be validated properly! *

0 commit comments

Comments
 (0)