Apple In-App Purchase - SK2 [Beta]
This tutorial will help you integrate Apple in-app purchases using the StoreKit 2 framework.
Beta
Please note that it is a Beta feature.
This tutorial will help you integrate Apple in-app purchases using the StoreKit 2 framework for devices that support universal purchases, including iPhones, iPads, Apple TV devices and Vision Pro.
👉 Please refer to Apple documentation for information about which Apple platforms and versions are supported for StoreKit 2.
Overview
Payments on mobile and TV apps (in-app purchases) enrich your portfolio with one more payment method for your services. Customers can easily buy access to video content directly from inside your native applications, which simplifies the process. It also provides added value to you.
When you enable in-app purchases with Cleeng you gain:
- entitlement across devices for your customers - they can use your services on many devices
- rich and consolidated reporting for you - all-in-one-place reporting that can support your subscriber retention analytics and strategy building.
It is important to note that legally and technically it is Apple who handles the actual payments for purchases made in apps. Cleeng acts as an observer and tracks in-app purchase lifecycle events to gather data to make it available for analysis and to control access rights (entitlements).
In short, in-app purchases integration requires the setup on your side, and when ready, calling Cleeng purchase validation endpoint to submit the initial purchase when it happens in the app.
Cleeng takes over from there. We validate the purchase in the store, create a subscription and keep it in sync by listening to server-to-server notifications for subscription status updates. And we take care of the reporting.
This tutorial will show what you need to take care of as a broadcaster to enable Apple in-app purchases with Cleeng, as well as what the user-flow will look like.
If you want to jump straight into details, go to the What you have to do section.
What is Apple StoreKit
As mentioned at the start of this tutorial, it will help you integrate Apple in-app purchases using the StoreKit 2 framework. (The legacy integration based on StoreKit 1 is described here.)
So before we move to integration steps, a few words about StoreKit.
To handle in-App Payments, Apple provides the StoreKit framework. The StoreKit framework connects to the App Store on the app’s behalf to prompt for and securely process payments. The framework then notifies the app, which delivers the purchased products.
StoreKit 2 is an updated framework that developers use to handle in-app purchases, subscriptions, and transactions within apps on Apple’s platforms. It provides tools and APIs to create a seamless buying experience for customers while offering developers more flexibility and efficiency when integrating and managing in-app purchases within their applications.
StoreKit 1 and Storekit 2 differ in some aspects, and one of them is purchase validation. As you can see below, purchase validation was based on receipts with Storekit 1, while now, with StoreKit 2, it is based on Original Transaction ID.
Purchase validation is based on: | |
---|---|
Apple StoreKit 1 | Encrypted receipts They contain information about what is bought and when, though do not include revenue numbers (actual price paid by the customer). Also the App Store has server-to-server notifications to share information about the subscriber lifecycle and billing information. |
Apple StoreKit 2 | Original Transaction ID It is the main object used for validating the purchase, using Server APIs and server-to-server notifications. |
Now, follow the steps below to integrate in-app purchases using the StoreKit 2 framework.
What you have to do
As a broadcaster you need to be aware and take care of the following:
- Architecture Overview
- Authorization
- Prerequisites
- Initial Purchase Submission
- Receive Subscriber Status Validation
- Keep Subscribers Synchronized
Important
If you want to switch from StoreKit 1 and integrate in-app purchases using StoreKit 2 framework, and you are currently using our StoreKit 1 integration endpoint, it is recommended to use our seamless integration.
Otherwise, switching to StoreKit 2 framework will cause your existing StoreKit 1-based implementation to stop working.
1. Architecture Overview
Below you can see the overview of the system architecture. It shows the interaction between your app, Apple AppStore, and Cleeng.
2. Authorization
Depending on how you integrate with Cleeng, you will use different authorization: either a publisher (X-Publisher-Token) or JWT (Bearer) token. A publisher token will be used for integrations through middleware, while JWT - for direct integrations.
Please note that some integration steps will differ for these two flows.
Also, the purchase validation endpoint that is used in Apple in-app purchase integration accepts either a publisher (X-Publisher-Token) or JWT (Bearer) token for authorization. Please make sure to use the one that matches your current integration.
Please also note that this tutorial focuses on integration where JSON Web Token (JWT) authorization is used so we recommend using MediaStore API (for more information see Getting started), especially for authentication (registration and login).
3. Prerequisites
You need to complete 6 steps in the prerequisites stage:
- Set up a developer account with Apple and create an application
- Add products within Apple Store Connect
- Create Keys in Apple
- Configure Server-to-Server notifications
- Provide configuration in the Cleeng Dashboard
- Contact Cleeng Broadcaster Success Specialists team
Please follow the sections below for details:
-
Set up a developer account with Apple (see more in Apple documentation) and create an application.
-
Add products within Apple Store Connect - see Apple documentation.
Products that you add must be compatible with your Cleeng offer.
Important notes for setting up products compatible with Cleeng:
- This Apple in-app purchase integration works only for subscription offers. Hence, use auto-renewable-subscription products for subscriptions.
- The product price must be set manually in App Store Connect. Be sure to align prices between Apple's product and your Cleeng offer.
- You can only select price points in App Store Connect.
- To test the setup, log in to your sandbox account on your phone (Settings -> App Store -> Sandbox account), with one of the sandbox accounts created in App Store Connect -> Users and Access -> Sandbox -> Test Accounts.
👉 Remember to add your App store product ID in the offer setup in the Cleeng dashboard in order to map the external offer properly in the Cleeng system. For more information, see this article.
-
Create Keys in Apple.
Authorization
Please note that JSON Web Token (JWT) authorization is used for API requests.
Create API Key
First, you need to create an API key. Any role is sufficient, but we recommend that the access role is set to “Developer” in Apple Connect -> User and Access -> Integrations.
Download your private key after generating it. Please note that it can be downloaded only once.
Important: Store your private key in a secure place as it is used to authorize API requests.
Data Access Key
To strengthen reporting we recommend using Data Access Key with the access role set to “Admin” in Apple Connect -> User and Access. -
Configure Server-to-Server notifications
You need to provide a URL address in App Store Connect for server-to-server notifications - see Apple documentation.
The URL you need to provide is:https://inapp.api.sandbox.cleeng.com/storekit2/notifications/broadcasters/{broadcasterId}
- for sandbox environment.- For production environment, it will be
https://inapp.api.prod.cleeng.com/storekit2/notifications/broadcasters/{broadcasterId}
👉 Please remember to replace {broadcasterId} with your broadcaster ID (publisher ID) in the URL.
For more information on Server-to-Server notifications, see the section below.Note
When using StoreKit 2 make sure you’re using version 2 notifications. For more information, see Apple documentation - App Store Server Notifications V2.
-
Provide configuration information in the Cleeng Dashboard
Once you are ready and have the required information from Apple at hand, log in to Cleeng Dashboard, go to Admin Settings > Integration Hub > Apple Store.
The section consists of mandatory and optional configuration as specified below.
Mandatory configuration
You need to fill in configuration information in the Cleeng Dashboard so as to automatically synchronize subscribers between Apple and Cleeng. This way your subscribers get access on any device, and you benefit from consolidated reporting.
Note
Please enter your private key in PEM format. PEM format typically starts with '-----BEGIN PRIVATE KEY-----' and ends with '-----END PRIVATE KEY-----'. Ensure there are no additional spaces or characters before or after the key data.
Configure the required fields: bundle id, issuer id, key id, and private key:
-
bundle Id - value taken from the App Store Connect under Apps -> App information -> Bundle ID
-
issuer Id - value taken from the the App Store Connect under Users & Accesses -> Integrations -> Issuer ID
-
key id (kid) - value taken from table of generated private keys at the App Store Connect under Users & Accesses -> Integrations -> Key ID
-
private key - value taken from the file, which can be downloaded only once, right after the private key generation.
Optional configuration
Configuring data reporting is optional, but recommended in order to have more insights.To configure data reporting you need to provide the Key ID and Private Key in the respective fields using the Data Access Key (with the access role set to “Admin” in Apple Connect under User and Access).
-
-
Contact Cleeng Broadcaster Success Specialists team to complete configuration on Cleeng’s side (add a payment method).
Important
Make sure that payment method is added and configuration is completed in the Cleeng Dashboard - these are mandatory for the setup to work.
4. Initial Purchase Submission
In-app purchases integration requires calling Cleeng purchase validation endpoint to submit the initial purchase when it happens in the app.
When a customer successfully buys a subscription offer, a request should be sent to the purchase validation endpoint:
POST https://inapp.api.sandbox.cleeng.com/storekit2/purchase-validation
(or POST https://inapp.api.prod.cleeng.com/storekit2/purchase-validation
- once in production environment)
Note:
The value of the
originalTransactionId
in the purchase validation payload should be taken from Apple StoreKit 2transactionId
.
Note
Cleeng has mechanisms for retrieving subscriptions that have not been properly verified.
In rare cases it might happen that information about a subscription arrives first via server-to-server notification from Apple and only after that from a broadcaster. It is then important for a broadcaster to send the request to Cleeng through the purchase validation API.
5. Receive Subscriber Status Validation
Once you make a call to Cleeng’s purchase validation endpoint, Cleeng takes over from there.
We validate the purchase in the app, and act on the validation result (e.g. create a subscription).
Subscriber Status Validation
Original transaction identifier is the main object used for validating a purchase, i.e validating a subscriber status, so access to content is based on an originalTransactionId
.
Cleeng validates it before access is granted, but it is an asynchronous process. Because it requires validation with an external app store, we are not able to return the outcome synchronously in the API request response. So the first “OK” message that you receive shows only that the request has been successfully queued.
See below for the overview of the process of subscriber status validation for two integration methods:
Direct Integrations (Without Middleware)
For direct integrations where no middleware is used (the request is submitted directly to Cleeng platform from the client app and authenticated with an end user JWT token), the polling approach should be used.
Even though most responses are within 3 seconds, they can take up to 60 seconds on the app store side. Therefore, the application needs to poll the Cleeng API using the Get entitlements
endpoint: GET mediastoreapi.cleeng.com/entitlements/{offreId} every five seconds until validation is completed and access is granted.
Integration With Middleware (Client Backend)
For backend integrations where middleware is used and the request is authenticated with a publisher token, your client backend service should subscribe to Cleeng webhook topics.
If you are subscribed to the topics listed below, you will receive a webhook notification when in-app purchase validation (subscriber status validation) is completed with information about the outcome of the validation result.
Webhooks dedicated for in-app purchase validation:
In addition generic subscription lifecycle topics will also be emitted:
For details of possible outcomes of in-app purchase validation and webhooks sent, please refer to In-app Purchase Validation article.
6. Keep Subscribers Synchronized
Cleeng acts as an observer and tracks in-app purchase lifecycle events. But for Cleeng to be able to do this, you need to configure server-to-server notifications to get the subscription status updates and keep subscribers synchronized.
You need to provide a URL address in App Store Connect for server-to-server notifications - as described in the Prerequisites section.
Server-to-Server Notifications
Server-to-Server Notifications is direct one-way communication between Apple App Store and Cleeng. It provides near real-time subscription updates that help to get information about new purchases, renewals, billing issues, etc. This helps to build more accurate analytics, as well as simplifies managing the subscriber’s status.
The table below presents which Apple notifications (version 2) are supported:
Apple Notification | Supported at Cleeng |
---|---|
DID_FAIL_TO_RENEW | ✓ |
EXPIRED | ✓ |
GRACE_PERIOD_EXPIRED | ✓ |
SUBSCRIBED | ✓ |
RENEWAL_EXTENSION | ✓ |
DID_CHANGE_RENEWAL_PREF | ✓ |
DID_CHANGE_RENEWAL_STATUS | ✓ |
REFUND | ✓ |
User Flow
1. Register/Login User
Note: We recommend using MediaStore API (for more information see Getting started), especially for authentication (registration and login).
The application attempts to log in the user. If the user doesn't exist, registration is required. It is recommended that the application uses the Register method to register the customer. For more information, see Registration.
If the user exists, it is recommended that the application uses the Login endpoint to log in. For more information see Login.
2. Purchase an Offer
Once a customer successfully purchases an offer, they get access to the content.
It results in subscription creation - if we do not have a subscription with this originalTransactionId
yet.
It is also possible that restore happens and then it can result in subscription transfer or restoring purchase
- subscription transfer - if we already have an active subscription for the provided
originalTransactionId
and it belongs to a customer with a different email address. Then a new subscription is created for the "new customer" (the one using the new e-mail address) and the subscription assigned to the "old customer" (the one using the old email address) is terminated. Please note that this process has implications in reporting (one subscription is terminated and another one created). - restoring purchase - in some cases your customers who purchased a subscription need to restore their purchase on another device. For example, if a customer has a purchase associated with his appleId but he/she uses a new apple device to log in to the app, it may be required to restore the purchase. In this case the transactionId should be submitted again to Cleeng to validate the purchase and make sure the subscription is created correctly, associated with the corresponding Cleeng account and synced with the app store.
3. Manage Subscription
For subscriptions purchased via in-apps, Cleeng does not handle payments. This also means that subscription lifecycle events like termination, or subscription upgrade/downgrade are managed by external services. Cleeng acts as an observer and tracks in-app purchase lifecycle events to synchronize the status.
So for example, if you are using Cleeng MediaStore SDK Components in your webApp, a subscription purchased via in-apps cannot be managed in MyAccount and your customers will be informed that they need to go to the external store to manage their subscription there.
If you are not using our Components solution, it is recommended that you provide respective information in your specific My Account implementation.
Testing Guidance
When you integrate the above, please follow these steps to test the initial payment configuration:
- Configure in-App purchase in App Store Connect - see Apple Documentation.
- Create a Cleeng sandbox account (or log in if you already have one) and create a test offer.
- Make sure App Store Connect and Cleeng offer in the sandbox environment are compatible - for more information see "Important notes for setting up products compatible with Cleeng" above.
- Provide bundle id, issuer id, key id, and private key in the Cleeng Dashboard.
- Contact Cleeng Broadcaster Success Specialists team to complete configuration on Cleeng’s side (add a payment method).
- Make an initial purchase.
- Subscription is added in Apple settings.
- Subscription is added in Cleeng.
Test Cases
You should cover the test scenarios below to test your integration more thoroughly:
- Initial purchase - when a logged-in customer purchases an offer from a list of offers available on the purchase page opened on the iOS mobile application.
- Recurring payment - when a customer’s subscription reaches a renewal date and the payment for it is processed.
- Subscription switch (upgrade/downgrade) - when a customer switches a subscription to another one (upgrades or downgrades a subscription).
- Subscription renewed - when a customer renews a subscription (that he/she has previously canceled) before the end of its grace period is reached.
- Subscription revival - when a customer buys the same offer as the one that he/she subscribed to previously, but the previous subscription was canceled by the customer and got terminated.
- Payment failed - when a customer's subscription reaches a renewal date and the payment for it fails.
- Subscription transfer - when a customer has an active subscription bought with one email address, and then he/she logs in with the second email address (using the same Apple Id) and selects the same previously purchased subscription, the new subscription will be transferred to the customer with the second email account.
👉 You can also refer to offical Apple testing guidelines under this link.
Good to Know
Unidentified User
In certain situations, when a purchase validation request fails to reach our connector due to connectivity issues or other disruptions, our system is designed to maintain transaction continuity. To achieve this, the StoreKit 2 connector will automatically create a temporary user, known as a ‘dummy’ or ‘unidentified’ user, within our system.
This mechanism ensures that the purchase can still be processed and recorded in our system, even if the user’s information is not fully validated at the time. The ‘dummy’ user acts as a placeholder, allowing us to later reconcile the transaction and transfer the subscription once the user's details can be verified.
This approach minimizes disruptions to the customer experience and helps maintain accurate transaction records, even in cases of temporary technical issues.
In such a case the user will not be given entitlements to the content.
In order to be able to identify the user and match the subscription with a named user, Cleeng should receive the initial purchase request. Once we receive the purchase validation request, and we are able to identify the user, the subscription will be transferred to their account. The unidentified user’s account will be removed.
Grace Period - Reducing Involuntary Subscriber Churn
Apple offers the feature of reducing involuntary subscriber churn which is supported by Cleeng. This feature prevents unintentional loss of subscribers due to billing issues. For more detailed information on how it works, please refer to Apple documentation.
Seamless Integration
Seamless integration is only for broadcasters who are currently using our StoreKit 1 integration endpoint.
For devices that cannot be migrated to StoreKit 2, we maintain StoreKit 1 API compatibility (excluding offerId parameter, as it was replaced by app store product IDs mapping in the Cleeng Dashboard).
Clients can also choose direct integration with StoreKit 2 via Apple StoreKit 2 API.
Introduction
For broadcasters who are currently using our StoreKit 1 integration endpoint, Cleeng ensures a smooth transition to StoreKit 2 using our seamless integration solution.
This integration simplifies the migration process by using a robust transformation layer that translates StoreKit 1 API calls to StoreKit 2, ensuring all existing functionalities are preserved.
Step-by-step Guide
The process requires actions both on the side of a broadcaster who is migrated and on Cleeng’s side.
The table below shows the responsibility split and the order of key steps to be performed so as to ensure a smooth and efficient transition for clients integrating with our system.
Step # | Broadcaster | Cleeng |
---|---|---|
1 | Verify offer mapping between Apple and Cleeng (see this article). Configure subscription upgrades and downgrades in the Cleeng Dashboard. | |
2 | Set up credentials in the Cleeng Dashboard (see point 5 in the Prerequisites section above). These should be the same credentials that are used for StoreKit 1 integration (important for retrieving information about purchases). | |
3 | Contact Cleeng Broadcaster Success Specialists Team and agree on the date of migration, selecting a time that minimizes customer impact. | Agree on the date of the migration with the Broadcaster. |
4 | Update notification endpoint in Apple Application profile (set notification version to v2). See point 4 in the Prerequisites section above). Note: It is recommended that you upgrade your iOS app to StoreKit 2. | Perform the migration process. |
5 | Coordinate sanity checks with the Broadcaster. | |
6 | Verify reports. |
Testing Guidance
For the broadcasters who already use StoreKit 1 integration, after completing the above Step-by-step guide, there should be no change in customer service delivery when Cleeng starts processing the requests in StoreKit 2 format in the background.
In order to make sure that all the necessary steps are done, you can purchase a new subscription via the existing iOS application and check the purchase in the Cleeng Dashboard for the given customer account. In the Transactions section, the StoreKit 2 payment method should be visible for the latest purchase.
Up next
Congratulations! By now you should be all set up to unlock the full potential of this integration in your projects.
As you wrap up, why not explore other integration tutorials for in-app purchases?
Updated 12 days ago