In-app purchases and cross entitlement
Table of Contents
In-App Purchases are a wonderful, wonderful thing, and have in a few short years created a multi-billion dollar industry of their own. They’re convenient, they’re fast and, most of all, they stop you from having to type out your card details every time you want to buy something.
That all said, we know that there are a number of situations in which In-App Purchases (IAPs) just don’t really make sense. Perhaps access to content is bundled as part of a bigger membership package, or perhaps you don’t fancy Apple, Google and Amazon taking their 30% commission from your sales.
ANOTHER WAY TO PAY?
So, what are your alternatives if you don’t want to run your content purchasing through IAPs? On iOS, Apple makes your options pretty clear: there are none. Here’s the official wording:
“If you want to unlock features or functionality within your app, (by way of example: subscriptions, in-game currencies, game levels, access to premium content, or unlocking a full version), you must use in-app purchase. Apps may not use their own mechanisms to unlock content or functionality, such as license keys, augmented reality markers, QR codes, etc. Apps and their metadata may not include buttons, external links, or other calls to action that direct customers to purchasing mechanisms other than in-app purchase.”
Trying to circumvent this is a very fast way to get your app rejected. Spotify are a notable example of how closely developers have to hew to these guidelines. Tapping the “Premium” button on iOS will take you to a lovely screen detailing the benefits of premium alongside the line “Spotify Premium can’t be purchased in this app”. No URL, no hint of where one might be able to subscribe, no nothing.
Perhaps, though, you’re looking for a deeper relationship with your customers, and your real goal is to bring them fully into your ecosystem without sacrificing the ease of IAPs.
Cross Entitlement / Receipt Postback from the App Stores
When a user purchases an In App Purchase from the various App Stores (iTunes or Google Play), they can only use this in that store. The idea of Cross Entitlement is to allow users to take advantage of these purchases on other platforms.
Pugpig supports this feature on both iTunes and Google Play. We do not support it on the Amazon App Store. Note also that you cannot grant access on Google Play to an iOS Suscriber, or the other way around. You can only grant access to your third party authentication system.
Note: Apple call this feature "Web Access". Others call it "Receipt Postback" as the implementation involves posting a store receipt to the server.
This is supported out of the box by some of the authentication providers we use, including:
- Piano (using their External Terms) https://docs.piano.io/external-service-term/
The Flow In The App
The most common flow is when a user who is not logged in makes an In App Purchases. In the vast majority of cases, a user that is already logged in or subscribed will not need to purchase via the App Stores. If this is your use case, get in touch with support and we can help you find the best option.
- User makes an IAP purchase
- Popup appears prompting user to make an account
- User registers or signs in via your auth provider
- Cross Entitlement Happens behind the scenes
Now that the user exists in your database, you need to know a little more about them. Specifically, you need to know what kind of subscription they’ve purchased and whether it’s still valid or not. We can provide you with the information needed to securely validate the user’s subscription with the app store. This will enable you to check what kind of subscription the user has purchased, whether it’s still active and when it’s due to expire.
Your subscription system can then validate the receipt again when necessary. This is in tandem with the validation we already perform to ensure a user has the correct access.
Setting up receipt postback isn't quite plug-and-play, it requires a little custom work to hook up to your desired system and theme correctly, and it will require an app release to enable the feature for new and existing users.
Implementing Cross Entitlement on your own Backend
If you wish to add this feature to your existing system, you need to do the following:
- Ensure you already provide a way for users to register/create an account if you want new users to be able to cross entitle (a PKCE/web auth with a registration option here as it’s the most convenient for users)
- Provide an endpoint where Pugpig can POST an App Store receipt and a user token
- Check the user token is valid
- If yes, decode the receipt using the store API endpoints, validate they contain the correct information, and assign the user the correct entitlements in your system
- Subscribe to the Store notifications which will notify you of changes to the subscriptions (auto-renew/cancellations/etc)
And example POST from the app to your back end would look something like this, but we can modify this to suit your needs if required:
curl -X POST \
'https://api.acme.com/api/user/iap-receipts' \
--header 'Accept: application/json' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'receipt=(receipt_body)' \
--data-urlencode 'store=(googleplay|itunes)' \
--data-urlencode 'token=(user_access_token)
Please be aware that a receipt can have multiple subscriptions/multiple single-issue purchases.
Validating Receipts
You can refer to Apple's documentation on receipt validation here. Google Play has documentation for checking the purchase and consumption status of an in-app item (i.e. single issue purchase) and documentation for checking whether a user's subscription purchase is valid and returns its expiry time here.
iTunes Receipt Versions
Currently we only support V1 Apple receipts, we will aspire to support V2 receipts when dropping iOS14. For backwards compatibility we hope that Apple will continue to support V1 receipts indefinitely. As of August 2023, Apple's documentation say that the receipt validation endpoint is deprecated, but you will still need to use this endpoint until further notice.
Store Notifications
Both Apple and Google Play provide APIs to allow you to keep your user entitlement database in sync in near real time.
As users can cancel at any time, and renew automatically, you need to subscribe to the stores to be notified of changes. The apps cannot do this for you. If you do not implement this step, a user can cancel and continue to have access to your content.
The app stores will send you a payload when a user's subscription status changes. The payload includes a unique identifier which will allow you to find and update the user in your database.
Apple: App Store Server Notifications is a server-to-server service that notifies you in real time when the status of in-app purchases and refunds changes. Details here: https://developer.apple.com/documentation/appstoreservernotifications
Google Play: Google provide their Real-time Developer Notifications service to achieve this:https://developer.android.com/google/play/billing/rtdn-reference
Most of the big players in subscription management implement these APIs - if you need examples just search for "App Store Server Notifications " or "Real-time Developer Notification"
If you've got any questions about subscriptions, receipts, or anything else for that matter, don't hesitate to get in touch at support@pugpig.com