AppsFlyer

Send in-app subscription data to AppsFlyer

Accurately measure what drives your subscription revenue on ad campaign level by tracking events like trial-to-paying-user conversions, renewals, refunds, and upgrades.
Qonversion tracks revenue even if a user does not open your app. This allows measuring the performance of each subscription plan with 100% accuracy.

1. Set up the SDKs

  1. You need to have AppsFlyer SDK integrated into your app before starting with this integration. If you do not have AppsFlyer integration yet, please use this documentation.

  2. Set Qonversion SDKs following installing the SDKs guides.

  3. Send AppsFlyer user ID to Qonversion. In the onConversionDataSuccess callback use theQonversion.setProperty() method with the AppsFlyer user ID value.

  4. Send attribution data to Qonversion. In the onConversionDataSuccess callback use the Qonversion.addAttributionData() method for passing the attribution data:

📘

For Qonversion to be able to receive the attribution data, AppsFlyer SDK needs to be initialized before Qonversion SDK

// AppsFlyer 6

import AppsFlyerLib
extension AppDelegate: AppsFlyerLibDelegate {

    func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]!) {
        Qonversion.addAttributionData(conversionInfo, from: .appsFlyer)
        Qonversion.setProperty(.appsFlyerUserID, value: AppsFlyerLib.shared().getAppsFlyerUID())
    }
    
    func onConversionDataFail(_ error: Error!) {
    
    }
}

// Appsflyer 5

import AppsFlyerLib
extension AppDelegate: AppsFlyerTrackerDelegate {

    func onConversionDataSuccess(_ conversionInfo: [AnyHashable : Any]!) {
        Qonversion.addAttributionData(conversionInfo, from: .appsFlyer)
        Qonversion.setProperty(.appsFlyerUserID, value: AppsFlyerTracker.shared()?.getAppsFlyerUID())
    }
    
    
    func onConversionDataFail(_ error: Error!) {
    
    }
}
/// AppsFlyer 6 
  
#import <AppsFlyerLib/AppsFlyerLib.h>

@interface AppDelegate: UIResponder <UIApplicationDelegate, AppsFlyerLibDelegate>

- (void)onConversionDataSuccess:(NSDictionary *)conversionInfo {
    [Qonversion addAttributionData:conversionInfo fromProvider:QAttributionProviderAppsFlyer];
    [Qonversion setProperty:QNPropertyAppsFlyerUserID value:[[AppsFlyerTracker sharedTracker] getAppsFlyerUID]];
}

- (void)onConversionDataFail:(NSError *)error {

}

@end

/// AppsFlyer 5

#import <AppsFlyerTracker/AppsFlyerTracker.h>

@interface AppDelegate: UIResponder <UIApplicationDelegate, AppsFlyerTrackerDelegate>

- (void)onConversionDataSuccess:(NSDictionary *)conversionInfo {
    [Qonversion addAttributionData:conversionInfo fromProvider:QAttributionProviderAppsFlyer];
    [Qonversion setProperty:QNPropertyAppsFlyerUserID value:[[AppsFlyerLib shared] getAppsFlyerUID]];
}

- (void)onConversionDataFail:(NSError *)error {

}

@end
AppsFlyerConversionListener conversionListener = new AppsFlyerConversionListener() {

            @Override
            public void onConversionDataSuccess(final Map<String, Object> conversionData) {
              Qonversion.setProperty(QUserProperties.AppsFlyerUserId, AppsFlyerLib.getInstance().getAppsFlyerUID(App.this));
              Qonversion.attribution(conversionData, AttributionSource.AppsFlyer);
            }

            @Override
            public void onConversionDataFail(String errorMessage) {

            }

            @Override
            public void onAppOpenAttribution(Map<String, String> conversionData) {

            }

            @Override
            public void onAttributionFailure(String errorMessage) {

            }
        };

        AppsFlyerLib.getInstance().init("afDevKey", conversionListener, this);
val conversionListener: AppsFlyerConversionListener = object : AppsFlyerConversionListener {
            override fun onConversionDataSuccess(conversionData: Map<String, Any>) {
            Qonversion.setProperty(
                QUserProperties.AppsFlyerUserId,
                AppsFlyerLib.getInstance().getAppsFlyerUID([email protected])
            )
            Qonversion.attribution(conversionData, AttributionSource.AppsFlyer)
            }

            override fun onConversionDataFail(errorMessage: String) {}
            override fun onAppOpenAttribution(conversionData: Map<String, String>) {}
            override fun onAttributionFailure(errorMessage: String) {}
        }

        AppsFlyerLib.getInstance().init("afDevKey", conversionListener, this)
this.onInstallConversionDataCanceller = appsFlyer.onInstallConversionData(
  (res) => {
    Qonversion.addAttributionData(res, Provider.APPSFLYER);
    
    appsFlyer.getAppsFlyerUID((err, appsFlyerUID) => {
      if (err) {
        console.error(err);
      } else {
        Qonversion.setProperty(Property.APPS_FLYER_USER_ID, appsFlyerUID);
      }
    });
  }
);
_appsflyerSdk.onInstallConversionData((res) {
  print("res: " + res.toString());
  setState(() {
    _gcd = res;
  });

  Qonversion.addAttributionData(data, provider: QAttributionProvider.appsFlyer, userId: null);
  Qonversion.setProperty(QUserProperty.appsFlyerUserId, 'your appsflyer user id');
});
using AppsFlyerSDK;
using QonversionUnity;

public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData
{
    void Start()
    {
        /* AppsFlyer.setDebugLog(true); */
        AppsFlyer.initSDK("devkey", "appID", this);
        AppsFlyer.startSDK();
    }

    public void onConversionDataSuccess(string conversionData)
    {
        Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
        Qonversion.AddAttributionData(conversionData, AttributionSource.AppsFlyer);
    }
}

❗️

Do not track any purchase events on the client side

Qonversion tracks all revenue events so if you track revenue events with AppsFlyer SDK, you may double count the revenue in your AppsFlyer account.

2. Configure the Appsflyer integration

Provide Integration Details

  1. Get AppsFlyer Dev Key in your AppsFlyer account navigate to Configuration → App Settings → Dev Key.

  2. Get your App ID. You can find App ID in App Store URL:
    For iOS

    https://apps.apple.com/us/app/apple-developer/id640199958

    For Android

    https://play.google.com/store/apps/details?id=com.android.chrome
  3. Navigate to the Integrations section in your Qonversion project, select AppsFlyer, and provide the Dev Key and App ID, and Save.

AppsFlyer Dev Key, App ID, and other settingsAppsFlyer Dev Key, App ID, and other settings

AppsFlyer Dev Key, App ID, and other settings

Configure the event names

We recommend using the default event names provided by Qonversion. But you can change the event names based on your preferences.
Note, that the event names will not affect revenue recognition. All purchase events containing a value (subscription started, trial converted, subscription renewed, subscription refunded, in-app purchase) will be sent to AppsFlyer with af_revenue property, and the revenue will be recognized correctly in AppsFlyer.

Read more about tracked events here

👍

Done!

Now Qonversion will start sending in-app purchases and subscriptions data to your AppsFlyer account.

Event Payload

We are providing an event payload that Qonversion sends to AppsFlyer below for your reference:

{
    // A unique identifier, generated by AppsFlyer
    'appsflyer_id': '', 
    'os': '14.6',
    'app_version_name': '1.0.0',

    
    // Set up from SDK
    // a unique user identifier set by the app owner
    'customer_user_id': 'outside_uid', 
    'idfa': '',
    'idfv': '',
    'eventName': 'trial_converted',
    'renewal': false, 
    
    // UTC time the event happened. 
    // AppsFlyer needs to get the event by 02:00 UTC of the following day. 
    // Otherwise AppsFlyer will use the time it has received the event. 
    'eventTime': 'Y-m-d H:i:s.u', 
    'eventValue': {
        'af_content_type': 'product',
        'af_content_id': 'product_id',
        'af_revenue': '1.99',
        'af_currency': 'EUR',
    }
}

📘

Check out the sample Xcode Project

Here you can find the sample Xcode project that demonstrates the Qonversion and AppsFlyer integration

How to compare your app revenue in AppsFlyer to Qonversion

Navigate to your AppsFlyer → Overview section. You can see the LTV (lifetime value) overview at the top. This data relates to installs occurred within the selected date range, and all their following lifetime actions. The revenue you see in this dashboard is the revenue generated from the users who installed your app in the selected date range.

To compare the total revenue from this dashboard to the revenue tracked by Qonversion:

  1. Navigate to Qonversion Customers dashboard.
  2. Select the same date range.
  3. See the "Sales" figure at the top right.

This sales number should be equal to your revenue in AppsFlyer. Note, that the sales number is before the App Store commission. If you are sending the revenue to AppsFlyer net of App Store commission (step 1 (4) of this guide above), the sales number will be roughly 30% higher in Qonversion than in AppsFlyer.

There also might be a minor difference due to:

  1. Time zones, Qonversion uses UTC time;
  2. FX rates.

🚧

Troubleshooting

If you don't see attribution data from AppsFlyer in Qonversion in data export or in customer details, you need:

  1. Check that you are using the latest Qonversion SDK version. Update SDK if needed.
  2. Make sure to initialize AppsFlyer SDK before Qonversion SDK.

What’s Next

Other Attribution Platforms

Did this page help you?