Discover the latest updates to the App Store Server API and App Store Server Notifications. Explore the current API offerings and learn how to track subscription status with notifications, work with transactions on your server, and efficiently recover missed notifications. We'll also show you how your server can support apps using StoreKit or StoreKit 2, and share an important deprecation in the API and suggested migration workflow.
♪ ♪ Ian: Hi, everyone. I'm Ian, and I'm an engineer on the App Store server team. Today I'll share some exciting updates about our server APIs for in-app purchase, including new features and important updates. If you're not familiar, we offer two primary APIs that help you get the most out of in-app purchases on your server. The first is the App Store Server API. You call the App Store Server API on-demand from your server, and it returns all the data you need to effectively manage in-app purchases made in your apps. The API offers a variety of powerful endpoints for retrieving and even modifying in-app purchase data.
The other major API we offer is App Store Server Notifications V2.
With App Store Server Notifications V2, the App Store server proactively sends updates to your server about in-app purchases made in your app. That means you can get minute-by-minute updates without needing to poll the App Store Server API.
Notifications cover a comprehensive set of events, including subscription renewals, expirations, refunds, and much more.
These events allow you to track the full lifecycle of in-app purchases, so you can better understand and respond to user behavior.
The App Store Server API and App Store Server Notifications V2 share a lot of great features. They both provide transaction data in a familiar JSON format, and the data is signed, so you can be confident it came from Apple. You can also use both APIs to support your apps that use StoreKit 2 or the original StoreKit API. And we actively support these APIs with new features based on your feedback.
Today I’m happy to announce the latest collection of updates coming to the App Store Server API and App Store Server Notifications V2.
We have so many new features, I only have time to cover a few in today's session. Please check out our developer documentation for the full details of all these new features. Now let's dive into this great selection of App Store server updates. I'll share today's updates in three parts. First, I'll detail some new features that make working with transactions on your server easier. Next, I'll cover enhancements to App Store Server Notifications that will help you reliably determine the status of your users' subscriptions. And finally, I'll provide important updates about migrating away from our older APIs. Let's get started with transactions. Transactions are a core data object for in-app purchase. They represent an in-app purchase on a device and contain important information about that purchase, such as the product identifier, the type, the purchase date, and much more.
The App Store Server represents a transaction through a JSON object signed with JWS. This is a secure, standardized format that you'll see across the App Store Server API and App Store Server Notifications V2.
The primary way to retrieve these signed transactions is using the Get Transaction History endpoint of the App Store Server API.
This endpoint returns the full transaction history for a given user of your app, so you can use it to keep up-to-date with all of a user's purchases, from past to present. But sometimes, your server is already aware of a transaction, for example, due to a call made from your app to your server. Server-side, you may want to further validate that transaction and ensure you have the most up-to-date information for it.
Previously, this use case required calling Get Transaction History and sifting through the response for the matching transaction. Once found, you could refresh your record of the transaction with the data in the response.
This process might feel tedious, particularly if your user's transaction history spans multiple pages, requiring multiple calls to the endpoint. And it also doesn't work if you're looking for a finished consumable transaction, as those don't appear in the Get Transaction History response. This use case simply demands a more specific solution.
That's why today, we're introducing a new endpoint that will directly address this use case. With the new Get Transaction Info endpoint, you can request the signed transaction information for a single purchase, and all you need to provide is a transactionId.
All transactionIds are supported, no matter the product type or the finished status of the transaction on the user's device. That's right, you can even fetch finished consumables from this endpoint.
Let's take a quick look at how the new endpoint works.
You'll send a GET request to this new endpoint on the App Store server, including the transactionId as a path parameter.
You'll receive a response containing a signedTransactionInfo string.
By decoding the signedTransactionInfo, you can view the transaction information for the ID you provided in the request.
And that's it. The new Get Transaction Info endpoint is quite simple, but makes for greater flexibility when working with transactions on your server. I think you'll find it useful for a variety of use cases. Now, let's take that theme of flexibility and extend it even further.
You might be familiar with these popular endpoints of the App Store Server API.
Each of these endpoints require an originalTransactionId as a path parameter. This id indicates to the server which user you're requesting or sending data for.
But you might not always have an originalTransactionId handy. What if all you have is a transactionId? You could send it to the new Get Transaction Info endpoint in order to retrieve the originalTransactionId, but why call one endpoint just to call another? Instead, starting today, you can call these endpoints with any transactionId.
Just provide the ID in the path of your request, just as you did before. We hope this greater flexibility will make it easier than ever to call these core endpoints of the App Store Server API. And if you're already calling these endpoints with originalTransactionIds, don't worry, they will continue to work as well. Now let's switch over to updates coming to App Store Server Notifications. If your app offers auto-renewable subscriptions, it's important for you to keep track of the status of those subscriptions and how it changes over time.
Here you can see the five possible statuses of a subscription. With App Store Server Notifications V2, you receive prompt notifications for events that lead to changes in this status, so you can quickly enable and disable content at the appropriate time and maintain a smooth user experience.
Let's take a look at how notifications can inform your knowledge of a subscription's status. Many notification events directly indicate the status of the subscription through their type and subtype. Take for example this SUBSCRIBED notification with subtype INITIAL_BUY.
This notification indicates a new subscription to your product, so you know the subscription's status is Active.
Here's an even simpler example, where the notification type is EXPIRED.
This clearly indicates that the status of the associated subscription is now Expired.
But for some notifications, the subscription status may not be so clear. Take for example this REFUND notification. This notification type is sent when a refund is granted for an in-app purchase made in your app. Checking the signedTransactionInfo of this notification will tell us what purchase was refunded.
In this case, we see the refund was for an auto-renewable subscription, so we'd like to update our record of the subscription's status.
It might be tempting to assume the status is now "Revoked," but that's not necessarily the case. If there's a more recent subscription renewal purchase with the same originalTransactionId, the status of the subscription could still be Active. If that's the case, you should not disable access to the subscription content.
In this situation, the status of the subscription is simply unclear, and the data in the notification alone is not enough to update it. This is not ideal. When you receive an App Store server notification for a subscription, we want it to clearly indicate the latest status of the subscription, so you can keep this important information up-to-date on your server.
That's why today, we're introducing a new status field to the data object of App Store Server Notifications V2. This field is a simple integer that indicates one of the five core states of a subscription I detailed earlier.
This new field will be included in every notification we send for auto-renewable subscriptions.
Now you can get the status of a subscription without having to call the Get All Subscription Statuses endpoint of the App Store Server API. Let's see how this new field improves the scenario I described earlier. Now when you receive a REFUND notification for a subscription, you can simply check the status field to understand the status of the subscription.
In this case it's 1, so you know the associated subscription is Active.
The new status field makes App Store Server Notifications more useful than ever, so useful, that you'll want to ensure you don't miss a single one. But if your server experiences an outage, the App Store server may not be able to reach it to send a notification.
That's why we offer the Get Notification History endpoint of the App Store Server API.
This endpoint allows you to request up to the last six months of version 2 notifications the App Store server generated for your app.
That way when your server has a known outage, you can call this endpoint for the outage period and retrieve any notifications your server missed.
For some use cases though, this process might not feel very efficient. Occasionally, your server may miss a notification even outside of an outage, for example, due to transient network issues. In this situation, you might not have a clear time period to query the endpoint with, leaving you to sift through pages of notifications that your server has largely already received.
To address this use case, we're introducing a new request field to Get Notification History called "onlyFailures".
This optional field will limit the notifications returned to only those that have failed to reach your server. The response will even contain notifications that are currently in the retry process.
Now you can recover from outages and occasional network issues much faster, as you only need to parse notifications that your server hasn't already seen. Let's take a look at how this new field works. You send a request to the Get Notification History endpoint, and you include the new field, onlyFailures, in the request body.
Here's the response.
Each entry in the notificationHistory array represents a notification, and since you included the new onlyFailures field in your request, every notification listed here has failed to reach your server.
Let's zoom in to a single notification entry.
Here we have the signedPayload. We can decode this string to view the contents of the notification, just as it was originally sent to your server.
Taking a look at the sendAttempts array for this notification, we can now see the result of each send attempt. This array may contain up to six entries, with one for the initial send attempt, and up to five for retries.
Here we see only two entries, and both have failed, so the notification must still be in the retry process. If a later retry is successful, this notification will no longer appear for subsequent requests that include the onlyFailures field.
So that's how the new onlyFailures field works. I think you'll find that it makes Get Notification History even more useful.
Finally, an important update about migrating away from our older APIs.
If your app has offered in-app purchases for some time, you're likely familiar with the verifyReceipt API.
In 2021, we released the App Store Server API as the new way to get in-app purchase data from the App Store Server. Let's compare these two APIs.
With verifyReceipt, you can verify and decode the receipts you receive from clients running the original version of StoreKit. With the App Store Server API, you can fetch all the same data you find in receipts and more using these three endpoints. And the App Store Server API also provides a variety of additional endpoints that offer useful data and powerful functionality you won't find anywhere else.
Shifting to our notification APIs, we still support the older App Store Server Notifications V1.
But in 2021, we introduced App Store Server Notifications V2. Now let's compare these APIs.
App Store Server Notifications V1 and V2 both offer real-time in-app purchase events sent directly to your server. But V2 offers greater clarity by defining events using both a type and subtype. And the differences don't stop there. V2 also offers notifications for additional events, the ability to request a test notification, access to notification history, and the brand-new status field for tracking the state of your users' subscriptions.
By adopting the App Store Server API and App Store Server Notifications V2, you'll unlock a wide array of new features for securely and efficiently managing in-app purchase data on your server. Ultimately, that means a better in-app purchase experience for your customers.
That's why today, we're announcing the deprecation of verifyReceipt and App Store Server Notifications V1. Starting today, these APIs are considered deprecated and will no longer receive feature updates.
Start planning your migration now to enjoy all the benefits of the newer APIs.
Migration requires just a few short steps.
To migrate from verifyReceipt to the App Store Server API, you'll first need to sign a JWT to represent your app, which is a simple process outlined in our documentation. Whenever you call the App Store Server API, you'll provide this JWT as a header. It will prove that you own the requested app data.
Next, you'll need to save a transactionId for each of your users. You'll provide this transactionId as a path parameter whenever you call core endpoints, like Get Transaction History and Get All Subscription Statuses. Any transactionId will work. If you maintain a database you likely already have one saved. Otherwise, you can extract one from a receipt for each of your users.
And that's it. You'll then have access to all the same data you used to get from verifyReceipt and so much more.
Migration from App Store Server Notifications V1 to V2 is even simpler. First, prepare your server to parse the new V2 format. If you're already using the App Store Server API, this step should be straightforward, as App Store Server Notifications V2 uses the same JWS transaction format.
Once your server is ready, visit App Store Connect to change your preference from V1 to V2 notifications. To test your implementation, you can start by receiving version 2 notifications in sandbox only.
After switching your preference, the App Store server will start sending new notifications in the V2 format. If you have any V1 notifications in the retry process, you may continue to receive them for up to three days.
For more assistance with migration, we have additional resources available. The App Store Server API and App Store Server Notifications V2 are available in the sandbox environment, so you can test your implementation before rolling it out to production.
And this week, we are releasing the App Store Server Library, a new open-source library for calling the App Store Server API and parsing App Store Server Notifications V2. It can help you easily call our endpoints, verify the signed data you receive, and even extract transactionIds from receipts to make migration easier.
I hope you'll check out its dedicated session at WWDC this year titled "Meet the App Store Server Library." And for more tips on how to migrate, see the WWDC22 session titled, "Explore in-app purchase integration and migration".
That concludes our App Store Server updates for this session. I hope you'll utilize the great new capabilities we announced today, and check out our documentation for even more features we didn't have time to review.
Every feature is available now in both sandbox and production, so you can first test in sandbox, then roll out to your production server whenever you're ready.
And we'd love to hear from you. If you have feature requests for the App Store server, please let us know through Apple’s Feedback Assistant. Thanks for joining me at WWDC23! ♪ ♪
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.