[Closed beta] Subscription revenue

beta_feature.png

At a glance: Automatically measure revenue from auto-renewable subscriptions to get the full picture of your subscriber life cycles and accurate ROAS measurements.

Subscription revenue overview

Auto-renewable subscriptions are events that keep recurring in your app. The subscriptions automatically renew at the end of their duration, until the users choose to upgrade, downgrade or cancel. Each upgrade, downgrade, or cancellation means changes to incoming revenue.

The AppsFlyer Subscription revenue solution automatically validates and records subscription-related events that happen inside or outside your app and attributes them. The subscription-related events come from:

  • The AppsFlyer Subscription revenue SDK connector for Android and iOS.
  • App Store and Google Play (RTDN) server notifications sent to AppsFlyer.

Subscription revenue data is available via AppsFlyer dashboards and reports.

Considerations

  • If you use the subscription revenue measurement solution, you shouldn't use in-app purchases (IAP) to log subscriptions. 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 Subscription revenue SDK purchase connector.

AppsFlyer Subscription revenue solution setup

Scope of work
Who's involved Tasks
Marketer
  • Configure Subscription revenue setup for Android.
  • Configure Subscription revenue setup for iOS.
Android developer

Integrates the AppsFlyer Android Subscription revenue SDK connector.

Recommended: To identify your subscriber base faster, have server notifications set up, before releasing your app version with the Subscription revenue SDK connector.

iOS developer

Integrates the AppsFlyer iOS Subscription revenue SDK connector.

Recommended: To identify your subscriber base faster, have server notifications set up, before releasing your app version with the Subscription revenue SDK connector.

Configure Subscription revenue for Android

Before you start:

  • Setting up Subscription revenue consists of steps performed in App Store Connect, Google Cloud Platform, and in the AppsFlyer UI. Keep tabs to App Store Connect, Google Cloud Platform and AppsFlyer open through the setup. 
  • Setup in the AppsFlyer UI requires admin permissions.

admin.png To configure Subscription revenue:

  1. In Google Cloud Platform, go to Service Accounts, and click Create service account.
  2. Enter a service account name.
  3. Click Create and continue.
  4. For Role, select Pub/sub subscriber.
  5. Click Continue > Done.
  6. In Google Cloud Platform, go to Service Accounts, find the relevant service account, and click Actions > Manage keys.
  7. Click ADD KEY > Create new key.
  8. For Key type, select JSON.
  9. Click Create.
    The Google service account private key JSON is downloaded.
  10. In Google Play Console, go to Setup > API access.
  11. In the Service accounts list, find the relevant service account, and click Grant permissions.
  12. In the Permissions section, go to Account permissions, and select both:
  13. Click Invite user > Send invite.
  14. In AppsFlyer, go to Integration > Subscription Attribution.
    The Revenue configuration page opens.
  15. In the Purchases and Subscriptions section, upload your Google service account private key JSON.
  16. Select the method used to receive Subscription revenue data from Google. Either:
    • Allow AppsFlyer to get RTDN messages directly from Google.
      1. Copy the AppsFlyer topic.
      2. In Google Play Console, select your app.
        The dashboard opens.
      3. Go to Monetization setup, and in the Google Play Billing section, in the Topic name field, paste the AppsFlyer topic that you recorded in substep 1.
      4. Click Save.
    • Forward your RTDN messages to AppsFlyer.
      1. Copy the AppsFlyer topic.
      2. In Google Cloud Platform, under Pub/Sub, go to the Topics section, and verify you have a dedicated pub/sub topic for subscriptions.
      3. In Google Cloud Platform, under Pub/Sub, go to the Subscriptions section, and click Create subscription.
      4. Enter a Subscription ID (name).
      5. Select the relevant subscription pub/sub topic from the dropdown.
      6. For Delivery type, select Push.
      7. Enter the endpoint URL (AppsFlyer topic) that you recorded in substep 1.
      8. For Expiration period, select Never expire.
      9. Leave everything else as is.
      10. Click Save.
      11. In Google Cloud Platform, under Pub/Sub, go to the Subscriptions section, and copy the topic name.
      12. 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 substep 11.
      13. Click Save.
  17. In the AppsFlyer Revenue configuration page, turn on Attribute and report auto-renewable subscriptions.
  18. Click Save.
  19. Tell your Android developer to integrate the AppsFlyer Android Subscription revenue SDK connector.

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.

Configure Subscription revenue for iOS

Before you start:

  • Setting up 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.

admin.pngTo configure Subscription revenue:

  1. In AppsFlyer, go to Integration > Subscription Attribution.
    The Revenue configuration page opens.
  2. Enter your App Store Connect shared secret key.
  3. Copy the AppsFlyer endpoint and enter it in your App Store Connect configuration.
  4. [Optional] Select to send server notifications to your endpoint and enter your endpoint. 
  5. Turn on Attribute and report auto-renewable subscriptions.
  6. Click Save.
  7. Log into App Store Connect and select your app.
  8. In the App Information section, scroll down to App Store Server notifications, and in the Production Server URL field, paste the AppsFlyer endpoint you copied in step 3. 
  9. Click Save.
  10. Tell your iOS developer to integrate the AppsFlyer iOS Subscription revenue SDK connector.

Note:

  • Apple can only send server notifications to one endpoint. If you want AppsFlyer to forward all incoming notifications to your endpoint, contact your CSM and give them your endpoint URL. (The URL must be a valid HTTP or HTTPS endpoint. Preferably HTTPS.)
  • 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.

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.

Note: All parameters apply to Android and iOS unless otherwise stated

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 cancelled (af_ars_trial_cancelled)

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 cancellation 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_churn_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
  • af_revenue_usd
  • af_revenue
  • store_commission
  • net_revenue
  • net_revenue_factors

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
  • af_revenue_usd
  • af_revenue
  • store_commission
  • net_revenue
  • net_revenue_factors

Subscription cancelled (af_ars_subscription_cancelled)

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
  • af_revenue
  • store_commission
  • net_revenue
  • net_revenue_factors

Subscription churned (af_ars_subscription_churned)

Description

Recorded when a subscriber churns. This usually happens after auto-renewal cancellation 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_churn_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_cancellation_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
  • af_revenue_usd
  • af_revenue
  • af_product_id
  • android_id
  • idfa
  • ip
  • appsflyer_id
  • af_store
  • af_environment
  • af_period_type
  • store_commission
  • net_revenue
  • net_revenue_factors
  • net_revenue_usd

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
  • af_revenue_usd
  • af_revenue
  • store_commission
  • net_revenue
  • 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
  • af_revenue_usd
  • af_revenue
  • store_commission
  • net_revenue
  • net_revenue_factors

Event parameter dictionary

Parameter Remarks
app_id

The app ID

customer_user_id

The latest customer user ID as reported by the advertiser.

af_cancellation_reason
  • The reason why the user received a refund:
    • 1: issue with your app
    • 0: other reason
  • iOS only
af_churn_reason

The reason a user churned. Potential values:

  • iOS
    • cancel_intent
    • billing_issue
    • cost_related
    • product_unavailable
    • unknown_reason
  • Android
    • I don't use this service enough
    • Technical issues
    • Cost-related reasons
    • I found a better app
    • Other
country_code

The country code

af_currency

The local currency of the transaction

af_expires_date_ms

The expiration date of the current subscription billing cycle

af_subscription_ownership_type

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

af_discount_id

The offer ID presented to the user during the initial purchase

af_original_transaction_id
  • The original transaction ID
  • iOS only
af_order_id
  • The order ID for the transaction
  • Android only
af_purchase_token
  • The purchase token for the transaction
  • Android only
af_transaction_id
  • The ID of the transaction
  • iOS only
af_refunded_transaction_ids An array of all refunded transaction IDs
iOS only
af_revenue_usd

The gross revenue reported in USD - based on the latest known product price

af_revenue

The gross revenue reported in the local currency based on the latest known product price

af_product_id

The subscription product ID

advertiser_id

The advertiser ID

idfa

iOS device identifier

ip

IP address

appsflyer_id

AppsFlyer user ID

purchase_date_ms

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

af_store

The app store the subscription product was purchased from

af_environment

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

af_period_type

Subscription period type. For example: trial, intro, or normal.

store_commission
  • The calculated percentage of commission the store gets from the purchased product.
  • Displayed as a decimal.
net_revenue

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

net_revenue_factors
  • An array representing all factored reasons that produce the reported net_revenue amount.
  • Example value: store_commission
af_cuids
  • In the context of Subscription revenue, 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.
Parameters

Additional information

Testing Subscription revenue via sandbox

Customers can validate their Subscription revenue integration in a sandbox environment and ensure that:

  • The Subscription revenue SDK connector is properly integrated.
  • The Subscription revenue server notifications are properly configured.

Considerations:

In a sandbox environment:

  • Only initial purchase events cause the Subscription revenue SDK connector to produce an event. The event is called af_ars_sandbox_sdk, and includes:
    • A revenue value of 0.
    • A af_sandbox_revenue parameter that includes the revenue value of the product purchased.
  • All other purchase events are dropped, meaning the Subscription revenue SDK connector doesn’t produce an event.
  • Incoming server notifications are only processed if the Subscription revenue SDK connector first records the original transaction. In this case, an event is produced called af_ars_sandbox_s2s.
  • An event isn’t produced for any server notification for which the Subscription revenue SDK connector didn’t first record the original transaction.

Traits and limitations

Traits and limitations
Trait Remarks
Google billing libraries V5 Not supported
Apple notifications V2 Not supported
Gross revenue Supported
Net revenue Not supported
Store commission Not supported
Tax Not supported
New subscriptions Only recorded via the AppsFlyer SDK
Price change 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 Subscription revenue SDK, the new price is recorded.
Was this article helpful?