If your app offers subscription-based features, you can record subscriptions and subscription renewals with AppsFlyer. By doing so the associated metrics revenue, conversion event, ROAS, ROI, and so on are updated. The overall consequence is that dashboards and reports reflect the complete value brought by a user over time.
Subscription event recording methods
Select a subscription recording method from those listed in the table that follows.
Topic | Server-to-Server | In-App Events |
---|---|---|
Event dependence on the app |
The event is sent from the server and is not dependent on app launch |
The event is sent by the app which means that the app must be launched |
Implementation |
|
|
Data accuracy |
|
|
Identifying subscribing users |
Requires you to cross-reference data in order to identify the actual user for whom a subscription was renewed |
|
Server-to-server subscription event
To implement server-to-server events, you need to design backend logic. The backend logic keeps track of subscriptions (new and renewed) and sends subscription events to AppsFlyer as necessary.
Sending server-to-server events to AppsFlyer for subscription notifications
AppsFlyer by default doesn't receive notifications of renewal or subscription events from the app stores. This section discusses how to set up a connection to the respective app store and pass subscription information to AppsFlyer as a server-to-server event.
Managing subscriptions on Android can be done on the App and Server levels. On the App level, communication is done through Google Play Billing Library. On the Server level while it is done through Google Play Developer API. The recommended way for managing subscriptions is through Google Play Developer API. This is the way that is discussed in this article.
Step 1: Set up the server endpoint to receive subscription-related notifications
Create a server endpoint that receives subscription-related notifications from Google Cloud. Then, enable real-time developer notifications:
- Determine a URL endpoint on your server to use for subscription status updates. For example, https://myserver/subscription-notifications.
- Set up Cloud Pub/Sub in your Google Cloud Platform (GCP) project.
- Enable real-time developer notifications for your Android app.
Step 2: Handle real-time subscription notifications
Once you set up a server endpoint to receive notifications, write the logic to handle these notifications. By default, Google sends notifications through Pub/Sub with subscriptionId
and purchaseToken
. The notification message doesn't contain any relevant information about the actual subscription. You need to take the purchase token and send a request to the Google Play Developer API to purchases.subscriptions.
The subscription notification contains the following:
{
"version": string,
"packageName": string,
"eventTimeMillis": 1578509686,
"subscriptionNotification": SubscriptionNotification,
"testNotification": AppsFlyerTest
}
In the subscription notification, there's an object called SubscriptionNotification
. It contains the following.
{
"version": 1.0,
"notificationType": 4,
"purchaseToken": 0f43308f-bf3f-4fa1-8aef-d515c941334b,
"subscriptionId": 123456789
}
purchaseToken
is the token that you send to Google Play Developer API to purchases.subscriptions get data about the subscription.
The subscriptionId
is the value you store into your database and associate it with the AppsFlyer ID.
Step 3: Associate subscription with Appsflyer ID and GAID in your database
Once you get the data about the subscription, you need to set up a link between the subscription ID and the AppsFlyer ID and GAID. The AppsFlyer ID is mandatory for sending server-to-server events to AppsFlyer. We strongly recommend to include the GAID when sending a server-to-server event. Including it allows AppsFlyer to send event postbacks to SRNs (self-reporting networks). It also opens for you the option to use AppsFlyer Audiences. You can get the AppsFlyer ID and GAID in one of the following ways:
The complete Android subscription attribution flow
See the following flowchart for the complete subscription attribution flow:
- Getting notified about a subscription status change.
- Associating a subscription with AppsFlyer ID and GAID.
- Sending a subscription-related event to AppsFlyer.
Apple calls its service Server-to-Server notifications. This service is designed specifically for auto-renewable subscriptions. The App Store sends notifications of real-time changes in a subscription's status. You can use these notifications and their data to send subscription-related events to AppsFlyer.
Step 1: Set up the server endpoint to receive subscription-related notifications
Set up a server endpoint that receives post requests. Configure the endpoint as follows:
- Support App Transport Security (ATS) on your server. The App Store must establish a secure network connection with your server by using ATS protocols before sending notifications. For more information, see preventing insecure network connections.
- Determine a URL endpoint on your server to use for subscription status updates. For example, https://myserver/subscription-notifications.
- Configure the subscription status URL for your app in App Store Connect. For guidance, see Enable status notifications for auto-renewable subscriptions.
Step 2: Connect the server endpoint to your app:
Once the endpoint is configured, input the server URL in the Subscription Status URL field in App Store Connect:
Step 3: Receive the notification and associate it with AppsFlyer IDs and IDFA in your database
Now you are ready to receive notifications from Apple about subscriptions. See the following sample notification:
{
"latest_receipt": "ewoXXXXX",
"latest_receipt_info": {
"original_purchase_date_pst": "2019-07-29 21:13:18 America/Los_Angeles",
"quantity": "1",
"unique_vendor_identifier": "XXX",
"original_purchase_date_ms": "1564459998000",
"expires_date_formatted": "2019-08-06 04:13:17 Etc/GMT",
"is_in_intro_offer_period": "false",
"purchase_date_ms": "1564459997000",
"expires_date_formatted_pst": "2019-08-05 21:13:17 America/Los_Angeles",
"is_trial_period": "true",
"item_id": "1452171111",
"unique_identifier": "00000",
"original_transaction_id": "0000000",
"expires_date": "00000000",
"app_item_id": "0000000",
"transaction_id": "00000000",
"bvrs": "00000",
"web_order_line_item_id": "00000000",
"version_external_identifier": "000000",
"bid": "com.XXX",
"product_id": "XXXXX",
"purchase_date": "2019-07-30 04:13:17 Etc/GMT",
"purchase_date_pst": "2019-07-29 21:13:17 America/Los_Angeles",
"original_purchase_date": "2019-07-30 04:13:18 Etc/GMT"
},
"environment": "PROD",
"auto_renew_status": "true",
"password": "*****",
"auto_renew_product_id": "com.XXXX",
"notification_type": "INITIAL_BUY"
}
Important!
The data from Apple's Status Update Notification doesn't contain the subscription price. You should implement backend logic to match the notification from Apple with the correct subscription price.
You use this data to send subscription-related events to AppsFlyer. To do so, you need to associate a subscription with an AppsFlyer ID and IDFA. We strongly recommend to include the IDFA when sending a server-to-server event. Including it allows AppsFlyer to send event postbacks to SRNs (self-reporting networks). It also opens for you the option to use AppsFlyer Audiences.
You can get the AppsFlyer ID and IDFA in one of the following ways:
The complete iOS subscription attribution flow
See the following flowchart for the complete subscription attribution flow:
- Getting notified about a subscription status change.
- Associating a subscription with AppsFlyer ID and IDFA.
- Sending a subscription-related event to AppsFlyer.
Sending the event to AppsFlyer
At this point, you have knowledge of a subscription status change (purchase, renewal, cancellation) and have associated it with an AppsFlyer ID. Now, make sure the following takes place:
- Your server gathers the necessary data for the event. Such data should include the following: revenue, subscription type, subscription ID (item_id in the data from Apple), AppsFlyer ID, time of renewal. Recommended mapping (see the code snippet below):
- af_revenue: revenue
- af_content_type: subscription type
- af_content_id: subscription ID (item_id in the data from Apple)
- renewal: true/false (based on subscription status change)
- eventTime: the time the notification reaches your server
- Based on the type of event (purchase, renewal, cancellation), the server sends the event to AppsFlyer as a subscription event with all related data.
Formatting and sending the event
Subscription event request example:
HTTP POST https://api2.appsflyer.com/inappevent/<APP_ID>
HTTP/1.1
headers:
{
authentication: '<YOUR_DEV_KEY>',
Host: 'api2.appsflyer.com',
Accept: 'application/json',
'Content-Type': 'application/json'
}
body:
{
"appsflyer_id":"<APPS_FLYER_ID>",
"customer_user_id":"123456",
"eventName":"af_subscribe",
"eventValue":"{\"af_revenue\":\"200\",\"af_content_id\":\"092\", \"af_content_type\": \"123\", \"renewal\":\"true\"}",
"eventCurrency":"USD",
"ip":"1.0.0.0",
"eventTime":"2018-07-09 4:17:00.000",
"af_events_api":"true"
}
To learn how to format and send the event to AppsFlyer, see sending server-to-server events.
In-app subscription event
Apps often need to check subscription status in order to enable subscription-specific features. You can use this mechanism in order to send subscription-related events to AppsFlyer. Once the app is aware of a subscription purchase or renewal, it can send the event.
Warning
If a user subscribes but doesn't launch the app for more than a month, the subscription is not counted as an event. For example, a user subscribes through your website but then doesn't open the app. If the user doesn't open the app for more than a month after subscribing, the subscription is not counted.
Checking subscription status in the app
The app can either communicate with your servers or receive push notifications with data about subscriptions.
You can configure your app to check the status of the subscription. There are two ways you can achieve this:
- The app checks the subscription status and related data (active or not active, subscription type, expiration date etc.)
- The app receives a push notification about a subscription purchase or renewal.
Tip
For Android applications: you can use Android's real-time developer notifications to notify the app about renewals in real-time.
For iOS applications: the Store kit provides you with payment queue and transaction observers. You can use these to verify a subscription purchase or renewal. Refer to Apple's documentation on finalizing transactions for more information.
Note
Receipt validation is not supported for recording subscriptions in iOS applications.
Sending a subscription-related in-app event
Once the app has the relevant subscription-related data, the following steps should take place:
- The app checks to see if the subscription is a purchase or renewal.
- The app gathers the relevant data (revenue, content_id, purchase or renewal, etc.).
- The app sends the subscription event to AppsFlyer using the SDK.
Subscription event example
Parameter Name | Type | Example of Value | Description |
---|---|---|---|
af_revenue | float | 200 | The revenue associated with the subscription |
af_currency | string | USD, GBP | The currency of the payment |
af_content_id | string | 092, monthly_subscription | The name or code of the subscription |
renewal | boolean | true, false | whether the subscription is new or renewed |
Event code samples
The code snippet below demonstrates how to configure and send the event using the SDK.
Map<String, Object> eventValue = new HashMap<String, Object>();
eventValue.put(AFInAppEventParameterName.REVENUE, 200);
eventValue.put(AFInAppEventParameterName.CURRENCY, "USD");
eventValue.put(AFInAppEventParameterName.CONTENT_ID, "092");
eventValue.put("renewal", true);
AppsFlyerLib.getInstance().trackEvent(getApplicationContext(), AFInAppEventType.SUBSCRIBE, eventValue);
[[AppsFlyerTracker sharedTracker] trackEvent:(AFEventSubscribe) withValues: @{
AFEventParamRevenue: @200,
AFEventParamCurrency: @"USD",
AFEventParamContentId: @"092",
@"renewal": @TRUE
}];
AppsFlyerTracker.shared().trackEvent(AFEventSubscribe, withValues: [
AFEventParamRevenue: 200,
AFEventParamCurrency: "USD",
AFEventParamContentId: "092",
"renewal": true
]);
Dictionary<string, string> SubscriptionEvent = new Dictionary<string, string>();
SubscriptionEvent.Add("af_revenue", "200");
SubscriptionEvent.Add("af_currency", "USD");
SubscriptionEvent.Add("af_content_id", "092");
SubscriptionEvent.Add("renewal", "true");
AppsFlyer.trackRichEvent ("af_subscribe", SubscriptionEvent);
Note
It is highly recommended that you associate subscriptions with customers. To do so, make sure to set the customer user ID. Setting the customer user ID is your way to match your customers with users of your app as they appear in AppsFlyer. By setting the customer user ID you make sure that any event, subscription-related events included, is sent with the customer user ID.