ROI360 in-app purchase (IAP) and subscription revenue measurement

Premium

At a glance: Automatically validate and measure revenue from in-app purchases and auto-renewable subscriptions to get the full picture of your customers' life cycles and accurate ROAS measurements.

Overview

Advertisers can use validated in-app purchases (IAP) and subscription revenue to measure:

  • All revenue from in-app purchases of products and subscriptions managed through either App Store Connect (iOS) or Google Play Console (Android).
  • Refunds.
  • Pending and deferred transaction revenue (Android).
  • Subscription-related events that happen inside or outside your app.

The IAP and subscription revenue solution also:

  • Makes sure no duplicate transactions are recorded. For iOS, this also can also ensure that no duplications are recorded for family sharing.
  • Allows AppsFlyer to forward Apple App Store transactions to you (the advertiser).
  • Provides True Revenue data, meaning net revenue data that takes into account store commission and taxes.

The purchase and subscription data originates from:

  • The AppsFlyer purchase SDK connector for Android and iOS (Unity wrapper included).
  • App Store and Google Play (RTDN) server notifications sent to AppsFlyer.

Purchase and subscription revenue data is available via AppsFlyer dashboards and reports. They can also be shared with partners via postbacks.

Considerations:

  • If you use this IAP and subscription revenue measurement solution, you shouldn’t send in-app purchases events or execute validateAndLogInAppPurchase, as doing so results in duplicate revenue being reported.
  • Subscription revenue is able to start recording subscriber life cycle changes for existing subscribers as soon as they launch an app version that includes the purchase SDK connector.

Flow:

  1. A user makes an in-app purchase or auto-renewable subscription.
  2. The app makes a transaction in the app store.
  3. The AppsFlyer purchase SDK connector automatically detects the purchase and sends its payload to AppsFlyer for validation and logging.
  4. AppsFlyer validates the purchase with the relevant store to ensure it's not fraudulent.
    • Upon successful validation, AppsFlyer logs the purchase or subscription.
    • If receipt validation fails, the event displays in the blocked in-app events raw data report (available to Protect360 subscribers). 
  5. AppsFlyer transfers the response to the SDK connector, which in turn transfers the receipt validation response (success or fail) to the app.
  6. Any incoming server notifications are also processed by the AppsFlyer purchase and subscription revenue business logic.
    • Notifications regarding transactions previously reported via the SDK connector are validated and processed, and result in the internal creation of a purchase or life cycle event.
    • Notifications regarding unknown transactions are dropped.
    • For iOS, all server notifications can be rerouted to your own servers.

IAP and Subscription revenue integration workflow

Precisely follow the order of the setup instructions listed in the table below to ensure optimal accuracy and complete reporting of IAP and auto-renewable subscription revenue and life cycle events. Failing to do so can result in permanent reporting inaccuracies. Full details for each step are included in the tabs following the table.

Step Tasks
1

Set up notifications for IAP and subscription revenue from Google Play.

2

Set up notifications for IAP and subscription revenue from the iOS App Store.

3
  • Integrate the AppsFlyer purchase SDK connector for Android and iOS.
  • Recommended for subscription app owners: To identify your subscriber base faster, have server notifications set up before releasing your app version with the SDK connector.
4

Integrate the True Revenue tax API. This is only needed if you want to edit the default tax rates. Otherwise, taxes are reported for any transaction measured by ROI360.

5

Test the integration to ensure:

  • The SDK connector is properly integrated.
  • Server notifications are properly configured and received by AppsFlyer.
6

Release the Android and iOS app versions with the purchase SDK connectors.

Step 1: Set up notifications from Google Play

Before you start:

  • Setting up IAP and subscription revenue consists of steps performed in Google Cloud Platform, and in the AppsFlyer UI. We recommend you keep tabs to Google Cloud Platform and AppsFlyer open throughout the setup.
  • Setup in the AppsFlyer UI requires admin permissions.

Follow the instructions in the tab below to set up notifications from Google Play:

1.1 Link your Google Play Developer Account to your Google Cloud Project

  1. In the Google Play Console, go to your Google Play Developer Account.
  2. Link the account to your Google Cloud project. For instructions, see this Google help topic.
  3. Enable the Google Play Developer API. For instructions, see this Google help topic.

1.2 Create service account

  1. Go to Google Cloud and open the project you just linked in 1.1.
  2. Under your project go to IAM and Admin > Service Accounts, and click Create service account

01.png

  1. In the Create service account page fill the Service account details step.

02.png

  1. Click Create and continue.
  2. In the Grant this service account access to the project step, select the  Pub/sub subscriber role.

03.png

  1. Click Continue > Done.

1.3 Download account private key.

  1. In the Service Accounts page, find the relevant service account, and click  ellipsis.png  and than Manage keys.

08.png

  1. In the Keys tab of the service account page click ADD KEY > Create new key.

10.png

  1. In the Create private key dialog, select the JSON key type.
  2. Click Create. The private key JSON file is downloaded.
  3. In AppsFlyer, from the side menu, select Settings > Revenue Settings.

41.png

  1. Select your app from the list.
  2. In the Purchases and subscriptions tab, click upload-2.png to upload the JSON file. 

40.png

 

1.4 Set API access permissions

  1. In the Google Play Console, go to Users and permissions.
  2. In the Users and permissions list, find the service account you created in 1.2, and click Manage.

14.png

  1. In the Permissions section, go to the Account permissions tab, and select both:
    • View financial data.
    • Manage orders and subscriptions.

15.png

  1. Click Invite user and then Send invitation.

Either 1.5 Send Google Play notifications directly to AppsFlyer

Select one of two methods used to receive IAP and subscription revenue data from Google Play.

Either:

  • Create a topic where AppsFlyer directly receives the RTDN notifications from Google Play (continue in this step)

or

  • Set AppsFlyer as a subscriber to your pre-existing PUB/SUB topic (skip to the next step).

To create a topic where AppsFlyer directly receives the RTDN notifications perform the following steps:

  1. In AppsFlyer, from the side menu, select Settings Revenue Settings Purchases & subscription, select Allow AppsFlyer topic to get RTDN messages directly from google.
    42.png
  2. Copy the AppsFlyer topic to the clipboard.
  3. In Google Play Console > All apps, select your app. The dashboard opens.
    18.png
  4. Go to Monetization setup, and in the Google Play Billing section, in the Topic name field, paste the AppsFlyer topic address you copied in substep 2.
    19.png
  5. For Notification content, select Subscriptions, voided purchases, and all one-time products.
    google notification content.png
  6. Click Save Changes.

OR 1.6 Forward Google Play notifications to AppsFlyer

The other method to receive IAP and subscription notifications is applicable when you already have a pre-existing topic that gets notifications from Google Play.  In this case, set AppsFlyer as a subscriber to your pre-existing PUB/SUB topic instead of creating a new topic (as in the previous step).

To set AppsFlyer as a subscriber to your pre-existing PUB/SUB topic

  1. In AppsFlyer, from the side menu, select Settings > Revenue Settings > Purchases and subscriptions, select Forward your RTDN topic messages to AppsFlyer.
  2. Copy the endpoint URL to the clipboard .
    52.png
  3. In Google Cloud Platform, under your project, search for Pub/Sub.
    21.png
  4. In Pub/Sub go to the Topics section, and verify you have a dedicated pub/sub topic for subscriptions.
    22.png
  5. Go to the Subscriptions section, and click Create subscription.
    25.png
  6. Enter the Subscription ID.
  7. Select the relevant subscription pub/sub topic from the dropdown.
    26.png
  8. For Delivery type, select Push.
  9. Enter the endpoint URL  that you recorded in substep 2.
  10. For Expiry period, select Never expire.
    28.png
  11. Click Save.
  12. Go to the Subscriptions section, and copy the topic name to the clipboard.
    46.png
  13. In Google Play Console, go to Monetization setup, and in the Google Play Billing section, in the Topic name field, paste the topic name that you copied in the previous step.
    19.png
  14. For Notification content, select Subscriptions, voided purchases, and all one-time products.
    google notification content.png
  15. Click Save.

1.7 Configure automatic services

  1. In AppsFlyer, from the side menu, select Settings > Revenue Settings > Purchases and subscriptions, turn on either or both:
    • Validate purchases with Google Play.
    • Attribute and record auto-renewable subscriptions.

50.png

  1. [Optional] Check Allow AppsFlyer to deduplicate transactions that were already reported. This ensures no duplicate transactions are recorded.
  2. Click Save.
Note: It can take time (sometimes even 24 hours) after setting service account credentials and permissions to be able to use them. This may cause you to receive errors when trying to connect to Google RTDN.

Step 2: Set up notifications from the iOS App Store

Before you start:

  • Setting up IAP and subscription revenue consists of steps performed in App Store Connect and in the AppsFlyer UI. Keep tabs to both App Store Connect and AppsFlyer open during setup.

  • Setup in the AppsFlyer UI requires admin permissions.

To configure IAP and subscription revenue:

  1. In App Store Connect, go to Features > Subscriptions, and click Manage to get the App Store Connect shared secret key.
    app_store_connect_shared_secret.png
  2. In AppsFlyer, from the side menu, select Settings > Revenue Settings > Purchases and subscriptions.
    The Revenue configuration page opens.
    ARS-VIAP.png
  3. Enter your App Store Connect shared secret key.
  4. Copy the AppsFlyer endpoint and enter it in your App Store Connect configuration:
    1. In App Store Connect, select your app.
    2. In the App Information section, scroll down to App Store Server Notifications, and paste the AppsFlyer endpoint in the Production Server URL and Sandbox Server URL fields. Note: The AppsFlyer endpoint is the same regardless of whether you use Apple notifications V1 or V2.
      /guide-media/01HH9D9BGV8H7XHW44WN00V11M
    3. Click Save.
  5. [Optional] Select to send server notifications to your endpoint and enter your endpoint. 
  6. In the AppsFlyer IAP and subscription revenue configuration page, turn on either or both:
    • Attribute and report auto-renewable subscriptions.
    • Validate purchases with the Apple App Store.
  7. [Optional] Check Allow AppsFlyer to deduplicate transactions that were already reported.
    This ensures no duplicate transactions are recorded.
  8. [Optional] Check Deduplicate revenue for Family Sharing purchases.
    This ensures no duplicate revenue is recorded for family-sharing purchases. Revenue events for other family members include the parameter purchase_ownership_type=FAMILY_SHARED and display zero revenue.

Note:

  • Apple can only send server notifications to one endpoint.
  • Customers can send Apple server notifications from their backend directly to the notification endpoint URL, but the requests must be exactly as they're received from the App Store.

Step 3: Integrate purchase SDK connector

Integrating the purchase SDK connector enables your app to record both in-app purchases and auto-renewable subsriptions. You can select to record one or both revenue types in Settings > Revenue Settings > Purchases and subscriptions page in AppsFlyer for Android and iOS.

To integrate the SDK connector:

  1. Tell your Android developer to integrate the AppsFlyer Android purchase SDK connector.
    • The AppsFlyer purchase connector V1 for Android supports Google billing library 4.
    • The AppsFlyer purchase connector V2 for Android supports Google billing library 5.
    • The AppsFlyer purchase connector V2.0.1 for Android supports Google billing library 6.
  2. Tell your iOS developer to integrate the AppsFlyer iOS purchase SDK connector.

Note: For apps built using the Unity framework, see the Unity connector documentation

Step 4: Integrate True Revenue tax API

True Revenue is a business logic layer built to serve the AppsFlyer in-app purchase and subscription revenue solution. It automatically calculates the net revenue value for each incoming transaction in real-time and includes it in reports. Tax is reported by default for any transaction measured by ROI360 using the default tax rate configuration. The configuration can be edited using the dedicated tax API.

Learn more about True Revenue

To edit the tax configuration using the tax API:

  1. Give your developer:
    • The API V2 token to use as the authorization key.
    • The parameters and values that contain information on what taxes to calculate, as outlined in the table that follows. 
  2. Tell your developer to follow their tax API instructions to create tax rate rules. Note: The API allows for a JSON file in the body of the post request. This JSON file includes all supported countries and their default tax rates. The developer can edit it or use it as is in the API.

Parameters and values to use in the API

Parameter Mandatory Remarks Record the value (for your developer to use)
tax_name Yes
  • Name appearing in the customer invoice that describes the specific type of tax. 
  • Example: Sales, VAT, GST
 
tax_rate Yes
  • Number up to 4 decimal places representing the tax percentage to be collected.
  • Example: 7.25
 
tax_exclusive No
  • Boolean parameter, either true or false.
  • False means tax is included in the overall revenue.
  • True means tax is in addition to the overall stated revenue. For example, in the USA or Canada, where the sticker price doesn't include sales tax.
  • Default is false.
 
country No  
subdivision No
  • For some countries, there can be an additional state/subdivision.
  • Handled according to ISO 3166-2 subdivision codes.
  • Must include the country code and subdivision code.
  • Example: US-CA
 
postal_code No
  • String of letters and/or numbers
  • Example: L4J8E3
 
deduction_order No
  • Enum, either 0, 1, or 2:
    • 0 means store commission is deducted first from the gross revenue and tax is deducted from the remaining amount.
    • 1 means tax is deducted first from the gross revenue and store commission is deducted remaining amount.
    • 2 means that both tax and store commission are deducted from the total revenue.
 

Step 5: Testing IAP and subscription revenue

It's best to validate the IAP and subscription revenue integrations in a sandbox environment to make sure that the SDK connector is properly integrated and that server notifications are properly configured and received by AppsFlyer.

Prior to the test, make sure your developer configures Sandbox environment in the SDK Connector (by setting Sandbox to true). This allows ROI360 to create only Sandbox in-app events with 0 revenue for tests. Thus, production data isn't affected.

Sandbox environment considerations

In a sandbox environment:

  • Only initial purchase events cause the SDK connector to produce an event that is recorded by AppsFlyer. An IAP event is called af_purchase_sandbox_sdk. A subscription event is called af_ars_sandbox_sdk.
  • All other purchase events are dropped, meaning the SDK connector doesn’t produce an event.
  • Incoming server notifications are only processed if the SDK connector first records the original transaction. In this case, an IAP event is produced called af_purchase_sandbox_s2s. A subscription event is produced called af_ars_sandbox_s2s.
  • An event isn’t produced for any server notification for which the SDK connector didn’t first record the original transaction.
  • For iOS, make sure that under App Store Server Notifications in App Store connect, the AppsFlyer endpoint is configured as your Sandbox Server URL.
    ASSN.png
  • For Android, tests performed by License Testers result in Sandbox events even if Sandbox environment in the SDK isn't configured.

Test IAP and subscription revenue

To test IAP and subscription revenue:

  1. Tell your developers to follow their Android , iOS , and Unity instructions to configure Sandbox environment in the SDK Connector.
  2. Make a test purchase. Transactions performed by License Tester in Google Play and from TestFlight in iOS are also supported.
    Note: Any subscription product can be tested only once from each testing device. In other words, you cannot register multiple test purchases of the same subscription from the same device, as they will not be recorded.
  3. Verify the event displays in the AppsFlyer Activity dashboard. An IAP event is called af_purchase_sandbox_sdk. A subscription event is called af_ars_sandbox_sdk. These events include:
    • A revenue value of 0 (so as not to skew real AppsFlyer reports).
    • An af_sandbox_revenue parameter that includes the revenue value of the product purchased so you can ensure the correct revenue is reported.
  4. If you’re testing a subscription product, give some time for AppsFlyer to receive a server notification from. Usually this occurs within a few minutes after the initial purchase. 
  5. Verify an event displays in the AppsFlyer Activity dashboard. An auto-renewable subscription purchase is called af_ars_sandbox_s2s. The event includes:
    • A revenue value of 0 (so as not to skew real AppsFlyer reports).
    • An af_sandbox_revenue parameter that includes the revenue value of the product purchased so you can ensure the correct revenue is reported.

Step 6: Release the app version with the SDK connector

Before your developer releases the new app version with the purchase SDK connector integrated, make sure that:

  • The in-app events you want to capture as an IAP or subscription aren't blocked by one of the Validation Rules you have configured in AppsFlyer.
  • Your developer should have any sandbox flags marked as false.
  • For iOS, make sure that under App Store Server Notifications in App Store connect, the AppsFlyer endpoint is configured as your Sandbox Server URL.
    ASSN.png

Reference

IAP-related events and parameters

The following sections display the IAP-related events that AppsFlyer measures, and the parameters that are recorded for each event. See the event parameter dictionary for an explanation of the included parameters.

All generated events:

  • Are considered S2S events.
  • Are accessible in raw data reports (as organic or non-organic in-app events).
  • Can be sent via postbacks to partners.
  • Can be used in SKAN Conversion Studio.

Note: Depending on the user device platform, some parameters aren't always populated for an in-app event.

Purchase (af_purchase)

Description

Recorded when a user makes a purchase.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_revenue
  • af_net_revenue
  • af_net_revenue_tax_name
  • af_net_revenue_tax_rate
  • af_net_revenue_tax_exclusive
  • af_net_revenue_country
  • af_net_revenue_subdivision
  • af_net_revenue_postal_code
  • af_net_revenue_factors

Purchase canceled (af_purchase_canceled)

Description

Recorded when a user cancels a purchase.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment

Purchase pending (af_purchase_pending)

Description

Recorded when a user makes a purchase but the payment isn't yet processed.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment

Refund (af_purchase_refund)

Description

Recorded when a purchase is refunded.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_discount_type
  • event_revenue_usd
  • event_revenue (included in the event when the revenue exceeds zero)
  • store_commission
  • af_revenue
  • af_net_revenue
  • af_net_revenue_factors
  • af_net_revenue_tax_name
  • af_net_revenue_tax_rate
  • af_net_revenue_tax_exclusive
  • af_net_revenue_country
  • af_net_revenue_subdivision
  • af_net_revenue_postal_code

Test purchase (af_purchase_sandbox_sdk)

Description

Recorded when testing a purchase recorded via SDK in sandbox environment.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_original_transaction_id
  • af_order_id
  • Af_purchase_token
  • af_transaction_id
  • af_purchase_state
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_net
  • af_sandbox_revenue

Test purchase (af_purchase_sandbox_s2s)

Description

Recorded when testing a purchase reported via S2S in a sandbox environment.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_purchase_state
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_net
  • af_sandbox_revenue

Subscription-related events and parameters

The following sections display the subscription-related events that AppsFlyer measures, and the parameters that are recorded for each event. See the event parameter dictionary for an explanation of the included parameters.

All generated events:

  • Are considered S2S events.
  • Are accessible in raw data reports (as organic or non-organic in-app events).
  • Can be sent via postbacks to partners.
  • Can be used in SKAN Conversion Studio.

Note: Depending on the user device platform, some parameters aren't always populated for an in-app event.

Trial started (af_ars_trial_started)

Description

Recorded when a subscriber begins a trial period.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • Af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • Af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type

Trial canceled (af_ars_trial_canceled)

Description

Recorded when a subscriber cancels the automatic renewal of the subscription during the trial period. If a user doesn't restore the auto-renewal within the trial period, a churn event follows.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • Af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • Af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type

Trial churned (af_ars_trial_churned)

Description

Recorded when a subscriber churns following a trial period. This happens after auto-renewal cancelation and trial period expiration. It can also follow a billing or technical issue with the renewal leading to churn.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • Af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • Af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_reason

Trial converted (af_ars_trial_converted)

Description

Recorded when a fully priced renewal starts, following a trial period. 

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • Af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_discount_id
  • af_discount_type
  • event_revenue_usd
  • store_commission
  • af_revenue (included in the event only when the revenue exceeds zero) 
  • af_net_revenue
  • af_net_revenue_factors
  • af_net_revenue_tax_name
  • af_net_revenue_tax_rate
  • af_net_revenue_tax_exclusive
  • af_net_revenue_country
  • af_net_revenue_subdivision
  • af_net_revenue_postal_code

Subscription started (af_ars_subscription_started)

Description

Recorded when a discounted or a fully priced subscription starts.

Note:

  • New subscriptions can only be recorded via the SDK connector.
  • For iOS, if a subscriber repurchases a subscription they already own, the SDK connector reports a successful receipt validation back to the app, but doesn't record a new transaction in AppsFlyer.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_discount_id
  • af_discount_type
  • event_revenue_usd
  • event_revenue (included in the event when the revenue exceeds zero)
  • store_commission
  • af_revenue
  • af_net_revenue
  • af_net_revenue_factors
  • af_net_revenue_tax_name
  • af_net_revenue_tax_rate
  • af_net_revenue_tax_exclusive
  • af_net_revenue_country
  • af_net_revenue_subdivision
  • af_net_revenue_postal_code

Subscription canceled (af_ars_subscription_canceled)

Description

Recorded when an auto-renewal subscription is canceled in the middle of a billing period. If a user doesn't restore the auto-renewal within the same billing period, a churn event follows.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type

Subscription paused (af_ars_subscription_paused) - Android only

Description

Recorded when a user pauses an active subscription.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type

Subscription resumed (af_ars_subscription_resumed)

Description

Recorded when a fully priced subscription is resumed following a churned or refunded subscription.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_discount_id
  • af_discount_type
  • af_reason
  • event_revenue (included in the event when event revenue exceeds zero)
  • store_commission
  • af_revenue
  • af_net_revenue
  • af_net_revenue_factors

Subscription churned (af_ars_subscription_churned)

Description

Recorded when a subscriber churns. This usually happens after auto-renewal cancelation or billing period expiration. It can also follow a billing or technical issue, with the renewal leading to churn.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • Af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • Af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_reason

Subscription refunded (af_ars_subscription_refunded)

Description

Recorded when a subscriber is issued a refund.

Note:

  • This event is usually generated along with a negative value. In cases where it is impossible to detect which transactions were refunded, or details of the refund aren't included in the notification, the refund event shows no value.

Parameters 

  • app_id
  • customer_user_id
  • af_reason
  • af_subscription_ownership_type
  • af_discount_id
  • af_discount_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_refunded_transaction_ids
  • event_revenue_usd
  • event_revenue (included in the event when the revenue exceeds zero)
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_store
  • af_environment
  • af_period_type
  • store_commission
  • af_revenue
  • af_net_revenue
  • af_net_revenue_factors
  • af_net_revenue_tax_name
  • af_net_revenue_tax_rate
  • af_net_revenue_tax_exclusive
  • af_net_revenue_country
  • af_net_revenue_subdivision
  • af_net_revenue_postal_code

Subscription billing grace (af_ars_subscription_billing_grace)

Description

Recorded when a subscription renewal fails due to a billing issue and the subscriber enters the billing grace period.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • Af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • Af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type

Subscription renewed (af_ars_subscription_renewed)

Description

Recorded when an auto-renewal subscription takes place.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_discount_id
  • af_discount_type
  • event_revenue_usd
  • event_revenue (included in the event when the revenue exceeds zero)
  • store_commission
  • af_revenue
  • af_net_revenue
  • af_net_revenue_factors

Subscription changed (af_ars_subscription_xgraded)

Description

Recorded when a subscriber upgrades, downgrades, or cross-grades to a different product.

Parameters 

  • app_id
  • customer_user_id
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_discount_id
  • af_discount_type
  • event_revenue_usd
  • event_revenue (included in the event when the revenue exceeds zero)
  • store_commission
  • af_revenue
  • af_net_revenue
  • af_net_revenue_factors

Existing subscriber (af_ars_existing_subscriber)

Description

Recorded when the SDK connector is notified about a subscriber in the middle of a billing cycle, before getting a follow-up server notification that transitions the subscriber to another relevant lifecycle stage. This event is usually generated during your onboarding and SDK connector adoption period.

Parameters 

  • app_id
  • customer_user_id
  • country
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_cuids
  • af_validated

Test purchase (af_ars_sandbox_sdk)

Description

Recorded when testing a purchase recorded via SDK in sandbox environment.

Parameters 

  • app_id
  • customer_user_id
  • country
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_discount_id
  • af_discount_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_cuids
  • af_validated
  • af_net
  • af_sandbox_revenue

Test purchase (af_ars_sandbox_s2s)

Description

Recorded when testing a purchase reported via S2S in a sandbox environment.

Parameters 

  • app_id
  • customer_user_id
  • country
  • af_currency
  • af_expires_date_ms
  • af_subscription_ownership_type
  • af_discount_id
  • af_discount_type
  • af_original_transaction_id
  • af_order_id
  • af_purchase_token
  • af_transaction_id
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_purchase_date_ms
  • af_store
  • af_environment
  • af_period_type
  • af_cuids
  • af_validated
  • af_net
  • af_sandbox_revenue

Parameter dictionary

Parameters for IAP and subscription events display in raw data reports either as their own columns or populated as part of the Event value.

The parameters that have their own columns are:

  • app_id
  • customer_user_id
  • country_code
  • af_currency
  • event_revenue_usd
  • af_revenue
  • android_id
  • ip
  • idfa
  • appsflyer_id

See the data fields dictionary for more details about these parameters.

The following table describes the raw data parameters available in ARS and VIAP events.

Parameter Remarks Product
af_cancelation_date_ms Date of the cancelation IAP
af_reason
  • In cancelation or churn-related events, the reason a user churned or canceled. Possible values:
    • iOS:
      • cancel_intent
      • billing_issue
      • declined_price_increase
      • product_unavailable
    • Android:
      • I don't use this service enough
      • Technical issues
      • Cost-related reasons
      • I found a better app
      • Other
  • In subscription resumed events, the reason a user resumed their subscription. Possible values:
    • Android:
      • paused and resumed
      • disabled and enabled auto-renew
  • In refund-related events, the reason why the user received a refund. Possible values:
    • iOS:
      • 1: issue with your app
      • 0: another reason
  • IAP
  • Subscription
af_expires_date_ms

The expiration date of the current subscription billing cycle

Subscription

af_subscription_ownership_type

FAMILY_SHARED means the user has access via family sharing.  PURCHASED means the paying user made the purchase.

Subscription

af_discount_id

The offer ID presented to the user during the initial purchase. The ID is populated only when there is a discount code.

  • IAP
  • Subscription
af_discount_type

The discount type redeemed by the user. Possible values:

  • IOS
    • introductory
    • subscription
  • Android
    • intro price
    • one_time_code
    • vanity_code
Subscription
af_original_transaction_id
  • The original transaction ID
  • iOS only
  • IAP
  • Subscription
af_order_id
  • The order ID for the transaction
  • Android only
  • IAP
  • Subscription
af_purchase_token
  • The purchase token for the transaction
  • Android only
  • IAP
  • Subscription
af_transaction_id
  • The ID of the transaction
  • iOS only
  • IAP
  • Subscription
af_purchase_state

Possible values:

  • Purchased
  • Canceled
  • Pending

IAP 

af_original_transaction_id
  • The original ID of the transaction
  • iOS only
  • IAP
  • Subscription
af_refunded_transaction_ids
  • An array of all refunded transaction IDs
  • iOS only
  • IAP
  • Subscription
af_product_id

The subscription product ID

  • IAP
  • Subscription
af_purchase_date_ms

The purchase date for the reported product ID in-app event

  • IAP
  • Subscription
af_store

The app store the subscription product was purchased from

  • IAP
  • Subscription
af_environment

The environment from which data is received, either production or sandbox.

  • IAP
  • Subscription
af_period_type
  • Subscription or trial period type.
  • Possible values:
    • trial
    • intro
    • normal

Subscription

store_commission
  • The calculated percentage of commission the store gets from the purchased product.
  • Displayed as a decimal.
  • Example: 30
  • IAP
  • Subscription
af_net_revenue

Net revenue calculated based on all factored reasons. See af_net_revenue_factors.

  • IAP
  • Subscription
af_net_revenue_factors
  • An array representing all factored reasons that produce the reported af_net_revenue amount.
  • Example value: store_commission
  • IAP
  • Subscription

af_net_revenue_tax_name

  • Name appearing in the customer invoice that describes the specific type of tax. 
  • Example: Sales, VAT, GST
  • IAP
  • Subscription

af_net_revenue_tax_rate

  • Number up to 4 decimal places representing the tax percentage collected.
  • Example: 7.25
  • IAP
  • Subscription

af_net_revenue_tax_exclusive

  • Boolean parameter, either true or false.
  • False means tax is included in the overall revenue.
  • True means tax is in addition to the overall stated revenue. For example, in the USA or Canada, where the sticker price doesn't include sales tax.
  • IAP
  • Subscription

af_net_revenue_country

  • IAP
  • Subscription

af_net_revenue_subdivision

  • For some countries, there can be an additional state/subdivision. This is handled according to ISO 3166-2 subdivision codes.
  • Includes the country code and subdivision code.
  • Example: US-CA
  • IAP
  • Subscription

af_net_revenue_postal_code

  • String of letters and/or numbers
  • Example: L4J8E3
  • IAP
  • Subscription
af_cuids
  • In the context of ARS, this parameter contains an array with all CUIDs.
  • The array of CUIDs displays irrespective of the device IDs. Thus, the same CUIDs can display for more than one device ID.
Subscription

True Revenue

True Revenue is a business logic layer built to serve the AppsFlyer in-app purchase and subscription revenue solution. It automatically calculates the net revenue value for each incoming transaction in real time and includes it in reports. True Revenue considers the following factors in the gross-to-net revenue calculation: 

  • Store commission:
    • Is calculated and reported automatically. No action on your part is required.
    • For purchases, store commission is 30%.
    • For, subscriptions, commission is automatically calculated on a per-subscriber basis, taking into account the lifetime of the subscriber, (App Store: starting at 30% commission, and reducing to 15% after a year, Play Store: 15% commission).
    • Related net revenue parameters are available in raw data reports.
  • Tax:
    • Tax is reported by default for any transaction measured by ROI360 using the default tax rate configuration.
    • The configuration can be edited using the dedicated tax API. This JSON file displays all supported countries and their default tax rates. The developer can edit it or use it as is in the API.

When viewing True Revenue in reports, the following parameters contain the net revenue data. See the parameter dictionary for more details.

Parameter Net revenue factor

store_commission

Store commission

af_net_revenue_tax_name

Tax

af_net_revenue_tax_rate

Tax

af_net_revenue_tax_exclusive

Tax

af_net_revenue_postal_code

Tax

af_net_revenue_country

Tax

af_net_revenue_subdivision

Tax
af_net_revenue
  • Store commission
  • Tax
af_net_revenue_factors
  • Store commission
  • Tax

Specifications and limitations

Specification Product Remarks
Record install and anonymize
  • IAP
  • Subscription revenue
Not supported
New subscriptions

Subscription revenue

Only recorded via the AppsFlyer purchase SDK
Price change

Subscription revenue

If subscription revenue doesn't receive an SDK-originated notification with the new product price, subscription revenue continues to report the previous product price as revenue. Once the new product price is received from the purchase SDK, the new price is recorded.
Gross revenue
  • IAP
  • Subscription revenue
Supported
Net revenue
  • IAP
  • Subscription revenue
Supported in raw data only
Tax

Subscription revenue

Supported
Net revenue store commission
  • IAP
  • Subscription revenue
  • For iOS, the 15% for subscribers older than 1 year: Supported in raw data only 
  • Small business programs: Not supported
Refunds IAP Can be reported until 180 days after the original purchase.
Deduplication
  • IAP
  • Subscription revenue
Supported for transactions reported up to 180 days after event date.
SDK strict mode
  • IAP
  • Subscription revenue

ROI360 subscriptions and IAP are supported under SDK strict mode from the:

  • AppsFlyer iOS purchase SDK connector V6.13.0
  • Unity purchase SDK connector V2.0.1
Currency
  • IAP
  • Subscription revenue
Revenue is reported in the original currency (using the event_revenue parameter) and in USD (using the event_revenue_usd parameter).
Data freshness
  • IAP
  • Subscription revenue
  • Transaction-level store revenue report: Hourly
  • Device-level store revenue report: Every 8 hours