What’s new with in-app purchases based on WWDC 2020: Refunds, server notifications, SKAdNetwork in iOS 14.
If a user has an issue with an app’s content, he can contact Apple and ask for a refund. Refunds affect only a small percent of the transactions, and you can drive this percentage down with proper refund management.
Typical refund scenario:
1) customer purchases content in an app.
2) The purchase was an accident, so the user contacts Apple
3) Apple reviews the case and issues a refund
4) The user can also contact you cause he believes he has not been refunded. You might not know if Apple has made a refund, and hence you do not know how to respond.
It would be helpful to know if Apple refunded so you can respond appropriately: acknowledge the refund, provide or close access to your premium features.
Apple introduced a new server notification – refund notification to make this process more transparent.
You are notified immediately with JSON post upon a status change. Apple would retry three times if it did not get HTTP ok response from your server. For consumables, non-renewing subscriptions, non-consumables, you’ll receive a refund notification. For auto-renewable subscriptions, you receive a cancel notification.
Setting up App Store server notifications
- Set up URL in App Store Connect (Navigate to your apps page -> enter your endpoint into the “URL for App Store Notifications” section).
- Make sure your endpoint meets app transport security requirements outlined in Apple developer documentation
- Receive notifications
Refund notification payload for consumable, non-consumable, and non-renewing subscriptions contains:
original_transactoin_id: what transaction was refunded
cancelation_date_ms: when it was refunded
cancelation_reason: 0 or 1, 1 means the customer requested the refund due to an issue within the app
bid: Bundle identifier, to know which app you received a refund for
product_id– Product that was canceled
password– shared secret for the app. You should use it to verify it’s from Apple.
If you received a refund notification, you could show the in-app message to your user providing the details:
Building your own server might be time-consuming and it’s probably not what you want to focus on when building an app with in-app purchases. You’ll probably be better of focusing on your product.
The good news is that you can use third-party services like Qonversion.io to handle your receipts with out-of-the-box support for Apple server-to-server notifications. After integrating Qonversion SDK, all you need is to pass Qonversion endpoint link for your app to App Store. Qonversion will handle the rest. You can get the details here.
Key events in the subscription life cycle:
- Subscribe (acquire subscriber for the first time)
- Auto-renew (successful or unsuccessful)
- Disable / Enable auto-renew
- Upgrade / Downgrade
Server notification is the recommended method to get data about your subscription status changes. You receive the data only when you need it.
Key payload components:
- auto_renew_product_id – what subscription is this notification for
- notification_type – type of the event you are receiving (see below for more details)
- password – shared secret for the app
- bid – Bundle identifier
- unified_receipt – object that mimics the response of verifyReceipt
- “INITIAL_BUY” – initial purchase of the subscription
- “INTERACTIVE_RENEWAL” – customer renewed using your app’s interface or Manage Subscriptions
- “DID_CHANGE_RENEWAL_STATUS” – change in the subscription renew status, e.g. toggling auto-renew on or off.
- “DID_CHANGE_RENEWAL_PREF” – customer made a change that takes place at the end of the subscription period such as a downgrade.
- “CANCEL” – customer contacted Apple support and was refunded.
- “DID_FAIL_TO_RENEW” – subscription failed to renew due to billing issue.
- “DID_RECOVER” – subscription was successfully renewed from billing retry or grace period.
- “DID_RENEW” – new notification Apple adding later in 2020 to notify about renewal.
DID_RENEW is being sent after each successful auto-renew. Since renewals are critical events, you should ensure successful updates with a double-check:
- enable App Store server notifications to receive DID_RENEW
- Schedule one call to verify receipt at the expiration date
SKAdNetwork allows measuring the effectiveness of adds while respecting customer privacy. Since Apple is moving to opt-in IDFA in iOS 14, the advertisers and ad networks will have to embrace SKAdNetwork.
SKAdNetwork involves three stakeholders: Ad Networks, Source Apps, Advertising Apps.
Ad network places the SKAdNetwork data inside the ad for the advertising app; then it displays the source app.
Ad network sends the following data when displaying the ad:
- Ad Network ID (registered with Apple)
- Campaign ID from 1 to 100 (for ad networks to measure their campaign effectiveness)
- Advertising App ID (the app that is advertised)
- Timestamp (generated at the time when an ad displayed)
- Nonce (unique random ad id to avoid double counting)
- Signature (generated all the other pieces of data)
- Version (“2.0”)
- Source App ID (ID of the app that is displaying the ad)
Post back API should be called by the advertising app (app B) upon the first launch of the app. registerAppForAdNetworkAttribution and updateConversionValue – some action in your app like free trial start or in-app purchase.
The details of the postback that StoreKit sends to ad network once the process is complete:
- Ad Network ID
- Campaign ID (1-100)
- Advertising App ID
- Transaction ID
- Version (“2.0”)
- Redownload (to show if it’s the first time consumer purchased the app or they previously purchased it and install it again)
- Source App ID (optional)
- Conversion Value (optional)
Advertising apps prepare the postback when the app first launches, using either the registerAppForAdNetworkAttribution API or updateConversionValue API.
It is hard to forecast how moving from IDFA to SKAdNetwork for mobile attribution will affect marketing ROAS for mobile apps. But one thing you can do to have accurate subscription data including renewals, refunds, trial-to-paid conversion in your attribution and product analytics platforms is to use Qonversion. You can check all available integrations here.