GitHub

Insert Affiliate Android SDK

Version License

The official Android SDK for Insert Affiliate - track affiliate-driven in-app purchases and reward your partners automatically.

What does this SDK do? It connects your Android app to Insert Affiliate's platform, enabling you to track which affiliates drive subscriptions and automatically pay them commissions when users make in-app purchases.

πŸ“‹ Table of Contents


πŸš€ Quick Start (5 Minutes)

Get up and running with minimal code to validate the SDK works before tackling IAP and deep linking setup.

Prerequisites

  • Android 5.0+ (API level 21 or higher)
  • Android Gradle Plugin 8.1+ and Gradle 8.0+
  • Company Code from your Insert Affiliate dashboard

Installation

Step 1: Add JitPack repository to your root build.gradle:

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

Step 2: Add the SDK dependency to your module's build.gradle:

dependencies {
    implementation 'com.github.Insert-Affiliate:InsertAffiliateAndroidSDK:v1.2.0'
}

Your First Integration

Add this minimal code to your MainActivity.java to test the SDK:

import com.aks.insertaffiliateandroid.InsertAffiliateManager;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Initialize SDK with verbose logging (recommended during setup)
        InsertAffiliateManager.init(
            this,
            "YOUR_COMPANY_CODE",  // Get from https://app.insertaffiliate.com/settings
            true                  // Enable verbose logging for setup
        );
    }
}

Expected Console Output:

When the SDK initializes successfully, you'll see these logs:

I/InsertAffiliate TAG: [Insert Affiliate] [VERBOSE] Starting SDK initialization...
I/InsertAffiliate TAG: [Insert Affiliate] [VERBOSE] Company code provided: Yes
I/InsertAffiliate TAG: [Insert Affiliate] [VERBOSE] Verbose logging enabled
I/InsertAffiliate TAG: [Insert Affiliate] SDK initialized with company code: YOUR_COMPANY_CODE
I/InsertAffiliate TAG: [Insert Affiliate] [VERBOSE] Generated and saved new user ID: a1b2c3
I/InsertAffiliate TAG: [Insert Affiliate] [VERBOSE] SDK initialization completed

βœ… If you see these logs, the SDK is working! Now proceed to Essential Setup below.

⚠️ Disable verbose logging in production by setting the third parameter to false or omitting it.


βš™οΈ Essential Setup

Complete these three required steps to start tracking affiliate-driven purchases.

1. Initialize the SDK

The SDK must be initialized in your MainActivity before using any features. You've already done the basic initialization above, but here are additional options:

Basic Initialization (Recommended for Getting Started)

// Minimal setup with verbose logging enabled (recommended during development)
InsertAffiliateManager.init(this, "YOUR_COMPANY_CODE", true);
Advanced Initialization Options (click to expand)
// With Insert Links enabled (for Insert Affiliate's built-in deep linking)
InsertAffiliateManager.init(
    this,                    // Activity context
    "YOUR_COMPANY_CODE",     // Your company code
    true,                    // Enable verbose logging
    true                     // Enable Insert Links (includes install referrer)
);
// With attribution timeout (7 days = 604800 seconds)
InsertAffiliateManager.init(
    this,
    "YOUR_COMPANY_CODE",
    true,                    // Enable verbose logging
    false,                   // Insert Links disabled (if using 3rd party like Branch)
    604800                   // Attribution expires after 7 days
);
// With affiliate transfer prevention (prevents new affiliates from overwriting existing)
InsertAffiliateManager.init(
    this,
    "YOUR_COMPANY_CODE",
    true,                    // Enable verbose logging
    false,                   // Insert Links disabled
    604800,                  // Attribution expires after 7 days
    true                     // Prevent affiliate transfer
);

Parameters:

  • enableVerboseLogging: Shows detailed logs for debugging (disable in production)
  • enableInsertLinks: Set to true if using Insert Links, false if using Branch/AppsFlyer
  • affiliateAttributionActiveTimeSeconds: How long affiliate attribution lasts (0 = never expires)
  • preventAffiliateTransfer: When true, the first affiliate is locked and new affiliate links won't overwrite existing attribution

2. Configure In-App Purchase Verification

Insert Affiliate requires a receipt verification method to validate purchases. Choose ONE of the following:

Method Best For Setup Time Complexity
RevenueCat Most developers, managed infrastructure ~10 min ⭐ Simple
Adapty Paywall A/B testing, analytics ~10 min ⭐ Simple
Google Play Direct Cost-focused users, no 3rd party fees ~15 min ⭐⭐ Medium
Iaptic Custom requirements, direct control ~20 min ⭐⭐⭐ Advanced

Option 1: RevenueCat (Recommended)

Step 1: Code Setup

Complete the RevenueCat Android SDK installation first, then modify your MainActivity.java:

import com.revenuecat.purchases.Purchases;
import com.aks.insertaffiliateandroid.InsertAffiliateManager;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize Insert Affiliate SDK with 7-day attribution timeout
        InsertAffiliateManager.init(this, "YOUR_COMPANY_CODE", true, false, 604800);
        // Set up callback for affiliate identifier changes (now includes offer code)
        InsertAffiliateManager.setInsertAffiliateIdentifierChangeCallback(
            this,
            (identifier, offerCode) -> {
                if (identifier != null) {
                    updateRevenueCatAttribution(identifier, offerCode);
                }
            }
        );
    }
    private void updateRevenueCatAttribution(String affiliateId, String offerCode) {
        // OPTIONAL: Prevent attribution for existing subscribers
        // Uncomment to ensure affiliates only earn from users they actually brought:
        /*
        Purchases.getSharedInstance().getCustomerInfo(new ReceiveCustomerInfoCallback() {
            @Override
            public void onReceived(@NonNull CustomerInfo customerInfo) {
                if (!customerInfo.getEntitlements().getActive().isEmpty()) {
                    // User already subscribed, don't attribute to this affiliate
                    return;
                }
                // Continue with attribution below...
            }
            @Override
            public void onError(@NonNull PurchasesError error) { }
        });
        */
        // Set main attributes
        Map<String, String> attributes = new HashMap<>();
        attributes.put("insert_affiliate", affiliateId);
        // Add expiry timestamp for RevenueCat targeting rules
        Long expiryTimestamp = InsertAffiliateManager.getAffiliateExpiryTimestamp(this);
        if (expiryTimestamp != null) {
            attributes.put("insert_timedout", String.valueOf(expiryTimestamp));
        }
        Purchases.getSharedInstance().setAttributes(attributes);
        // IMPORTANT: Set affiliateOfferCode in a SEPARATE call for targeting to work reliably
        if (offerCode != null && !offerCode.isEmpty()) {
            Map<String, String> offerCodeAttr = new HashMap<>();
            offerCodeAttr.put("affiliateOfferCode", offerCode);
            Purchases.getSharedInstance().setAttributes(offerCodeAttr);
        }
        // Sync attributes AND reload offerings for targeting to work
        Purchases.getSharedInstance().syncAttributesAndOfferingsIfNeededWith(
            error -> Log.e("MainActivity", "Sync error: " + error.getMessage()),
            offerings -> {
                // Offerings now reflect targeting based on affiliateOfferCode
                Log.d("MainActivity", "RevenueCat synced, current offering: " +
                    (offerings.getCurrent() != null ? offerings.getCurrent().getIdentifier() : "null"));
            }
        );
    }
}

Expected Console Output:

I/InsertAffiliate TAG: [Insert Affiliate] SDK initialized with company code: YOUR_COMPANY_CODE
I/InsertAffiliate TAG: [Insert Affiliate] [VERBOSE] Found identifier: SHORTCODE-a1b2c3

Step 2: Webhook Setup

  1. In RevenueCat, create a new webhook
  2. Configure webhook settings:
    • Webhook URL: https://api.insertaffiliate.com/v1/api/revenuecat-webhook
    • Event Type: "All events"
  3. In your Insert Affiliate dashboard:
    • Set In-App Purchase Verification to RevenueCat
    • Copy the RevenueCat Webhook Authentication Header value
  4. Back in RevenueCat webhook config:
    • Paste the authentication header value into the Authorization header field

βœ… RevenueCat setup complete! Now skip to Step 3: Set Up Deep Linking

Option 2: Adapty

Step 1: Add Adapty Dependency

Add Adapty to your module's build.gradle:

dependencies {
    implementation 'io.adapty:android-sdk:3.3.0'
    implementation 'io.adapty:android-ui:3.3.0'
}

Step 2: Initialize Adapty

In your Application class (e.g., MyApp.java):

import android.app.Application;
import com.adapty.Adapty;
import com.adapty.models.AdaptyConfig;
import com.adapty.utils.AdaptyLogLevel;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
public class MyApp extends Application {
    // Track Adapty activation state to prevent double activation and fix race conditions
    private static final CountDownLatch adaptyActivationLatch = new CountDownLatch(1);
    private static final AtomicBoolean adaptyActivated = new AtomicBoolean(false);
    @Override
    public void onCreate() {
        super.onCreate();
        // Set log level before activation (optional)
        Adapty.setLogLevel(AdaptyLogLevel.VERBOSE);
        // Initialize Adapty with protection against double activation
        if (adaptyActivated.compareAndSet(false, true)) {
            Adapty.activate(
                getApplicationContext(),
                new AdaptyConfig.Builder("YOUR_ADAPTY_PUBLIC_KEY").build(),
                (AdaptyProfile profile) -> {
                    adaptyActivationLatch.countDown();  // Signal activation complete
                }
            );
        }
    }
    // Call this method to wait for Adapty activation before updating profile
    public static void waitForAdaptyActivation() {
        try {
            adaptyActivationLatch.await();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

Step 3: Code Setup

In your MainActivity.java:

import com.adapty.Adapty;
import com.adapty.models.AdaptyProfileParameters;
import com.aks.insertaffiliateandroid.InsertAffiliateManager;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize Insert Affiliate SDK
        InsertAffiliateManager.init(this, "YOUR_COMPANY_CODE", true);
        // Set up callback for affiliate identifier changes - update Adapty when identifier changes
        InsertAffiliateManager.setInsertAffiliateIdentifierChangeCallback(
            this,
            new InsertAffiliateManager.InsertAffiliateIdentifierChangeCallback() {
                @Override
                public void onIdentifierChanged(String identifier, String offerCode) {
                    if (identifier != null && !identifier.isEmpty()) {
                        updateAdaptyProfile(identifier);
                    }
                }
            }
        );
    }
    private void updateAdaptyProfile(String affiliateId) {
        // Run on background thread to avoid blocking UI while waiting for Adapty
        new Thread(() -> {
            // Wait for Adapty activation before updating profile
            MyApp.waitForAdaptyActivation();
            AdaptyProfileParameters.Builder builder = new AdaptyProfileParameters.Builder()
                    .withCustomAttribute("insert_affiliate", affiliateId);
            Adapty.updateProfile(builder.build(), error -> {
                if (error != null) {
                    Log.e("MainActivity", "Failed to update Adapty profile: " + error.getMessage());
                } else {
                    Log.d("MainActivity", "Adapty profile updated with insert_affiliate: " + affiliateId);
                }
            });
        }).start();
    }
}

Expected Console Output:

D/MainActivity: Adapty profile updated with insert_affiliate: SHORTCODE-a1b2c3

Step 4: Webhook Setup

  1. In your Insert Affiliate dashboard:

    • Set In-App Purchase Verification to Adapty
    • Copy the Adapty Webhook URL
    • Copy the Adapty Webhook Authorization Header value
  2. In the Adapty Dashboard:

    • Navigate to Integrations β†’ Webhooks
    • Set Production URL to the webhook URL from Insert Affiliate
    • Set Sandbox URL to the same webhook URL
    • Paste the authorization header value into Authorization header value
    • Enable these options:
      • Exclude historical events
      • Send attribution
      • Send trial price
      • Send user attributes
    • Save the configuration

Step 5: Verify Integration

To confirm the affiliate identifier is set correctly:

  1. Go to app.adapty.io/profiles/users
  2. Find the test user who made a purchase
  3. Look for insert_affiliate in Custom attributes with format: {SHORT_CODE}-{UUID}

βœ… Adapty setup complete! Now skip to Step 3: Set Up Deep Linking

Option 3: Google Play Direct

Step 1: RTDN Setup

Complete the Real Time Developer Notifications setup in the Insert Affiliate documentation.

Step 2: Code Implementation

import com.aks.insertaffiliateandroid.InsertAffiliateManager;
public class InAppFragment extends Fragment {
    @Override
    public void onProductsPurchased(@NonNull List<PurchaseInfo> purchases) {
        for (PurchaseInfo purchase : purchases) {
            purchasedInfoList.add(purchase);
            // Store expected transaction for backend validation
            InsertAffiliateManager.storeExpectedPlayStoreTransaction(
                getActivity(),
                purchase.getPurchaseToken()
            );
        }
    }
}

Expected Console Output:

I/InsertAffiliate TAG: [Insert Affiliate] Storing expected transaction: {"UUID":"token123...","companyCode":"YOUR_CODE","shortCode":"AFFILIATE1","storedDate":"2025-11-24T10:30:00Z"}
I/InsertAffiliate TAG: [Insert Affiliate] Expected transaction stored successfully.

βœ… Google Play Direct setup complete! Now proceed to Step 3: Set Up Deep Linking

Option 4: Iaptic

Step 1: Code Setup

Install the Google In-App Billing Library (or your preferred billing library), then add this to your purchase handling code:

import com.aks.insertaffiliateandroid.InsertAffiliateManager;
public class InAppFragment extends Fragment {
    InsertAffiliateManager insertAffiliateManager;
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        insertAffiliateManager = new InsertAffiliateManager(getActivity());
        return view;
    }
    @Override
    public void onProductsPurchased(@NonNull List<PurchaseInfo> purchases) {
        for (PurchaseInfo purchase : purchases) {
            // Validate purchase with Iaptic via Insert Affiliate SDK
            insertAffiliateManager.validatePurchaseWithIapticAPI(
                getActivity(),
                "YOUR_IAPTIC_APP_NAME",     // From https://www.iaptic.com/account
                "YOUR_IAPTIC_PUBLIC_KEY",   // From https://www.iaptic.com/settings
                purchase.getProduct(),
                purchase.getOrderId(),
                purchase.getPurchaseToken(),
                purchase.getOriginalJson(),
                purchase.getSignature()
            );
        }
    }
}

Step 2: Webhook Setup

  1. In your Insert Affiliate dashboard settings:
    • Set In-App Purchase Verification to Iaptic
    • Copy both Iaptic Webhook URL and Iaptic Webhook Sandbox URL
  2. In your Iaptic Settings:
    • Paste the webhook URLs into Webhook URL and Sandbox Webhook URL fields
    • Click Save Settings
  3. Complete the Iaptic Google Play Notifications setup

βœ… Iaptic setup complete! Now proceed to Step 3: Set Up Deep Linking


3. Set Up Deep Linking

Deep linking lets affiliates share unique links that track users to your app. Choose ONE deep linking provider:

Provider Best For Complexity Setup Guide
Insert Links Simple setup, no 3rd party ⭐ Simple View
Branch.io Robust attribution, deferred deep linking ⭐⭐ Medium View
AppsFlyer Enterprise analytics, comprehensive attribution ⭐⭐ Medium View

Option 1: Insert Links (Simplest)

Insert Links is Insert Affiliate's built-in deep linking solutionβ€”no third-party SDK required.

Prerequisites:

Code Implementation:

Choose the example that matches your IAP verification platform:

With RevenueCat:

import com.aks.insertaffiliateandroid.InsertAffiliateManager;
import com.revenuecat.purchases.Purchases;
import android.content.Intent;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize SDK with Insert Links enabled
        InsertAffiliateManager.init(
            this,
            "YOUR_COMPANY_CODE",
            true,  // Verbose logging
            true   // Enable Insert Links
        );
        // Set up callback for affiliate identifier changes (now includes offer code)
        InsertAffiliateManager.setInsertAffiliateIdentifierChangeCallback(
            this,
            (identifier, offerCode) -> {
                if (identifier != null) {
                    // OPTIONAL: Check if user already has active subscription
                    // Uncomment to prevent affiliates earning from existing subscribers:
                    // Purchases.getSharedInstance().getCustomerInfo(info -> {
                    //     if (!info.getEntitlements().getActive().isEmpty()) return;
                    //     // Continue with attribution...
                    // });
                    Map<String, String> attributes = new HashMap<>();
                    attributes.put("insert_affiliate", identifier);
                    Purchases.getSharedInstance().setAttributes(attributes);
                    // Set affiliateOfferCode separately for targeting
                    if (offerCode != null && !offerCode.isEmpty()) {
                        Map<String, String> offerCodeAttr = new HashMap<>();
                        offerCodeAttr.put("affiliateOfferCode", offerCode);
                        Purchases.getSharedInstance().setAttributes(offerCodeAttr);
                    }
                    Purchases.getSharedInstance().syncAttributesAndOfferingsIfNeededWith(
                        error -> { /* handle error */ },
                        offerings -> { /* offerings synced with targeting */ }
                    );
                }
            }
        );
        // Handle deep link from app launch
        InsertAffiliateManager.handleInsertLink(this, getIntent());
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        InsertAffiliateManager.handleInsertLink(this, intent);
    }
}

With Adapty:

import com.aks.insertaffiliateandroid.InsertAffiliateManager;
import com.adapty.Adapty;
import com.adapty.models.AdaptyProfileParameters;
import android.content.Intent;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize SDK with Insert Links enabled
        InsertAffiliateManager.init(
            this,
            "YOUR_COMPANY_CODE",
            true,  // Verbose logging
            true   // Enable Insert Links
        );
        // Set up callback for affiliate identifier changes (now includes offer code)
        InsertAffiliateManager.setInsertAffiliateIdentifierChangeCallback(
            this,
            (identifier, offerCode) -> {
                if (identifier != null && !identifier.isEmpty()) {
                    updateAdaptyProfile(identifier);
                }
            }
        );
        // Handle deep link from app launch
        InsertAffiliateManager.handleInsertLink(this, getIntent());
    }
    private void updateAdaptyProfile(String affiliateId) {
        AdaptyProfileParameters.Builder builder = new AdaptyProfileParameters.Builder()
                .withCustomAttribute("insert_affiliate", affiliateId);
        Adapty.updateProfile(builder.build(), error -> {
            if (error != null) {
                Log.e("MainActivity", "Failed to update Adapty: " + error.getMessage());
            } else {
                Log.d("MainActivity", "Adapty updated with: " + affiliateId);
            }
        });
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        InsertAffiliateManager.handleInsertLink(this, intent);
    }
}

With Google Play Direct or Iaptic:

import com.aks.insertaffiliateandroid.InsertAffiliateManager;
import android.content.Intent;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Initialize SDK with Insert Links enabled
        InsertAffiliateManager.init(
            this,
            "YOUR_COMPANY_CODE",
            true,  // Verbose logging
            true   // Enable Insert Links
        );
        // Set up callback for affiliate identifier changes (now includes offer code)
        InsertAffiliateManager.setInsertAffiliateIdentifierChangeCallback(
            this,
            (identifier, offerCode) -> {
                Log.i("InsertAffiliate", "Affiliate identifier stored: " + identifier + ", offerCode: " + offerCode);
                // Identifier is stored automatically for direct store integration
            }
        );
        // Handle deep link from app launch
        InsertAffiliateManager.handleInsertLink(this, getIntent());
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        InsertAffiliateManager.handleInsertLink(this, intent);
    }
}

Expected Console Output:

I/InsertAffiliate TAG: [Insert Affiliate] [VERBOSE] Insert links enabled: true
I/InsertAffiliate TAG: [Insert Affiliate] Deep link detected with insertAffiliate parameter: AFFILIATE1
I/InsertAffiliate TAG: [Insert Affiliate] Setting affiliate identifier.
I/InsertAffiliate TAG: [Insert Affiliate] Short link received: AFFILIATE1
I/InsertAffiliate TAG: [Insert Affiliate] Storing affiliate identifier: AFFILIATE1

Android App Links (Optional, Recommended)

Android App Links provide a better user experience than custom URL schemes. When a user taps an Insert Link and already has your app installed, Android opens the app directly β€” without loading the browser or showing a disambiguation dialog.

Prerequisites:

  • Enter your Android Bundle Identifier (package name) and SHA-256 Certificate Fingerprints in the Insert Affiliate dashboard settings

To find your SHA-256 fingerprint:

# For debug builds
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android | grep SHA256
# For release builds (use your keystore)
keytool -list -v -keystore your-release-key.keystore -alias your-alias | grep SHA256

Step 1: Add intent filter to AndroidManifest.xml

Add this inside your main <activity> tag:

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" android:host="insertaffiliate.link" />
</intent-filter>

If you have a custom domain (e.g. links.yourcompany.com), add another intent filter:

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" android:host="links.yourcompany.com" />
</intent-filter>

Step 2: Set launch mode on your Activity

Add android:launchMode="singleTop" to your main activity to prevent it being recreated when an App Link is tapped while the app is already running:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop"
    ...>

This ensures onNewIntent() is called instead of creating a new activity instance. Without this, the activity will "flash" and reload, potentially losing the deep link data.

Step 3: Handle App Links in your Activity

No additional code changes needed β€” handleInsertLink() already handles both custom URL schemes and https:// App Links automatically. Just make sure you call it from both onCreate() and onNewIntent().

Testing App Links:

# Via ADB
adb shell am start -a android.intent.action.VIEW -d "https://insertaffiliate.link/YOUR_COMPANY_CODE/TEST_SHORT_CODE"

Note: App Links verification requires the app to be signed with the certificate matching the fingerprint in the dashboard. Debug builds use a different certificate than release builds β€” add both fingerprints if testing in debug mode.

βœ… Insert Links setup complete! Skip to Verify Your Integration

Option 2: Branch.io

Branch.io provides robust attribution and deferred deep linking capabilities.

Key Integration Steps:

  1. Install and configure Branch SDK for Android
  2. Extract ~referring_link from Branch callback
  3. Pass to Insert Affiliate SDK using setInsertAffiliateIdentifier()

πŸ“– View complete Branch.io integration guide β†’

βœ… After completing Branch setup, skip to Verify Your Integration

Option 3: AppsFlyer

AppsFlyer provides enterprise-grade analytics and comprehensive attribution.

Key Integration Steps:

  1. Install and configure AppsFlyer SDK for Android
  2. Create AppsFlyer OneLink in dashboard
  3. Extract deep link from onAppOpenAttribution() callback
  4. Pass to Insert Affiliate SDK using setInsertAffiliateIdentifier()

πŸ“– View complete AppsFlyer integration guide β†’

βœ… After completing AppsFlyer setup, proceed to Verify Your Integration


βœ… Verify Your Integration

Before going live, verify everything works correctly:

Integration Checklist

  • SDK Initializes: Check console for SDK initialized with company code log
  • Affiliate Identifier Stored: Click a test affiliate link and verify console shows Storing affiliate identifier: [CODE]
  • Purchase Tracked: Make a test purchase and verify transaction is sent to Insert Affiliate

Testing Commands

Test Deep Link (via ADB):

# Replace with your actual deep link URL
adb shell am start -a android.intent.action.VIEW -d "https://your-app.onelink.me/abc123"

Check Stored Affiliate Identifier:

String affiliateId = InsertAffiliateManager.returnInsertAffiliateIdentifier(this);
Log.d("Test", "Current affiliate ID: " + affiliateId);

Expected Output: Current affiliate ID: AFFILIATE1-a1b2c3

Common Setup Issues

Issue Solution
"Company code is not set" Ensure init() is called before any other SDK methods
"No affiliate identifier found" User must click an affiliate link before making a purchase
Deep link opens browser instead of app Verify intent filters in AndroidManifest.xml and SHA-256 certificate
Purchase not tracked Check webhook configuration in IAP verification platform

πŸ”§ Advanced Features

Event Tracking (Beta)

Track custom events beyond purchases (e.g., signups, referrals) to incentivize affiliates for specific actions.

// Track custom event (affiliate identifier must be set first)
InsertAffiliateManager.trackEvent(this, "user_signup");

Expected Console Output:

I/InsertAffiliate TAG: [Insert Affiliate] Event tracked successfully

Use Cases:

  • Pay affiliates for signups instead of purchases
  • Track trial starts, content unlocks, or other conversions

Short Codes

Short codes are 3-25 character alphanumeric codes affiliates can share (e.g., "SAVE20" in a TikTok video description).

Validate and Store Short Code:

InsertAffiliateManager.setShortCode(this, "SAVE20", new InsertAffiliateManager.ShortCodeValidationCallback() {
    @Override
    public void onValidationComplete(boolean isValid) {
        if (isValid) {
            Log.i("MyApp", "Short code is valid!");
            // Show success message to user
        } else {
            Log.e("MyApp", "Invalid short code");
            // Show error message
        }
    }
});

Get Affiliate Details Without Setting:

InsertAffiliateManager.getAffiliateDetails("SAVE20", new InsertAffiliateManager.AffiliateDetailsCallback() {
    @Override
    public void onAffiliateDetailsReceived(InsertAffiliateManager.AffiliateDetails details) {
        if (details != null) {
            Log.i("MyApp", "Affiliate: " + details.getAffiliateName());
            // Display affiliate info to user
        }
    }
});

Learn more: Short Codes Documentation

Dynamic Offer Codes / Discounts

Automatically apply discounts or trials when users come from specific affiliates.

How It Works:

  1. Configure an offer code modifier in your Insert Affiliate dashboard (e.g., -oneweekfree)
  2. SDK automatically fetches and stores the modifier when affiliate identifier is set
  3. Use the modifier to construct dynamic product IDs

Quick Example:

String offerCode = InsertAffiliateManager.getStoredOfferCode(this);
if (offerCode != null) {
    // Construct dynamic product ID
    String productId = "oneMonthSubscription" + offerCode;
    // Result: "oneMonthSubscription-oneweekfree"
}

πŸ“– View complete Dynamic Offer Codes guide β†’

Includes full examples for:

  • Google Play Console setup (multiple products, base plans, developer offers)
  • Google Play Billing integration with automatic product selection
  • RevenueCat integration with dynamic offerings
  • Testing and troubleshooting

Attribution Timeout Control

Control how long affiliate attribution remains active after a user clicks a link (e.g., 7-day attribution window).

Set Timeout During Initialization:

// 7-day attribution window (604800 seconds)
InsertAffiliateManager.init(this, "YOUR_COMPANY_CODE", false, false, 604800);

Check Attribution Validity:

boolean isValid = InsertAffiliateManager.isAffiliateAttributionValid(this);
if (isValid) {
    // Attribution is still active
} else {
    // Attribution expired
}

Common Timeout Values:

  • 1 day: 86400
  • 7 days: 604800 (recommended)
  • 30 days: 2592000
  • No timeout: 0 (default)

Get Attribution Date:

long storedDate = InsertAffiliateManager.getAffiliateStoredDate(this);
// Returns seconds since epoch

Get Expiry Timestamp (for RevenueCat targeting):

Long expiryTimestamp = InsertAffiliateManager.getAffiliateExpiryTimestamp(this);
// Returns Unix timestamp in milliseconds when attribution expires
// Returns null if no timeout configured or no affiliate exists

Prevent Affiliate Transfer

By default, clicking a new affiliate link will overwrite any existing attribution. Enable preventAffiliateTransfer to lock the first affiliate:

InsertAffiliateManager.init(
    this,
    "YOUR_COMPANY_CODE",
    true,      // verbose logging
    false,     // insert links
    604800,    // 7-day timeout
    true       // prevent affiliate transfer
);

How it works:

  • When enabled, once a user is attributed to an affiliate, that attribution is locked
  • New affiliate links will not overwrite the existing attribution
  • The callback still fires with the existing affiliate data (not the new one)
  • Useful for preventing "affiliate stealing" where users click competitor links

Example scenario:

  1. User clicks Affiliate A's link β†’ attributed to Affiliate A
  2. User later clicks Affiliate B's link β†’ still attributed to Affiliate A (blocked)
  3. Affiliate A gets credit for any purchases

Learn more: Prevent Affiliate Transfer Documentation


πŸ” Troubleshooting

Initialization Issues

Error: "Company code is not set"

  • Cause: SDK not initialized or init() called after other SDK methods
  • Solution: Call InsertAffiliateManager.init() in onCreate() before any other SDK methods

Deep Linking Issues

Problem: Deep link opens Play Store or browser instead of app

  • Cause: Missing or incorrect intent filters, or SHA-256 certificate not configured
  • Solution:
    • Verify intent filters in AndroidManifest.xml match your deep link domain
    • Add SHA-256 certificate fingerprint to your deep linking provider's console
    • For Play App Signing, use SHA-256 from Google Play Console β†’ Setup β†’ App Integrity

Problem: "No affiliate identifier found"

  • Cause: User hasn't clicked an affiliate link yet
  • Solution: Ensure users come from affiliate links before purchases. Test with adb command:
    adb shell am start -a android.intent.action.VIEW -d "YOUR_DEEP_LINK_URL"

RevenueCat Targeting Issues

Problem: RevenueCat not returning the expected targeted offering

  • Cause: affiliateOfferCode attribute not being saved properly
  • Solution:
    • Set affiliateOfferCode in a separate setAttributes() call (see RevenueCat code example above)
    • Always call syncAttributesAndOfferingsIfNeeded() after setting attributes
    • Fetch offerings after sync completes, not before
    • Verify the targeting rule exists in RevenueCat dashboard
    • Check RevenueCat customer profile to confirm affiliateOfferCode attribute is saved

Purchase Tracking Issues

Problem: Purchases not appearing in Insert Affiliate dashboard

  • Cause: Webhook not configured or affiliate identifier not passed to IAP platform
  • Solution:
    • Verify webhook URL and authorization headers are correct
    • For RevenueCat: Confirm insert_affiliate attribute is set before purchase
    • For Iaptic/Google Direct: Check that affiliate identifier exists when purchase is made
    • Enable verbose logging and check console for errors

Verbose Logging

Enable detailed logs during development to diagnose issues:

InsertAffiliateManager.init(this, "YOUR_COMPANY_CODE", true);

Filter logs by tag:

adb logcat | grep "InsertAffiliate TAG"

Important: Disable verbose logging in production builds.

Getting Help


πŸ“š Support


Need help getting started? Check out our quickstart guide or contact support.

Read the original on github.com β†—