스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
앱 내 구입을 위한 App Store Server API 자세히 알아보기
App Store Server API, App Store Server Notifications 및 App Store Server Library의 최신 업데이트를 확인하여 서버에서 직접 고객 구매 데이터를 관리하고 탁월한 앱 내 구입 경험을 선사하세요. appAccountToken 및 서명 인증, 서명된 거래 및 갱신 정보의 새로운 필드, 새로운 API 업데이트를 소개합니다. 그런 다음 서버에서 프로모션 특가 서명을 생성하는 방법과 Send Consumption Information 엔드포인트를 사용하는 방법을 보여드립니다.
챕터
- 0:00 - Introduction
- 1:36 - Manage In-App Purchases
- 12:17 - Sign requests
- 15:24 - Participate in refunds
리소스
- Advanced Commerce API
- App Store Server API
- App Store Server Notifications
- Set App Account Token
- Simplifying your implementation by using the App Store Server Library
- Submit feedback
관련 비디오
WWDC25
WWDC24
-
비디오 검색…
Hello, I’m Riyaz, an engineer on the App Store server team. In this session, we're diving deep into the App Store server APIs for In-App Purchase. I'll show how our latest updates are designed to streamline and enhance your app server responsibilities. Let's start by exploring some of the key responsibilities performed by your app server.
In this session, I'll focus on three critical responsibilities.
First, manage In-App Purchases. This task involves associating transaction data with your customer accounts so your app can deliver content and services seamlessly.
Next, sign requests. This requires generating a signature to authorize your server’s requests to the App Store.
Finally, participate in the refund decision process.
By sharing consumption data related to purchases, your server can help the App Store make informed refund decisions. These are some of the many crucial responsibilities managed by your app server. Next, I'll explore how the new updates to the App Store server API will enhance these responsibilities. There's a lot to cover, so let's jump right in. First up, I'll introduce updates to transaction identifiers that will help you better manage In-App Purchases.
Then, I'll look at improvements for generating signatures to simplify signing requests on your server.
And finally, I'll review enhancements that simplify your participation in refund processes.
Let's dive into the details, beginning with Manage In-App Purchases. Managing In-App Purchases starts with effectively handling customer accounts on your system.
Typically, you would assign a unique account ID on your system to each customer, establishing a clear link between their account and the App Store transactions. This association is crucial for delivering the right content or personalizing the user experience. The App Store provides In-App Purchase data through three key data structures: AppTransaction, JWSTransaction, and JWSRenewalInfo.
First, I'll focus on the JWSTransaction. I'll return to the other types later.
When a customer makes an In-App Purchase, the App Store provides a signed transaction object. On the server, the JWSTransaction represents this signed transaction, which you can effectively verify and decode using the App Store Server Library.
Here's a sample decoded signedTransactionInfo.
The first few fields contains important information related to the app, and the in-app product type.
Following that, is metadata about the purchase including quantity, price, and currency.
If a customer redeems an offer, the JWSTransaction includes fields for the offerType, offerIdentifier, and offerDiscountType. We recently added a new field offerPeriod, which indicates the duration of the redeemed offer using the ISO 8601 duration format.
This field is also included in JWSRenewalInfo, informing you of the offer's duration that applies at the time of next subscription renewal.
Then, there are transaction identifiers.
The transactionId is a unique identifier for a transaction, such as an In-App Purchase, restore, or subscription renewal.
In this example, it represents the transaction ID of the subscription renewal.
The originalTransactionId is the transaction ID of the original purchase. It helps you accurately identify auto-renewable subscriptions, as it remains consistent across subscription renewals.
Lastly, the appAccountToken, which is a UUID you set in your app using StoreKit when a customer makes an In-App Purchase.
This field enables you to associate the purchase with the customer's account on your system. To make it easier to get appAccountToken for subscription renewals, we have included this field in the JWSRenewalInfo.
This will help you seamlessly associate your customer accounts with their most recent subscription renewal transactions. I'll explain how that works next.
You start by generating a UUID on your server, and associate this value with your customer account.
Then, your server passes this value to your app built with StoreKit. to set the appAccountToken at the time of In-App Purchase. We recommend using the same appAccountToken value for all In-App Purchases made by a given customer account. The App Store server returns the same appAccountToken value in the JWS transaction and renewal info.
Previously, you could set appAccountToken during purchases that were made in-app. But customers can also make purchases outside of your app, such as when they redeem offer codes or make promoted purchases in the App Store. To provide you more flexibility to set appAccountToken in such cases, we have a new server endpoint. Use the Set App Account Token endpoint to set a new appAccountToken or update an existing appAccountToken for a transaction.
You can use this endpoint for all product types. This includes past one-time purchases, such as consumables, non-consumables, and non-renewing subscriptions, and the latest purchase for each auto-renewable subscription. For auto-renewable subscriptions, the appAccountToken you set using this endpoint carries over to future renewals including upgrades or downgrades.
The Set App Account Token endpoint is useful when a customer completes a transaction outside of your app, such as redeeming an offer code. Previously, there was no way to set the appAccountToken field for these types of purchases, since StoreKit wasn't involved.
Additionally, you can fix inconsistencies in associating appAccountToken with customer accounts such as when account ownership changes in your system. Now, I'll show you the endpoint, which is a part of the App Store Server API.
Here’s an example of using the Set App Account Token endpoint.
Provide the original TransactionId in the path. This value identifies either the one-time purchase transaction, or the subscription that you want to set the appAccountToken for.
In the request body, set a desired UUID value for the appAccountToken. The appAccountToken you provide with the Set App Account Token endpoint overrides any previous appAccountToken set for that transaction.
The appAccountToken along with other transaction identifiers such as transactionId and originalTransactionId, provide a way to associate customer accounts with the App Store transactions. Here’s a brief overview of these identifiers.
The App Store is the source of transactionId and originalTransactionId, while you are responsible for generating and associating the appAccountToken with an App Store transaction. The transactionId is useful to identify a specific purchase event.
The originalTransactionId is great for managing the subscription life cycle of auto-renewable subscriptions in a single subscription group and for checking the subscription status.
The appAccountToken is useful to associate a customer's account information with their In-App Purchase. If your app supports Family Sharing, note that appAccountToken is not available for family shared transactions. Both transactionId and originalTransactionId are present in JWSTransaction and JWSRenewalInfo. The appAccountToken is only available, if you set it for a purchase either using StoreKit or the new Set App Account Token endpoint.
When a customer downloads your app, the AppTransaction object becomes available through StoreKit and represents important app download information.
As transactionId, originalTransactionId, and appAccountToken are specific to an In-App Purchase, they are not included in the AppTransaction object.
But sometimes it’s important to uniquely identify an app download, such as for unlocking content at app install. So, we have added a new field called appTransactionId to the AppTransaction object to help you with this use-case. The appTransactionId is a globally unique identifier for each Apple Account per app.
For Family Sharing, each family member gets a unique appTransactionId. By design, the appTransactionId is static for a given Apple Account and app, across redownloads, refunds, repurchases, or storefront changes.
The appTransactionId is also included with any In-App Purchases made by the customer within your app. This provides you greater flexibility in associating your customer accounts to all App Store transactions. I'll explain how that works next.
Here’s one way to use the appTransactionId to associate your customer accounts with the App Store transactions.
First, when a customer downloads your app, associate the customer account in your system with the appTransactionId present in the AppTransaction object.
One way to get AppTransaction object on your server is by sending this info from your app.
When a customer makes an In-App Purchase, JWSTransaction and JWSRenewalInfo include the same appTransactionId. So, you can associate once, and re-use across all App Store transaction objects. Since the appTransactionId is present across all App Store transaction objects it unlocks some valuable use-cases for your app such as identifying whether two different subscription purchases belong to the same customer account. For example, assume that your app supports two subscription products: a monthly billed sports newsletter and an annual season subscription to watch live games. How can you determine if a customer account has access to both subscriptions? Even though each subscription has distinct transactionId and originalTransactionId, they share the same appTransactionId.
You can leverage this field to enable in-app customizations at launch, such as restoring In-App Purchases. Additionally, you can use appTransactionId as the transaction ID for popular App Store Server API endpoints, like Get Transaction History, Get All Subscription Statuses, and more. Today, I am pleased to share a new endpoint to get AppTransaction object using a server endpoint. With the new Get App Transaction Info endpoint, for the first time, you can fetch app download information directly on your server, without relying on the device. You can use the AppTransaction object to check important app download information such as app version, platform, and environment.
With this, you can understand how your app is performing with business model changes. Keep in mind, this endpoint does not return device related details such as device Verification.
For those purposes, continue to rely on the AppTransaction object obtained from your app.
Next, I'll show you the endpoint, which is a part of the App Store Server API.
Here’s an example of using the Get App Transaction Info endpoint. You can provide any transaction identifier such as an originalTransactionId, transactionId or appTransactionId in the path.
The response contains JWS signedAppTransactionInfo. You can use the App Store Server Library as one way to decode the signedAppTransactionInfo. The Get App Transaction Info endpoint will be available later this year. Now, I’ll compare appTransactionId with other transaction identifiers that I showed earlier.
The App Store generates appTransactionId, as it does the transactionId and originalTransactionId.
You can use the appTransactionId to uniquely identify app downloads, and associate the customer’s subsequent purchases with that download. The appTransactionId is consistent across all App Store transaction objects. You can use appTransactionId for family shared transactions, if your app supports Family Sharing. We recommend using appTransactionId as it provides a one-stop identifier solution for all your needs. It simplifies managing In-App Purchases, and associating them with the customer accounts on your server. Now, let's jump into some key improvements we have made to sign requests. The first step is creating a JWS string, short for JSON Web Signature, on your server. You then sign this information using a private key that you download from App Store Connect.
You then send this signature string to your app built with StoreKit to call functions that require a signature.
StoreKit then sends the signed signature string to the App Store server. Previously, depending on your use-case, you signed signatures with different formats as required by the App Store server. Now, we’ve unified signing requests across all use cases to use the JWS signature format. This means you can now use this format in StoreKit calls that require them, including functions such as generating promotional offer signatures. You can now sign promotional offers using the JWS signature format. This new signing method is an alternative to the previous promotional offer signature. To provide you more flexibility with introductory offers we recently introduced a new JWS introductory offer signature. This feature enables you to set custom eligibility for introductory offers per transaction and per user, thereby having more control over the number of introductory offers a customer redeems with the App Store.
You can also send signed JWS in-app requests with the Advanced Commerce API. For more information please visit our developer documentation. I’ll now show you how to create the JWS promotional offer signature on your server. Use promotional offer signature with StoreKit, to retain existing or churned subscribers on your app.
Here’s an example of creating a promotional offer signature using the App Store Server Library. I'm using Java for this example.
First, I instantiate the class PromotionalOfferV2SignatureCreator with a private key, keyId, issuerId, and bundleId for my app. You can find key, keyId, and issuerId on App Store Connect.
These values are used to sign the signature, which prevents customers from redeeming promotional offers without developer consent.
Next, I specify transactionId. Here, you can supply any transaction identifier that belongs to the customer, including the appTransactionId.
Provide transactionId, if you want to limit the offer to a specific customer, if not, you can skip this field.
Then, I provide a productId and offerId.
I have pre-configured the offer represented by this ID in App Store Connect.
Finally, I pass the productId, offerId, and transactionId to the createSignature function. Notice that the new signature is simpler than the older version as it has fewer inputs. You can simplify signing requests across multiple use-cases by using the unified JWS signature signing format.
Even after providing an offer, it is sometimes possible that customers may drop-off and request a refund due to things that are beyond your control such as a billing issue, or an accidental purchase. For such cases, let me now show you how to participate in the refund decision process. First, I’ll share some benefits. You should consider participating in refund decisions because you know your customers product consumption. For instance, when supporting consumable products on your app, you are already managing customers' consumable balances on your server.
This can help improve customer satisfaction post-refund request.
When a customer requests a refund, the App Store sends a CONSUMPTION_REQUEST notification to your server. To help inform the refund decisioning process, you can respond to this notification using the Send Consumption Information endpoint.
I am delighted to share a new and improved Send Consumption Information V2 endpoint.
At its core, the endpoint is simpler to integrate as we have significantly reduced the number of inputs you provide compared to the previous version.
The new endpoint also supports prorated refund preference to better represent partial consumption of a product, when applicable.
While the previous version of this endpoint only supported consumables and auto-renewable subscriptions, we have now extended the support to all product types including non-consumables and non-renewing subscriptions.
If you have already been using the V1 end point note that this is now deprecated but will continue to accept requests. If you haven't used the Send Consumption Information endpoint, we recommend using the latest V2 endpoint with the App Store Server Library. I'll now show you how to use the Send Consumption Information V2 endpoint. Assume that a customer has requested a refund for a consumable purchase, and a CONSUMPTION_REQUEST notification was sent to your sever. Here's an example on how to respond to the notification with the Send Consumption Information V2 endpoint.
You provide the transactionId in the path, that you find in CONSUMPTION_REQUEST notification.
The new endpoint supports a total of five input fields down from twelve in the previous version.
Out of the five input fields, there are three mandatory fields, and two optional fields.
We have significantly reduced the fields to simplify your participation in refund decisions. Set the customerConsented field to true if the customer has provided consent to send the App Store the consumption data related to their refund request, including all the data you provide in the ConsumptionRequestV2 body. If the customer has not consented, do not respond to CONSUMPTION_REQUEST notification. If the endpoint is called with the field set to false, the request is rejected.
Use sampleContentProvided to specify whether you provided a sample content before the customer purchased the product. Use DELIVERED as the deliveryStatus if you successfully delivered the content to the customer; otherwise, use an appropriate UNDELIVERED status.
You can optionally provide your preference for the refund. You can now consider providing a prorated refund preference using the GRANT_PRORATED value, in addition to the already-supported full or no refund. If you don't want to provide a preference, do not set this field.
The consumptionPercentage tells the consumption of the product in millipercent.
Here, a value of 25,000 represents 25% consumption of the consumable product. The Send Consumption Information V2 endpoint will be available later this year. Now, let's dive into the new prorated refund option provided by the latest V2 endpoint. Consider providing a prorated refund preference in cases where the customer can partially consume the product.
Prorated refund preference allows you to specify the consumption, helping the App Store grant an appropriate refund amount.
It is required that you specify consumptionPercentage when you provide a prorated refund preference for consumable, non-consumable, and non-renewing subscription product types. This is so that App Store can accurately grant the appropriate refund. Note that the App Store calculates the consumptionPercentage of auto-renewable subscriptions for you, using the remaining time left on the customer's subscription. The consumption data you submit helps the App Store decide to grant a full refund, prorate the refund, or decline it altogether. You are notified about the decision using a REFUND or REFUND_DECLINED notification. If you receive a REFUND_DECLINED notification, no action is needed. However, you’re responsible to take an appropriate action when you receive a REFUND notification. Here's a sample REFUND notification. You can now understand how much of a refund was granted by the App Store using the new refundPercentage field.
In this case, a 75% refund was granted, so you can take the appropriate action for the consumed product.
When using this field, remember that App Store Connect is your source of truth for all financial and accounting purposes.
You can also understand the type of revocation using the new revocationType field.
This field could be REFUND_FULL, REFUND_PRORATED, or FAMILY_REVOKE.
Since this is a consumable refund, the possible values are REFUND_FULL and REFUND_PRORATED. In case of a full refund or family revoke, you immediately revoke access to content on your server. For REFUND_PRORATED, revoke the refunded percentage of the content. I'll now show you how to handle a refund notification with prorated refund on your server. In the case of a consumable, non-consumable, or non-renewing subscription product, you use the refundPercentage field to calculate and revoke the proportional amount of content from the customer's account. For example, if the customer purchased a virtual currency, you may wish to reduce their balance by the refunded amount. For auto-renewable subscriptions, handle prorated refunds the same way you handle full refunds.
Check the current subscription status, and take appropriate action. I hope you'll use the new Send Consumption Information V2 endpoint to participate in the refund decision process, as it is now easier and more powerful than ever.
We have covered a lot today! Let’s quickly recap.
I showed you various transaction identifiers, and introduced appTransactionId as a one-stop transaction identifier. Then, I explored the unified JWS signature signing format.
Finally, I showed you how easy it is to participate in refund decisions. Before I let you go, let me talk about some useful next steps. If you've already made contributions to the open-source App Store Server Library, thank you! Otherwise, please visit our GitHub page to learn how to contribute and support the App Store community. As we bring in new features we would love to hear from you. Please submit feature requests and feedback for the App Store server team with Feedback Assistant. To learn more about the updates we have made to StoreKit, visit WWDC25 session "What's new in StoreKit and In-App Purchase". Also, check out WWDC24 session "Explore App Store server APIs for In-App Purchase", to learn more about the App Store server. Thanks for joining me today, I'll see you next time!
-
-
- 0:00 - Introduction
Learn about updates to the App Store server APIs for In-App Purchase, specifically how the updates streamline app server responsibilities. The three main areas covered are: Managing In-App Purchases by associating transaction data with customer accounts Signing requests to authorize server communications with the App Store Participating in the refund decision process by sharing consumption data The updates include improvements to transaction identifiers, signature generation, and refund processes.
- 1:36 - Manage In-App Purchases
Managing In-App Purchases involves assigning unique account IDs to customers and linking them to App Store transactions. The App Store provides data through three structures, with the focus initially on 'JWSTransaction'. This signed transaction object, verified and decoded using the App Store Server Library, contains details about the app, product type, purchase metadata, and offer information. New fields include 'offerPeriod' which indicates the duration of redeemed offers using ISO 8601 format, and is present in both 'JWSTransaction' and 'JWSRenewalInfo' for subscription renewals. Transaction identifiers are also included to uniquely track each purchase, restore, or renewal.
- 12:17 - Sign requests
The JWS Signature Format is introduced as a means for unified signing requests across all use cases. This includes, for example, generating promotional offer signatures, introductory offers per transaction and per user. An example is discussed showing the details involved.
- 15:24 - Participate in refunds
Features allowing developers to participate in the refund decision process are discussed. This includes the expanded Send Consumption Information V2 endpoint the provides simpler integration options and additional support for all product types including non-consumables and non-renewing subscriptions. Details explaining what you need to do to support the new Send Consumption Information V2 endpoint are discussed including the new prorated refund option. This allows you to provide a prorated refund option in cases where customers can partially consume a product.