insert-affiliate-react-native-sdk 1.9.0 → 1.11.1

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.
@@ -0,0 +1,385 @@
1
+ # AppsFlyer Deep Linking Integration
2
+
3
+ This guide shows how to integrate InsertAffiliateReactNative SDK with AppsFlyer for deep linking attribution.
4
+
5
+ ## Prerequisites
6
+
7
+ - [AppsFlyer SDK for React Native](https://dev.appsflyer.com/hc/docs/react-native-plugin) installed and configured
8
+ - Create an AppsFlyer OneLink and provide it to affiliates via the [Insert Affiliate dashboard](https://app.insertaffiliate.com/affiliates)
9
+
10
+ ## Platform Setup
11
+
12
+ Complete the deep linking setup for AppsFlyer by following their official documentation:
13
+ - [AppsFlyer Deferred Deep Link Integration Guide](https://dev.appsflyer.com/hc/docs/deeplinkintegrate)
14
+
15
+ This covers all platform-specific configurations including:
16
+ - iOS: Info.plist configuration, AppDelegate setup, and universal links
17
+ - Android: AndroidManifest.xml intent filters, MainActivity setup, and App Links
18
+ - Testing and troubleshooting for both platforms
19
+
20
+ ## Integration Examples
21
+
22
+ Choose the example that matches your IAP verification platform:
23
+
24
+ ### Example with RevenueCat
25
+
26
+ ```javascript
27
+ import React, { useEffect } from 'react';
28
+ import { AppRegistry, Platform } from 'react-native';
29
+ import appsFlyer from 'react-native-appsflyer';
30
+ import Purchases from 'react-native-purchases';
31
+ import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
32
+ import App from './App';
33
+ import { name as appName } from './app.json';
34
+
35
+ const DeepLinkHandler = () => {
36
+ const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
37
+
38
+ useEffect(() => {
39
+ if (!isInitialized) return;
40
+
41
+ // Initialize AppsFlyer
42
+ const initAppsFlyer = async () => {
43
+ try {
44
+ const initOptions = {
45
+ devKey: 'YOUR_APPSFLYER_DEV_KEY',
46
+ isDebug: true,
47
+ appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
48
+ };
49
+
50
+ await appsFlyer.initSdk(initOptions);
51
+ } catch (error) {
52
+ console.error('AppsFlyer initialization error:', error);
53
+ }
54
+ };
55
+
56
+ // Handle deep link data
57
+ const handleDeepLink = async (deepLinkData) => {
58
+ if (deepLinkData && deepLinkData.data) {
59
+ const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
60
+
61
+ if (referringLink) {
62
+ try {
63
+ const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
64
+
65
+ if (insertAffiliateIdentifier) {
66
+ await Purchases.setAttributes({ "insert_affiliate": insertAffiliateIdentifier });
67
+ }
68
+ } catch (err) {
69
+ console.error('Error setting affiliate identifier:', err);
70
+ }
71
+ }
72
+ }
73
+ };
74
+
75
+ // Listen for all deep link types
76
+ appsFlyer.onDeepLink(handleDeepLink);
77
+ appsFlyer.onAppOpenAttribution(handleDeepLink);
78
+ appsFlyer.onInstallConversionData(handleDeepLink);
79
+
80
+ initAppsFlyer();
81
+ }, [setInsertAffiliateIdentifier, isInitialized]);
82
+
83
+ return <App />;
84
+ };
85
+
86
+ const RootComponent = () => {
87
+ return (
88
+ <DeepLinkIapProvider>
89
+ <DeepLinkHandler />
90
+ </DeepLinkIapProvider>
91
+ );
92
+ };
93
+
94
+ AppRegistry.registerComponent(appName, () => RootComponent);
95
+ ```
96
+
97
+ **Replace the following:**
98
+ - `YOUR_APPSFLYER_DEV_KEY` with your AppsFlyer Dev Key
99
+ - `YOUR_IOS_APP_ID` with your iOS App ID (numbers only, e.g., "123456789")
100
+ - `YOUR_ANDROID_PACKAGE_NAME` with your Android package name
101
+
102
+ ### Example with Adapty
103
+
104
+ ```javascript
105
+ import React, { useEffect, useRef } from 'react';
106
+ import { AppRegistry, Platform } from 'react-native';
107
+ import appsFlyer from 'react-native-appsflyer';
108
+ import { adapty } from 'react-native-adapty';
109
+ import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
110
+ import App from './App';
111
+ import { name as appName } from './app.json';
112
+
113
+ const DeepLinkHandler = () => {
114
+ const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
115
+ const adaptyActivationPromiseRef = useRef(null);
116
+
117
+ // Initialize Adapty SDK
118
+ useEffect(() => {
119
+ const initAdapty = async () => {
120
+ try {
121
+ adaptyActivationPromiseRef.current = adapty.activate('YOUR_ADAPTY_PUBLIC_SDK_KEY', {
122
+ __ignoreActivationOnFastRefresh: __DEV__,
123
+ });
124
+ await adaptyActivationPromiseRef.current;
125
+ } catch (error) {
126
+ console.error('Failed to activate Adapty SDK:', error);
127
+ }
128
+ };
129
+
130
+ if (!adaptyActivationPromiseRef.current) {
131
+ initAdapty();
132
+ }
133
+ }, []);
134
+
135
+ useEffect(() => {
136
+ if (!isInitialized) return;
137
+
138
+ const initAppsFlyer = async () => {
139
+ try {
140
+ const initOptions = {
141
+ devKey: 'YOUR_APPSFLYER_DEV_KEY',
142
+ isDebug: true,
143
+ appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
144
+ };
145
+
146
+ await appsFlyer.initSdk(initOptions);
147
+ } catch (error) {
148
+ console.error('AppsFlyer initialization error:', error);
149
+ }
150
+ };
151
+
152
+ const handleDeepLink = async (deepLinkData) => {
153
+ if (deepLinkData && deepLinkData.data) {
154
+ const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
155
+
156
+ if (referringLink) {
157
+ try {
158
+ const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
159
+
160
+ if (insertAffiliateIdentifier && adaptyActivationPromiseRef.current) {
161
+ // Wait for Adapty activation before updating profile
162
+ await adaptyActivationPromiseRef.current;
163
+ await adapty.updateProfile({
164
+ codableCustomAttributes: {
165
+ insert_affiliate: insertAffiliateIdentifier,
166
+ },
167
+ });
168
+ }
169
+ } catch (err) {
170
+ console.error('Error setting affiliate identifier:', err);
171
+ }
172
+ }
173
+ }
174
+ };
175
+
176
+ appsFlyer.onDeepLink(handleDeepLink);
177
+ appsFlyer.onAppOpenAttribution(handleDeepLink);
178
+ appsFlyer.onInstallConversionData(handleDeepLink);
179
+
180
+ initAppsFlyer();
181
+ }, [setInsertAffiliateIdentifier, isInitialized]);
182
+
183
+ return <App />;
184
+ };
185
+
186
+ const RootComponent = () => {
187
+ return (
188
+ <DeepLinkIapProvider>
189
+ <DeepLinkHandler />
190
+ </DeepLinkIapProvider>
191
+ );
192
+ };
193
+
194
+ AppRegistry.registerComponent(appName, () => RootComponent);
195
+ ```
196
+
197
+ ### Example with Apphud
198
+
199
+ ```javascript
200
+ import React, { useEffect } from 'react';
201
+ import { AppRegistry, Platform } from 'react-native';
202
+ import appsFlyer from 'react-native-appsflyer';
203
+ import Apphud from 'react-native-apphud';
204
+ import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
205
+ import App from './App';
206
+ import { name as appName } from './app.json';
207
+
208
+ const DeepLinkHandler = () => {
209
+ const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
210
+
211
+ useEffect(() => {
212
+ if (!isInitialized) return;
213
+
214
+ const initAppsFlyer = async () => {
215
+ try {
216
+ const initOptions = {
217
+ devKey: 'YOUR_APPSFLYER_DEV_KEY',
218
+ isDebug: true,
219
+ appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
220
+ };
221
+
222
+ await appsFlyer.initSdk(initOptions);
223
+ } catch (error) {
224
+ console.error('AppsFlyer initialization error:', error);
225
+ }
226
+ };
227
+
228
+ const handleDeepLink = async (deepLinkData) => {
229
+ if (deepLinkData && deepLinkData.data) {
230
+ const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
231
+
232
+ if (referringLink) {
233
+ try {
234
+ const insertAffiliateIdentifier = await setInsertAffiliateIdentifier(referringLink);
235
+
236
+ if (insertAffiliateIdentifier) {
237
+ await Apphud.setUserProperty("insert_affiliate", insertAffiliateIdentifier, false);
238
+ }
239
+ } catch (err) {
240
+ console.error('Error setting affiliate identifier:', err);
241
+ }
242
+ }
243
+ }
244
+ };
245
+
246
+ appsFlyer.onDeepLink(handleDeepLink);
247
+ appsFlyer.onAppOpenAttribution(handleDeepLink);
248
+ appsFlyer.onInstallConversionData(handleDeepLink);
249
+
250
+ initAppsFlyer();
251
+ }, [setInsertAffiliateIdentifier, isInitialized]);
252
+
253
+ return <App />;
254
+ };
255
+
256
+ const RootComponent = () => {
257
+ return (
258
+ <DeepLinkIapProvider>
259
+ <DeepLinkHandler />
260
+ </DeepLinkIapProvider>
261
+ );
262
+ };
263
+
264
+ AppRegistry.registerComponent(appName, () => RootComponent);
265
+ ```
266
+
267
+ ### Example with Iaptic / Store Direct Integration
268
+
269
+ ```javascript
270
+ import React, { useEffect } from 'react';
271
+ import { AppRegistry, Platform } from 'react-native';
272
+ import appsFlyer from 'react-native-appsflyer';
273
+ import { useDeepLinkIapProvider, DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
274
+ import App from './App';
275
+ import { name as appName } from './app.json';
276
+
277
+ const DeepLinkHandler = () => {
278
+ const { setInsertAffiliateIdentifier, isInitialized } = useDeepLinkIapProvider();
279
+
280
+ useEffect(() => {
281
+ if (!isInitialized) return;
282
+
283
+ const initAppsFlyer = async () => {
284
+ try {
285
+ const initOptions = {
286
+ devKey: 'YOUR_APPSFLYER_DEV_KEY',
287
+ isDebug: true,
288
+ appId: Platform.OS === 'ios' ? 'YOUR_IOS_APP_ID' : 'YOUR_ANDROID_PACKAGE_NAME',
289
+ };
290
+
291
+ await appsFlyer.initSdk(initOptions);
292
+ } catch (error) {
293
+ console.error('AppsFlyer initialization error:', error);
294
+ }
295
+ };
296
+
297
+ const handleDeepLink = async (deepLinkData) => {
298
+ if (deepLinkData && deepLinkData.data) {
299
+ const referringLink = deepLinkData.data.link || deepLinkData.data.deep_link_value;
300
+
301
+ if (referringLink) {
302
+ try {
303
+ await setInsertAffiliateIdentifier(referringLink);
304
+ // Affiliate identifier is stored automatically for Iaptic/direct store integration
305
+ } catch (err) {
306
+ console.error('Error setting affiliate identifier:', err);
307
+ }
308
+ }
309
+ }
310
+ };
311
+
312
+ appsFlyer.onDeepLink(handleDeepLink);
313
+ appsFlyer.onAppOpenAttribution(handleDeepLink);
314
+ appsFlyer.onInstallConversionData(handleDeepLink);
315
+
316
+ initAppsFlyer();
317
+ }, [setInsertAffiliateIdentifier, isInitialized]);
318
+
319
+ return <App />;
320
+ };
321
+
322
+ const RootComponent = () => {
323
+ return (
324
+ <DeepLinkIapProvider>
325
+ <DeepLinkHandler />
326
+ </DeepLinkIapProvider>
327
+ );
328
+ };
329
+
330
+ AppRegistry.registerComponent(appName, () => RootComponent);
331
+ ```
332
+
333
+ ## Deep Link Listener Types
334
+
335
+ AppsFlyer provides three types of deep link callbacks:
336
+
337
+ | Callback | When It Fires | Use Case |
338
+ |----------|---------------|----------|
339
+ | `onDeepLink` | App opened via deep link (app already installed) | Direct attribution |
340
+ | `onAppOpenAttribution` | App opened via deep link with attribution data | Re-engagement campaigns |
341
+ | `onInstallConversionData` | First app launch after install | Deferred deep linking |
342
+
343
+ For comprehensive affiliate tracking, we recommend listening to all three as shown in the examples above.
344
+
345
+ ## Testing
346
+
347
+ Test your AppsFlyer deep link integration:
348
+
349
+ ```bash
350
+ # Test with your OneLink URL (iOS Simulator)
351
+ xcrun simctl openurl booted "https://your-app.onelink.me/abc123"
352
+
353
+ # Test with your OneLink URL (Android Emulator)
354
+ adb shell am start -W -a android.intent.action.VIEW -d "https://your-app.onelink.me/abc123"
355
+ ```
356
+
357
+ ## Troubleshooting
358
+
359
+ **Problem:** Attribution callback not firing
360
+ - **Solution:** Ensure AppsFlyer SDK is initialized with correct dev key and app ID
361
+ - Check AppsFlyer dashboard to verify OneLink is active
362
+ - Verify `isInitialized` is `true` before setting up listeners
363
+
364
+ **Problem:** Deep link parameters not captured
365
+ - **Solution:** Verify deep link contains correct parameters in AppsFlyer dashboard
366
+ - Check Info.plist has correct URL schemes and associated domains (iOS)
367
+ - Check AndroidManifest.xml has correct intent filters (Android)
368
+
369
+ **Problem:** Deferred deep linking not working
370
+ - **Solution:** Make sure `onInstallConversionData` listener is set up
371
+ - Test with a fresh app install (uninstall/reinstall)
372
+ - Verify AppsFlyer's "Deferred Deep Linking" is enabled in dashboard
373
+
374
+ **Problem:** `deep_link_value` is undefined
375
+ - **Solution:** Ensure you're accessing the correct property path in the callback data
376
+ - Log the full `deepLinkData` object to see available fields
377
+
378
+ ## Next Steps
379
+
380
+ After completing AppsFlyer integration:
381
+ 1. Test deep link attribution with a test affiliate link
382
+ 2. Verify affiliate identifier is stored correctly
383
+ 3. Make a test purchase to confirm tracking works end-to-end
384
+
385
+ [Back to Main README](../readme.md)