What You Will Build
By the end of this tutorial, your React Native app will attribute in-app purchases to the affiliates who drove them. When a user clicks an affiliate link, opens your app, and makes a purchase, the transaction will appear in your Insert Affiliate dashboard with the correct affiliate credited and commission calculated.
The integration uses the insert-affiliate-react-native-sdk package and takes roughly 30 minutes to complete.
Prerequisites
- React Native 0.60 or later
- iOS 13.0+ / Android API 21+
- A Company Code from your Insert Affiliate dashboard (Settings page)
- A purchase verification platform configured (this tutorial uses RevenueCat, but the SDK also supports Adapty, Apphud, Iaptic, direct App Store, and direct Google Play)
Step 1: Install the SDK
Install the Insert Affiliate SDK and its required peer dependencies:
npm install insert-affiliate-react-native-sdk
npm install @react-native-async-storage/async-storage @react-native-clipboard/clipboard @react-native-community/netinfo react-native-device-info axiosFor bare React Native projects, install iOS pods:
cd ios && pod install && cd ..For Expo managed workflow, skip the pod install. Pods are installed automatically when you run npx expo prebuild or npx expo run:ios.
Step 2: Wrap Your App with the Provider
The SDK uses React Context to manage state. Wrap your app with the DeepLinkIapProvider in your entry file (index.js):
import React from 'react';
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import { DeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
const RootComponent = () => {
return (
);
};
AppRegistry.registerComponent(appName, () => RootComponent);Step 3: Initialize the SDK
In your App.tsx, call initialize() with your Company Code:
import React, { useEffect } from 'react';
import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
const App = () => {
const { initialize, isInitialized } = useDeepLinkIapProvider();
useEffect(() => {
if (!isInitialized) {
initialize(
"YOUR_COMPANY_CODE",
true, // verbose logging (disable in production)
true, // enable Insert Links
false // clipboard attribution
);
}
}, [initialize, isInitialized]);
return ;
};When initialization succeeds, you will see this in your console:
[Insert Affiliate] SDK initialized with company code: YOUR_COMPANY_CODEStep 4: Connect to RevenueCat
This is the critical step that bridges affiliate attribution with purchase tracking. When the SDK detects an affiliate identifier (from a deep link or short code), you pass it to RevenueCat as a subscriber attribute:
import React, { useEffect } from 'react';
import { AppState } from 'react-native';
import Purchases from 'react-native-purchases';
import { useDeepLinkIapProvider } from 'insert-affiliate-react-native-sdk';
const App = () => {
const {
initialize,
isInitialized,
setInsertAffiliateIdentifierChangeCallback,
isAffiliateAttributionValid,
getAffiliateExpiryTimestamp
} = useDeepLinkIapProvider();
useEffect(() => {
if (!isInitialized) {
initialize("YOUR_COMPANY_CODE", true, true, false);
}
}, [initialize, isInitialized]);
useEffect(() => {
setInsertAffiliateIdentifierChangeCallback(async (identifier, offerCode) => {
if (identifier) {
await Purchases.setAttributes({
"insert_affiliate": identifier,
"affiliateOfferCode": offerCode || "",
"insert_timedout": ""
});
await Purchases.syncAttributesAndOfferingsIfNeeded();
}
});
return () => setInsertAffiliateIdentifierChangeCallback(null);
}, [setInsertAffiliateIdentifierChangeCallback]);
useEffect(() => {
if (!isInitialized) return;
const clearExpiredAffiliation = async () => {
const isValid = await isAffiliateAttributionValid();
if (!isValid) {
const expiryTimestamp = await getAffiliateExpiryTimestamp();
if (!expiryTimestamp) return;
await Purchases.setAttributes({
"affiliateOfferCode": "",
"insert_timedout": expiryTimestamp.toString()
});
await Purchases.syncAttributesAndOfferingsIfNeeded();
}
};
clearExpiredAffiliation();
const subscription = AppState.addEventListener('change', (state) => {
if (state === 'active') {
clearExpiredAffiliation();
}
});
return () => subscription?.remove();
}, [isInitialized, isAffiliateAttributionValid, getAffiliateExpiryTimestamp]);
return ;
};The callback fires every time the affiliate identifier changes. The insert_timedout attribute stores the expiry timestamp so the webhook can compare purchase dates against the attribution window.
Step 5: Configure the RevenueCat Webhook
- In RevenueCat, create a new webhook.
- Set the Webhook URL to
https://api.insertaffiliate.com/v1/api/revenuecat-webhook. - Set Event Type to "All events".
- In your Insert Affiliate dashboard Settings, set the In-App Purchase Verification method to RevenueCat.
- Copy the RevenueCat Webhook Authentication Header value from the Insert Affiliate dashboard.
- Paste it into the Authorization header field in RevenueCat's webhook configuration.
Step 6: Set Up Deep Linking (iOS)
Update your ios/YourApp/AppDelegate.mm to handle incoming URLs:
#import
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
} Add your iOS URL scheme to Info.plist and, for Universal Links, add applinks:insertaffiliate.link to Associated Domains in Xcode.
Step 7: Set Up Deep Linking (Android)
Add an intent filter to your main activity in android/app/src/main/AndroidManifest.xml:
For Android App Links, add a second intent filter with android:autoVerify="true" and android:host="insertaffiliate.link". Set android:launchMode="singleTop" on your activity.
Step 8: Handle Expo Router (If Applicable)
If you use Expo Router, create app/+native-intent.tsx to prevent route conflicts:
export function redirectSystemPath({ path }: { path: string }): string | null {
if (path.includes('insert-affiliate') || path.includes('insertAffiliate')) {
return null;
}
return path;
}Step 9: Test the Integration
Create a test affiliate in your Insert Affiliate dashboard using an email alias (e.g., [email protected]). Then test the deep link:
# iOS Simulator
xcrun simctl openurl booted "https://insertaffiliate.link/YOUR_COMPANY_CODE/TEST_SHORT_CODE"
# Android Emulator
adb shell am start -a android.intent.action.VIEW -d "https://insertaffiliate.link/YOUR_COMPANY_CODE/TEST_SHORT_CODE"Verify the affiliate identifier is stored by checking the console logs, then make a sandbox purchase and confirm the transaction appears in your dashboard.
Using Other Purchase Verification Platforms
If you use Adapty instead of RevenueCat, the identifier callback sets a custom attribute via adapty.updateProfile(). For Iaptic, call validatePurchaseWithIapticAPI() from the SDK. For direct App Store integration, call returnUserAccountTokenAndStoreExpectedTransaction() before each purchase. For direct Google Play, call storeExpectedStoreTransaction() with the purchase token after each purchase.
The deep linking and SDK initialization steps remain the same regardless of which purchase verification platform you choose.
Advanced Features
Once the basic integration is working, consider adding:
- Short codes: Let affiliates share codes like "SAVE20" that users enter in your app. Call
setShortCode(code)to validate and store. - Dynamic offer codes: Configure offer code modifiers in the dashboard and use
OfferCodefrom the SDK to build dynamic product IDs. - Event tracking: Track custom events like signups with
trackEvent('user_signup')for commission structures beyond purchases. - Attribution timeout: Set a time limit on how long affiliate attribution remains active, such as 7 days (604,800 seconds).
- Prevent affiliate transfer: Lock the first affiliate attribution so subsequent link clicks cannot overwrite it.
