insert-affiliate-react-native-sdk 1.6.2 → 1.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +4 -1
- package/dist/DeepLinkIapProvider.d.ts +4 -1
- package/dist/DeepLinkIapProvider.js +819 -7
- package/dist/index.d.ts +1 -0
- package/dist/useDeepLinkIapProvider.d.ts +3 -1
- package/dist/useDeepLinkIapProvider.js +3 -1
- package/package.json +17 -1
- package/readme.md +394 -12
- package/src/DeepLinkIapProvider.tsx +931 -11
- package/src/index.ts +3 -0
- package/src/useDeepLinkIapProvider.tsx +4 -0
- package/updateProcess.md +31 -0
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,9 @@ declare const useDeepLinkIapProvider: () => {
|
|
|
10
10
|
trackEvent: (eventName: string) => Promise<void>;
|
|
11
11
|
setShortCode: (shortCode: string) => Promise<void>;
|
|
12
12
|
setInsertAffiliateIdentifier: (referringLink: string) => Promise<void | string>;
|
|
13
|
-
|
|
13
|
+
setInsertAffiliateIdentifierChangeCallback: (callback: import("./DeepLinkIapProvider").InsertAffiliateIdentifierChangeCallback | null) => void;
|
|
14
|
+
handleInsertLinks: (url: string) => Promise<boolean>;
|
|
15
|
+
initialize: (code: string | null, verboseLogging?: boolean, insertLinksEnabled?: boolean, insertLinksClipboardEnabled?: boolean) => Promise<void>;
|
|
14
16
|
isInitialized: boolean;
|
|
15
17
|
OfferCode: string | null;
|
|
16
18
|
};
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const react_1 = require("react");
|
|
4
4
|
const DeepLinkIapProvider_1 = require("./DeepLinkIapProvider");
|
|
5
5
|
const useDeepLinkIapProvider = () => {
|
|
6
|
-
const { referrerLink, userId, validatePurchaseWithIapticAPI, storeExpectedStoreTransaction, returnUserAccountTokenAndStoreExpectedTransaction, returnInsertAffiliateIdentifier, trackEvent, setShortCode, setInsertAffiliateIdentifier, initialize, isInitialized, OfferCode, } = (0, react_1.useContext)(DeepLinkIapProvider_1.DeepLinkIapContext);
|
|
6
|
+
const { referrerLink, userId, validatePurchaseWithIapticAPI, storeExpectedStoreTransaction, returnUserAccountTokenAndStoreExpectedTransaction, returnInsertAffiliateIdentifier, trackEvent, setShortCode, setInsertAffiliateIdentifier, setInsertAffiliateIdentifierChangeCallback, handleInsertLinks, initialize, isInitialized, OfferCode, } = (0, react_1.useContext)(DeepLinkIapProvider_1.DeepLinkIapContext);
|
|
7
7
|
return {
|
|
8
8
|
referrerLink,
|
|
9
9
|
userId,
|
|
@@ -14,6 +14,8 @@ const useDeepLinkIapProvider = () => {
|
|
|
14
14
|
trackEvent,
|
|
15
15
|
setShortCode,
|
|
16
16
|
setInsertAffiliateIdentifier,
|
|
17
|
+
setInsertAffiliateIdentifierChangeCallback,
|
|
18
|
+
handleInsertLinks,
|
|
17
19
|
initialize,
|
|
18
20
|
isInitialized,
|
|
19
21
|
OfferCode,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "insert-affiliate-react-native-sdk",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.5",
|
|
4
4
|
"description": "A package for connecting with the Insert Affiliate Platform to add app based affiliate marketing.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,15 +14,31 @@
|
|
|
14
14
|
],
|
|
15
15
|
"author": "Michael Butler",
|
|
16
16
|
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"react-native-play-install-referrer": "^1.1.9"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@react-native-async-storage/async-storage": ">=1.0.0",
|
|
22
|
+
"@react-native-clipboard/clipboard": ">=1.16.0",
|
|
23
|
+
"@react-native-community/netinfo": ">=11.4.0",
|
|
24
|
+
"axios": ">=1.0.0",
|
|
25
|
+
"react": ">=16.0.0",
|
|
26
|
+
"react-native": ">=0.60.0",
|
|
27
|
+
"react-native-device-info": ">=10.0.0"
|
|
28
|
+
},
|
|
17
29
|
"devDependencies": {
|
|
18
30
|
"@jeremybarbet/apple-api-types": "^1.4.1",
|
|
19
31
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
|
32
|
+
"@react-native-clipboard/clipboard": "^1.16.3",
|
|
33
|
+
"@react-native-community/netinfo": "^11.4.1",
|
|
20
34
|
"@types/react": "^18.3.12",
|
|
21
35
|
"@types/react-native": "^0.72.8",
|
|
22
36
|
"axios": "^1.7.7",
|
|
23
37
|
"react": "^18.3.1",
|
|
24
38
|
"react-native": "^0.76.1",
|
|
25
39
|
"react-native-branch": "^6.4.0",
|
|
40
|
+
"react-native-device-info": "^10.14.0",
|
|
41
|
+
"react-native-play-install-referrer": "^1.1.9",
|
|
26
42
|
"typescript": "^5.6.3"
|
|
27
43
|
}
|
|
28
44
|
}
|
package/readme.md
CHANGED
|
@@ -23,11 +23,30 @@ To get started with the InsertAffiliateReactNative SDK:
|
|
|
23
23
|
|
|
24
24
|
To integrate the InsertAffiliateReactNative SDK into your app:
|
|
25
25
|
|
|
26
|
-
1. Install the NPM package.
|
|
26
|
+
1. Install the NPM package and its required peer dependencies.
|
|
27
27
|
```bash
|
|
28
28
|
npm install insert-affiliate-react-native-sdk
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
2. Install the required peer dependencies:
|
|
32
|
+
```bash
|
|
33
|
+
npm install @react-native-async-storage/async-storage @react-native-clipboard/clipboard @react-native-community/netinfo react-native-device-info axios
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Required Dependencies
|
|
37
|
+
|
|
38
|
+
The SDK requires the following peer dependencies to function properly:
|
|
39
|
+
|
|
40
|
+
- **`@react-native-async-storage/async-storage`** (>= 1.0.0) - For persistent storage of affiliate identifiers and user data
|
|
41
|
+
- **`@react-native-clipboard/clipboard`** (>= 1.16.0) - For clipboard-based affiliate link detection (Insert Links feature)
|
|
42
|
+
- **`@react-native-community/netinfo`** (>= 11.4.0) - For network connectivity detection and system information collection
|
|
43
|
+
- **`react-native-device-info`** (>= 10.0.0) - For device information and system data collection
|
|
44
|
+
- **`axios`** (>= 1.0.0) - For API communication with Insert Affiliate services
|
|
45
|
+
- **`react`** (>= 16.0.0) - React framework
|
|
46
|
+
- **`react-native`** (>= 0.60.0) - React Native framework
|
|
47
|
+
|
|
48
|
+
**Note**: These dependencies must be installed in your app for the SDK to work. If any are missing, you'll get runtime errors when the SDK tries to use them.
|
|
49
|
+
|
|
31
50
|
## Architecture Overview
|
|
32
51
|
|
|
33
52
|
The SDK uses a clean, two-file architecture:
|
|
@@ -83,7 +102,9 @@ const App = () => {
|
|
|
83
102
|
|
|
84
103
|
### Verbose Logging (Optional)
|
|
85
104
|
|
|
86
|
-
|
|
105
|
+
By default, the SDK operates silently to avoid interrupting the user experience. However, you can enable verbose logging to see visual confirmation when affiliate attribution is processed. This is particularly useful for debugging during development or TestFlight testing.
|
|
106
|
+
|
|
107
|
+
#### Enable Verbose Logging
|
|
87
108
|
|
|
88
109
|
```javascript
|
|
89
110
|
const Child = () => {
|
|
@@ -102,7 +123,7 @@ const Child = () => {
|
|
|
102
123
|
|
|
103
124
|
- **Initialization Process**: SDK startup, company code validation, AsyncStorage operations
|
|
104
125
|
- **Data Management**: User ID generation, referrer link storage, company code state management
|
|
105
|
-
- **Deep Link Processing**: Input validation, short code detection, API conversion process
|
|
126
|
+
- **Deep Link / Insert Link Processing**: Input validation, short code detection, API conversion process
|
|
106
127
|
- **API Communication**: Request/response details for all server calls
|
|
107
128
|
- **Event Tracking**: Event parameters, payload construction, success/failure status
|
|
108
129
|
- **Purchase Operations**: Transaction storage, token validation, webhook processing
|
|
@@ -130,13 +151,49 @@ const Child = () => {
|
|
|
130
151
|
|
|
131
152
|
⚠️ **Important**: Disable verbose logging in production builds to avoid exposing sensitive debugging information and to optimize performance.
|
|
132
153
|
|
|
154
|
+
### Insert Link and Clipboard Control (BETA)
|
|
155
|
+
We are currently beta testing our in-house deep linking provider, Insert Links, which generates links for use with your affiliates.
|
|
156
|
+
|
|
157
|
+
For larger projects where accuracy is critical, we recommend using established third-party deep linking platforms to generate the links you use within Insert Affiliate - such as Appsflyer or Branch.io, as described in the rest of this README.
|
|
158
|
+
|
|
159
|
+
If you encounter any issues while using Insert Links, please raise an issue on this GitHub repository or contact us directly at michael@insertaffiliate.com
|
|
160
|
+
|
|
161
|
+
#### Initialize with Insert Links
|
|
162
|
+
|
|
163
|
+
When using Insert Affiliate's built-in deep link handling (Insert Links), you can enable these features during initialization:
|
|
164
|
+
|
|
165
|
+
```javascript
|
|
166
|
+
const Child = () => {
|
|
167
|
+
const { initialize, isInitialized } = useDeepLinkIapProvider();
|
|
168
|
+
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
if (!isInitialized) {
|
|
171
|
+
initialize(
|
|
172
|
+
"{{ your-company-code }}",
|
|
173
|
+
false, // Enable for debugging
|
|
174
|
+
true, // Enables Insert Links
|
|
175
|
+
true // Enable Insert Links Clipboard access to avoid permission prompt
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}, [initialize, isInitialized]);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**When to use `insertLinksEnabled`:**
|
|
183
|
+
- Set to `true` (default: `false`) if you are using Insert Affiliate's built-in deep link and universal link handling (Insert Links)
|
|
184
|
+
- Set to `false` if you are using an external provider for deep links
|
|
185
|
+
|
|
186
|
+
**When to use `insertLinksClipboardEnabled`:**
|
|
187
|
+
- Set to `true` (default: `false`) if you are using Insert Affiliate's built-in deep links (Insert Links) **and** would like to improve the effectiveness of our deep links through the clipboard
|
|
188
|
+
- **Important caveat**: This will trigger a system prompt asking the user for permission to access the clipboard when the SDK initializes
|
|
189
|
+
|
|
133
190
|
|
|
134
191
|
## In-App Purchase Setup [Required]
|
|
135
192
|
Insert Affiliate requires a Receipt Verification platform to validate in-app purchases. You must choose **one** of our supported partners:
|
|
136
193
|
- [RevenueCat](https://www.revenuecat.com/)
|
|
137
194
|
- [Iaptic](https://www.iaptic.com/account)
|
|
138
|
-
- [App Store Direct Integration](#app-store-direct-integration)
|
|
139
|
-
- [Google Play Store Direct Integration](#google-play-store-direct-integration)
|
|
195
|
+
- [App Store Direct Integration](#option-3-app-store-direct-integration)
|
|
196
|
+
- [Google Play Store Direct Integration](#option-4-google-play-store-direct-integration)
|
|
140
197
|
|
|
141
198
|
### Option 1: RevenueCat Integration
|
|
142
199
|
#### Step 1. Code Setup
|
|
@@ -145,7 +202,6 @@ First, complete the [RevenueCat SDK installation](https://www.revenuecat.com/doc
|
|
|
145
202
|
```javascript
|
|
146
203
|
import React, {useEffect} from 'react';
|
|
147
204
|
import {AppRegistry} from 'react-native';
|
|
148
|
-
import branch from 'react-native-branch';
|
|
149
205
|
import App from './App';
|
|
150
206
|
import {name as appName} from './app.json';
|
|
151
207
|
import {useDeepLinkIapProvider, DeepLinkIapProvider} from 'insert-affiliate-react-native-sdk';
|
|
@@ -372,7 +428,7 @@ useEffect(() => {
|
|
|
372
428
|
|
|
373
429
|
## Deep Link Setup [Required]
|
|
374
430
|
|
|
375
|
-
Insert Affiliate requires a Deep Linking platform to create links for your affiliates. Our platform works with **any** deep linking provider
|
|
431
|
+
Insert Affiliate requires a Deep Linking platform to create links for your affiliates. Our platform works with **any** deep linking provider. Below are examples for popular providers including Branch.io and AppsFlyer:
|
|
376
432
|
1. **Create a deep link** in your chosen third-party platform and pass it to our dashboard when an affiliate signs up.
|
|
377
433
|
2. **Handle deep link clicks** in your app by passing the clicked link:
|
|
378
434
|
```javascript
|
|
@@ -380,6 +436,159 @@ Insert Affiliate requires a Deep Linking platform to create links for your affil
|
|
|
380
436
|
```
|
|
381
437
|
3. **Integrate with a Receipt Verification platform** by using the result from `setInsertAffiliateIdentifier` to log in or set your application’s username. Examples below include [**Iaptic**](https://github.com/Insert-Affiliate/InsertAffiliateReactNativeSDK?tab=readme-ov-file#example-with-iaptic) and [**RevenueCat**](https://github.com/Insert-Affiliate/InsertAffiliateReactNativeSDK?tab=readme-ov-file#example-with-revenuecat)
|
|
382
438
|
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
### Deep Linking with Insert Links
|
|
442
|
+
|
|
443
|
+
Insert Links by Insert Affiliate supports deferred deep linking into your app. This allows you to track affiliate attribution when end users are referred to your app by clicking on one of your affiliates Insert Links.
|
|
444
|
+
|
|
445
|
+
#### Initial Setup
|
|
446
|
+
|
|
447
|
+
1. Before you can use Insert Links, you must complete the setup steps in [our docs](https://docs.insertaffiliate.com/insert-links)
|
|
448
|
+
|
|
449
|
+
2. **Initialization** of the Insert Affiliate SDK with Insert Links
|
|
450
|
+
|
|
451
|
+
You must enable *insertLinksEnabled* when [initialising our SDK](https://github.com/Insert-Affiliate/InsertAffiliateReactNativeSDK?tab=readme-ov-file#initialize-with-insert-links)
|
|
452
|
+
|
|
453
|
+
**Handle Insert Links** in your React Native app
|
|
454
|
+
|
|
455
|
+
The React Native SDK handles deep links in ALL scenarios:
|
|
456
|
+
|
|
457
|
+
- **App Not Running (Cold Start)**: When user clicks a deep link and app is not running, the app launches and processes the URL
|
|
458
|
+
- **App Running (Warm Start)**: When user clicks a deep link while app is already running, processes the URL immediately
|
|
459
|
+
- **App Backgrounded**: When user clicks a deep link while app is backgrounded, brings app to foreground and processes the URL
|
|
460
|
+
- **Automatic Processing**: Parses Insert Link URLs and sets affiliate identifiers without additional code
|
|
461
|
+
|
|
462
|
+
3. **Platform Specific** Setup
|
|
463
|
+
|
|
464
|
+
##### iOS Additional Setup (required)
|
|
465
|
+
|
|
466
|
+
To enable deep linking and universal links on iOS, you need to configure your app's Info.plist and AppDelegate files.
|
|
467
|
+
|
|
468
|
+
**AppDelegate Setup**
|
|
469
|
+
|
|
470
|
+
Update your `ios/YourApp/AppDelegate.mm` (or `AppDelegate.m`) file:
|
|
471
|
+
|
|
472
|
+
```objc
|
|
473
|
+
#import <React/RCTLinkingManager.h>
|
|
474
|
+
|
|
475
|
+
// Handle URL opening when app is already running (iOS 9+)
|
|
476
|
+
- (BOOL)application:(UIApplication *)application
|
|
477
|
+
openURL:(NSURL *)url
|
|
478
|
+
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
|
|
479
|
+
{
|
|
480
|
+
return [RCTLinkingManager application:application openURL:url options:options];
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// Handle URL opening (iOS 8 and below - for backward compatibility)
|
|
484
|
+
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
|
|
485
|
+
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
|
|
486
|
+
{
|
|
487
|
+
return [RCTLinkingManager application:application openURL:url
|
|
488
|
+
sourceApplication:sourceApplication annotation:annotation];
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Handle universal links (iOS 9+)
|
|
492
|
+
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
|
|
493
|
+
restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
|
|
494
|
+
{
|
|
495
|
+
return [RCTLinkingManager application:application
|
|
496
|
+
continueUserActivity:userActivity
|
|
497
|
+
restorationHandler:restorationHandler];
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
4. **Receipt Verification Integration Examples when Using Insert Links**
|
|
502
|
+
|
|
503
|
+
The SDK provides a callback mechanism that triggers whenever the affiliate identifier changes. This is perfect for integrating with receipt verification platforms.
|
|
504
|
+
|
|
505
|
+
##### With RevenueCat
|
|
506
|
+
|
|
507
|
+
Set up the callback to automatically update RevenueCat when the affiliate identifier changes:
|
|
508
|
+
|
|
509
|
+
```javascript
|
|
510
|
+
import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
511
|
+
import Purchases from 'react-native-purchases';
|
|
512
|
+
|
|
513
|
+
const App = () => {
|
|
514
|
+
const { setInsertAffiliateIdentifierChangeCallback } = useDeepLinkIapProvider();
|
|
515
|
+
|
|
516
|
+
useEffect(() => {
|
|
517
|
+
// Set up callback to handle affiliate identifier changes
|
|
518
|
+
setInsertAffiliateIdentifierChangeCallback(async (identifier) => {
|
|
519
|
+
if (identifier) {
|
|
520
|
+
// Update RevenueCat with the affiliate identifier
|
|
521
|
+
await Purchases.setAttributes({"insert_affiliate": identifier});
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// Cleanup on unmount
|
|
526
|
+
return () => {
|
|
527
|
+
setInsertAffiliateIdentifierChangeCallback(null);
|
|
528
|
+
};
|
|
529
|
+
}, []);
|
|
530
|
+
|
|
531
|
+
return <YourAppContent />;
|
|
532
|
+
};
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
##### With Apphud
|
|
536
|
+
|
|
537
|
+
```javascript
|
|
538
|
+
import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
539
|
+
import Apphud from 'react-native-apphud';
|
|
540
|
+
|
|
541
|
+
const App = () => {
|
|
542
|
+
const { setInsertAffiliateIdentifierChangeCallback } = useDeepLinkIapProvider();
|
|
543
|
+
|
|
544
|
+
useEffect(() => {
|
|
545
|
+
setInsertAffiliateIdentifierChangeCallback(async (identifier) => {
|
|
546
|
+
if (identifier) {
|
|
547
|
+
// Update Apphud with the affiliate identifier
|
|
548
|
+
await Apphud.setUserProperty("insert_affiliate", identifier, false);
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
return () => {
|
|
553
|
+
setInsertAffiliateIdentifierChangeCallback(null);
|
|
554
|
+
};
|
|
555
|
+
}, []);
|
|
556
|
+
|
|
557
|
+
return <YourAppContent />;
|
|
558
|
+
};
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
##### With Iaptic
|
|
562
|
+
|
|
563
|
+
```javascript
|
|
564
|
+
import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
565
|
+
import InAppPurchase from 'react-native-iaptic';
|
|
566
|
+
|
|
567
|
+
const App = () => {
|
|
568
|
+
const { setInsertAffiliateIdentifierChangeCallback } = useDeepLinkIapProvider();
|
|
569
|
+
|
|
570
|
+
useEffect(() => {
|
|
571
|
+
setInsertAffiliateIdentifierChangeCallback(async (identifier) => {
|
|
572
|
+
if (identifier) {
|
|
573
|
+
// Initialize Iaptic with the affiliate identifier
|
|
574
|
+
await InAppPurchase.initialize({
|
|
575
|
+
iapProducts: iapProductsArray,
|
|
576
|
+
validatorUrlString: "https://validator.iaptic.com/v3/validate?appName={{ your_iaptic_app_name }}&apiKey={{ your_iaptic_app_key_goes_here }}",
|
|
577
|
+
applicationUsername: identifier
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
return () => {
|
|
583
|
+
setInsertAffiliateIdentifierChangeCallback(null);
|
|
584
|
+
};
|
|
585
|
+
}, []);
|
|
586
|
+
|
|
587
|
+
return <YourAppContent />;
|
|
588
|
+
};
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
|
|
383
592
|
### Deep Linking with Branch.io
|
|
384
593
|
To set up deep linking with Branch.io, follow these steps:
|
|
385
594
|
|
|
@@ -485,6 +694,155 @@ const RootComponent = () => {
|
|
|
485
694
|
};
|
|
486
695
|
```
|
|
487
696
|
|
|
697
|
+
### Deep Linking with AppsFlyer
|
|
698
|
+
To set up deep linking with AppsFlyer, follow these steps:
|
|
699
|
+
|
|
700
|
+
1. Create a [OneLink](https://support.appsflyer.com/hc/en-us/articles/208874366-Create-a-OneLink-link-for-your-campaigns) in AppsFlyer and pass it to our dashboard when an affiliate signs up.
|
|
701
|
+
- Example: [Create Affiliate](https://docs.insertaffiliate.com/create-affiliate).
|
|
702
|
+
2. Initialize AppsFlyer SDK and set up deep link handling in your app.
|
|
703
|
+
|
|
704
|
+
#### Platform Setup
|
|
705
|
+
Complete the deep linking setup for AppsFlyer by following their official documentation:
|
|
706
|
+
- [AppsFlyer Deferred Deep Link Integration Guide](https://dev.appsflyer.com/hc/docs/deeplinkintegrate)
|
|
707
|
+
|
|
708
|
+
This covers all platform-specific configurations including:
|
|
709
|
+
- iOS: Info.plist configuration, AppDelegate setup, and universal links
|
|
710
|
+
- Android: AndroidManifest.xml intent filters, MainActivity setup, and App Links
|
|
711
|
+
- Testing and troubleshooting for both platforms
|
|
712
|
+
|
|
713
|
+
#### Example with RevenueCat
|
|
714
|
+
|
|
715
|
+
```javascript
|
|
716
|
+
import React, { useEffect } from 'react';
|
|
717
|
+
import { Platform } from 'react-native';
|
|
718
|
+
import appsFlyer from 'react-native-appsflyer';
|
|
719
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
720
|
+
import Purchases from 'react-native-purchases';
|
|
721
|
+
|
|
722
|
+
const DeepLinkHandler = () => {
|
|
723
|
+
const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
|
|
724
|
+
|
|
725
|
+
useEffect(() => {
|
|
726
|
+
if (!isInitialized) return;
|
|
727
|
+
|
|
728
|
+
// Initialize AppsFlyer
|
|
729
|
+
const initAppsFlyer = async () => {
|
|
730
|
+
try {
|
|
731
|
+
const initOptions = {
|
|
732
|
+
devKey: 'your-appsflyer-dev-key',
|
|
733
|
+
isDebug: true,
|
|
734
|
+
appId: Platform.OS === 'ios' ? 'your-ios-app-id' : 'your-android-package-name',
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
await appsFlyer.initSdk(initOptions);
|
|
738
|
+
} catch (error) {
|
|
739
|
+
console.error('AppsFlyer initialization error:', error);
|
|
740
|
+
}
|
|
741
|
+
};
|
|
742
|
+
|
|
743
|
+
// Handle deep link data
|
|
744
|
+
const handleDeepLink = async (deepLinkData) => {
|
|
745
|
+
if (deepLinkData && deepLinkData.data) {
|
|
746
|
+
let referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
|
|
747
|
+
|
|
748
|
+
if (referringLink) {
|
|
749
|
+
try {
|
|
750
|
+
let insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
|
|
751
|
+
|
|
752
|
+
if (insertAffiliateIdentifier) {
|
|
753
|
+
await Purchases.setAttributes({"insert_affiliate": insertAffiliateIdentifier});
|
|
754
|
+
}
|
|
755
|
+
} catch (err) {
|
|
756
|
+
console.error('Error setting affiliate identifier:', err);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
// Listen for both deep link types
|
|
763
|
+
appsFlyer.onDeepLink(handleDeepLink);
|
|
764
|
+
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
765
|
+
|
|
766
|
+
initAppsFlyer();
|
|
767
|
+
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
768
|
+
|
|
769
|
+
return <App />;
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
const RootComponent = () => {
|
|
773
|
+
return (
|
|
774
|
+
<DeepLinkIapProvider>
|
|
775
|
+
<DeepLinkHandler />
|
|
776
|
+
</DeepLinkIapProvider>
|
|
777
|
+
);
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
AppRegistry.registerComponent(appName, () => RootComponent);
|
|
781
|
+
```
|
|
782
|
+
|
|
783
|
+
#### Example with Iaptic / App Store Direct Integration / Google Play Direct Integration
|
|
784
|
+
|
|
785
|
+
```javascript
|
|
786
|
+
import React, { useEffect } from 'react';
|
|
787
|
+
import { Platform } from 'react-native';
|
|
788
|
+
import appsFlyer from 'react-native-appsflyer';
|
|
789
|
+
import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
|
|
790
|
+
|
|
791
|
+
const DeepLinkHandler = () => {
|
|
792
|
+
const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
|
|
793
|
+
|
|
794
|
+
useEffect(() => {
|
|
795
|
+
if (!isInitialized) return;
|
|
796
|
+
|
|
797
|
+
// Initialize AppsFlyer
|
|
798
|
+
const initAppsFlyer = async () => {
|
|
799
|
+
try {
|
|
800
|
+
const initOptions = {
|
|
801
|
+
devKey: 'your-appsflyer-dev-key',
|
|
802
|
+
isDebug: true,
|
|
803
|
+
appId: Platform.OS === 'ios' ? 'your-ios-app-id' : 'your-android-package-name',
|
|
804
|
+
};
|
|
805
|
+
|
|
806
|
+
await appsFlyer.initSdk(initOptions);
|
|
807
|
+
} catch (error) {
|
|
808
|
+
console.error('AppsFlyer initialization error:', error);
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
// Handle deep link data
|
|
813
|
+
const handleDeepLink = async (deepLinkData) => {
|
|
814
|
+
if (deepLinkData && deepLinkData.data) {
|
|
815
|
+
let referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
|
|
816
|
+
|
|
817
|
+
if (referringLink) {
|
|
818
|
+
try {
|
|
819
|
+
await setInsertAffiliateIdentifier(referringLink);
|
|
820
|
+
} catch (err) {
|
|
821
|
+
console.error('Error setting affiliate identifier:', err);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
// Listen for both deep link types
|
|
828
|
+
appsFlyer.onDeepLink(handleDeepLink);
|
|
829
|
+
appsFlyer.onAppOpenAttribution(handleDeepLink);
|
|
830
|
+
|
|
831
|
+
initAppsFlyer();
|
|
832
|
+
}, [setInsertAffiliateIdentifier, isInitialized]);
|
|
833
|
+
|
|
834
|
+
return <App />;
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
const RootComponent = () => {
|
|
838
|
+
return (
|
|
839
|
+
<DeepLinkIapProvider>
|
|
840
|
+
<DeepLinkHandler />
|
|
841
|
+
</DeepLinkIapProvider>
|
|
842
|
+
);
|
|
843
|
+
};
|
|
844
|
+
```
|
|
845
|
+
|
|
488
846
|
## Additional Features
|
|
489
847
|
|
|
490
848
|
### 1. Event Tracking (Beta)
|
|
@@ -524,13 +882,10 @@ const {
|
|
|
524
882
|
|
|
525
883
|
The SDK allows you to apply dynamic modifiers to in-app purchases based on whether the app was installed via an affiliate. These modifiers can be used to swap the default product ID for a discounted or trial-based one - similar to applying an offer code.
|
|
526
884
|
|
|
527
|
-
> **Note:** Offer Codes are currently supported on **iOS only**.
|
|
528
|
-
|
|
529
885
|
#### How It Works
|
|
530
886
|
|
|
531
887
|
When a user clicks an affiliate link or enters a short code linked to an offer (set up in the **Insert Affiliate Dashboard**), the SDK auto-populates the `OfferCode` field with a relevant modifier (e.g., `_oneWeekFree`). You can append this to your base product ID to dynamically display the correct subscription.
|
|
532
888
|
|
|
533
|
-
|
|
534
889
|
#### Basic Usage
|
|
535
890
|
|
|
536
891
|
##### 1. Automatic Offer Code Fetching
|
|
@@ -545,12 +900,41 @@ const { OfferCode } = useDeepLinkIapProvider();
|
|
|
545
900
|
|
|
546
901
|
##### Setup Requirements
|
|
547
902
|
|
|
903
|
+
#### Insert Affiliate Setup Instructions
|
|
904
|
+
|
|
905
|
+
1. Go to your Insert Affiliate dashboard at [app.insertaffiliate.com/affiliates](https://app.insertaffiliate.com/affiliates)
|
|
906
|
+
2. Select the affiliate you want to configure
|
|
907
|
+
3. Click "View" to access the affiliate's settings
|
|
908
|
+
4. Assign an iOS IAP Modifier to the affiliate (e.g., `_oneWeekFree`, `_threeMonthsFree`)
|
|
909
|
+
5. Assign an Android IAP Modifier to the affiliate (e.g., `-oneweekfree`, `-threemonthsfree`)
|
|
910
|
+
5. Save the settings
|
|
911
|
+
|
|
912
|
+
Once configured, when users click that affiliate's links or enter their short codes, your app will automatically receive the modifier and can load the appropriate discounted product.
|
|
913
|
+
|
|
548
914
|
#### App Store Connect Configuration
|
|
549
915
|
1. Create both a base and a promotional product:
|
|
550
916
|
- Base product: `oneMonthSubscription`
|
|
551
917
|
- Promo product: `oneMonthSubscription_oneWeekFree`
|
|
552
918
|
2. Ensure **both** products are approved and available for sale.
|
|
553
919
|
|
|
920
|
+
#### Google Play Console Configuration
|
|
921
|
+
There are multiple ways you can configure your products in Google Play Console:
|
|
922
|
+
|
|
923
|
+
1. **Multiple Products Approach**: Create both a base and a promotional product:
|
|
924
|
+
- Base product: `oneMonthSubscription`
|
|
925
|
+
- Promo product: `oneMonthSubscription-oneweekfree`
|
|
926
|
+
|
|
927
|
+
2. **Single Product with Multiple Base Plans**: Create one product with multiple base plans, one with an offer attached
|
|
928
|
+
|
|
929
|
+
3. **Developer Triggered Offers**: Have one base product and apply the offer through developer-triggered offers
|
|
930
|
+
|
|
931
|
+
4. **Base Product with Intro Offers**: Have one base product that includes an introductory offer
|
|
932
|
+
|
|
933
|
+
Any of these approaches are suitable and work with the SDK. The important part is that your product naming follows the pattern where the offer code modifier can be appended to identify the promotional version.
|
|
934
|
+
|
|
935
|
+
**If using the Multiple Products Approach:**
|
|
936
|
+
- Ensure **both** products are activated and available for purchase.
|
|
937
|
+
- Generate a release to at least **Internal Testing** to make the products available in your current app build
|
|
554
938
|
|
|
555
939
|
**Product Naming Pattern:**
|
|
556
940
|
- Follow the pattern: `{baseProductId}{OfferCode}`
|
|
@@ -829,8 +1213,6 @@ Short codes must meet the following criteria:
|
|
|
829
1213
|
- Contain only **letters, numbers, and underscores** (alphanumeric characters and underscores).
|
|
830
1214
|
- Replace {{ user_entered_short_code }} with the short code the user enters through your chosen input method, i.e. an input field / pop up element
|
|
831
1215
|
|
|
832
|
-
When a short code is set, the SDK automatically attempts to fetch and store any associated offer codes for iOS users.
|
|
833
|
-
|
|
834
1216
|
```javascript
|
|
835
1217
|
import {
|
|
836
1218
|
DeepLinkIapProvider,
|