App Store Server API

RSS for tag

Call this REST API from your server to request and provide information about your customers' in-app purchases.

Posts under App Store Server API tag

44 Posts

Post

Replies

Boosts

Views

Activity

In-App Purchase Products Not Fetching via Unity IAP in TestFlight Builds
We are experiencing an issue with our iOS TestFlight builds where in-app purchase (IAP) products are not being retrieved as expected. We are using Unity IAP to handle our purchases, and despite having all the products correctly configured and approved in App Store Connect, we consistently receive errors such as: UnityIAP: Received 0 products Unavailable product [product_id] We have thoroughly verified that: The product identifiers are correctly configured in App Store Connect. The bundle ID mappings are correctly set on both Unity and our backend. The same setup works on the live App Store build, where purchases are fetched and validated correctly for the same set of In App products. Sandbox test accounts are being used during TestFlight testing. This issue only started appearing recently and affects the TestFlight builds only. Note: My App ID and Product ID are correct, the IAP is live on the App Store, and the product is recognized in sandbox. Looking forward to your support on this matter.
4
16
960
May ’25
Cancel subscription not working in TestFlight
Hi, I have deployed my app on Test Flight, I have two subscriptions, monthly and yearly. User can have one of them at a time and upgrade, downgrade to the other. Upgrade, downgrade, cancel from the Apple Settings worked fine in the sandbox environment when testing locally. Now when I have deployed the app on TestFlight, I was able to purchase the subscription successfully from my app. Now when I want to cancel my subscription from the Apple Settings it gives me the following error after confirming cancellation, 'Your request is temporarily unable to be processed. Please try again later.' Also the other subscription offer (yearly) is also not shown to which I could upgrade, even though in the sandbox I was able to upgrade downgrade from the settings. Another thing I have noticed is that the app Icon or name is not shown anywhere in settings with the subscription. Instead of app icon only empty square is shown. Even though app icon shows fine everywhere else. Can someone please help me figure out this issue?
22
15
4.5k
Oct ’25
Transaction ID Misassociation in IAP Subscription API
Dear Apple Support Team, Hello! I am currently developing the in-app subscription functionality using Apple IAP API and have encountered a serious technical issue while processing subscription data. I would like to report this issue to you. Issue Description: When calling the subscription API endpoint, the same OriginalTransactionId returns inconsistent results. Specifically, a particular transaction ID (let's call it TransactionId_A) should belong to the subscription order with OriginalTransactionId_A, but it is currently incorrectly associated with OriginalTransactionId_B. This issue severely affects our ability to accurately manage and process subscription data. Here are the relevant log details for your reference: API Endpoint Requested: https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{TransactionId_A} (Note: The link is a placeholder for the actual API endpoint.) Log Information on February 21, 2025, at 09:40:09: { "AppAccountToken": "{AppAccountToken}", "BundleId": "{BundleId}", "Currency": "CNY", "Environment": "Production", "ExpiresDate": {ExpiresDate}, "InAppOwnershipType": "PURCHASED", "IsUpgraded": false, "OfferDiscountType": "", "OfferIdentifier": "", "OfferType": 0, "OriginalPurchaseDate": {OriginalPurchaseDate}, "OriginalTransactionId": "{OriginalTransactionId_A}", "Price": {Price}, "ProductId": "{ProductId}", "PurchaseDate": {PurchaseDate}, "Quantity": 1, "RevocationDate": 0, "RevocationReason": 0, "SignedDate": {SignedDate}, "Storefront": "CHN", "StorefrontId": {StorefrontId}, "SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}", "TransactionId": "{TransactionId_A}", "TransactionReason": "PURCHASE", "Type": "Auto-Renewable Subscription", "WebOrderLineItemId": "{WebOrderLineItemId}" } Log Information on March 21, 2025, at 09:38:49: { "AppAccountToken": "{AppAccountToken}", "BundleId": "{BundleId}", "Currency": "CNY", "Environment": "Production", "ExpiresDate": {ExpiresDate}, "InAppOwnershipType": "PURCHASED", "IsUpgraded": false, "OfferDiscountType": "", "OfferIdentifier": "", "OfferType": 0, "OriginalPurchaseDate": {OriginalPurchaseDate}, "OriginalTransactionId": "{OriginalTransactionId_B}", "Price": {Price}, "ProductId": "{ProductId}", "PurchaseDate": {PurchaseDate}, "Quantity": 1, "RevocationDate": 0, "RevocationReason": 0, "SignedDate": {SignedDate}, "Storefront": "CHN", "StorefrontId": {StorefrontId}, "SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}", "TransactionId": "{TransactionId_A}", "TransactionReason": "PURCHASE", "Type": "Auto-Renewable Subscription", "WebOrderLineItemId": "{WebOrderLineItemId}" } From the above logs, it is evident that the same transaction (TransactionId_A) returns different OriginalTransactionId values at different times, which is clearly not expected and severely impacts our ability to correctly process and manage subscription data. I hope you can address and investigate this issue as soon as possible. If you need any further information or assistance, please feel free to contact me. Thank you for your support! Best regards!
6
4
1.1k
Apr ’25
When will ONE_TIME_CHARGE notify type be available in a production environment?
https://developer.apple.com/documentation/appstoreservernotifications/app-store-server-notifications-changelog#June-10-2024 ONE_TIME_CHARGE notify type running in a sandbox environment for almost a year, the feature is not yet available for production environment. The notification is already available in Google subscriptions. Our services often miss orders because of the absence of this notification. Can you give us an approximate time range?
2
3
520
May ’25
StoreKit appAccountToken Not Preserved During Apple ID Email Migration
I'm encountering an issue with the App Store Server API where the appAccountToken is not preserved when users migrate their Apple ID email addresses. I've submitted Feedback Assistant ticket FB18709241 but wanted to check if anyone else has experienced this and get community input on best practices. The Issue When a user migrates their Apple ID from one email to another (e.g., from olduser@example.com to newuser@icloud.com), the App Store creates a new subscription transaction with a different originalTransactionId, but the appAccountToken is not carried forward from the original transaction. What I'm Seeing note: these values are fake When querying /inApps/v1/subscriptions/{originalTransactionId} with the either post-migration transaction ID or the pre-migration transaction ID, the API returns both transactions: Pre-migration transaction (status: 2 - inactive): originalTransactionId: "12345678910111" Contains: "appAccountToken": "abc123-def456-ghi789" Post-migration transaction (status: 1 - active): originalTransactionId: "67891011121314" Missing: appAccountToken entirely The Problem The appAccountToken is our only way to link App Store subscriptions to user accounts. Without it on the new transaction: Users lose access to premium features despite having valid subscriptions Server-side renewal notifications can't be matched to user accounts Manual support intervention is required for each affected user Questions for the Community Has anyone else encountered this issue with Apple ID migrations? What's the recommended approach for handling this scenario? Is there an alternative mechanism to maintain the subscription-to-user linkage across migrations? Questions for Apple Engineers Is this the expected behavior, or should the appAccountToken be preserved? Are there any planned improvements to handle this migration scenario? What's the best practice for developers to handle this case? Interestingly, both the old and new transaction IDs return the same JSON response from the App Store Server API, suggesting Apple maintains internal linkage between these transactions, but the appAccountToken isn't carried forward to the active transaction. Any insights or similar experiences would be greatly appreciated! Thank you!! Feedback Assistant: FB18709241
0
3
196
Jul ’25
Apple Server Notifications Webhooks stopped retrying on HTTP 400
Hey We have noticed a change in the retry behavior of Apple Server Notifications webhooks V2 starting around March 12–13, 2026. Previously, when our webhook endpoint returned an HTTP 400 response, Apple would retry the notification delivery multiple times according to the documented retry policy. However, beginning around March 12–13, it appears that Apple no longer retries the webhook when a 400 response is returned. The notification is sent only once and no further retry attempts are made. From our understanding of the documentation, retries should occur when delivery fails, and historically we observed retries even for some 4xx responses. We would like to confirm: Has Apple recently changed the retry behavior for Server Notifications? Are HTTP 4xx responses (specifically 400) now considered terminal failures that will not trigger retries? Is this change intentional or related to a rollout in the webhook delivery system? We have called the "Notification History" endpoint for some users who purchased a sub and we are only getting one attempt with the following data in it: { attemptDate: 1773469202552, (2026-03-14T06:20:02.552Z) sendAttemptResult: 'UNSUCCESSFUL_HTTP_RESPONSE_CODE', } This was 2 days ago, based on the docs, the user should have a few attempts at least. This behavior change affects systems that rely on retries to handle temporary validation issues or transient failures. Thanks!
3
2
170
1w
App Store Server Notifications and API Client - Toggling Sandbox vs Production Environment
The documentation mentions the following: Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code. This approach ensures you don’t have to switch between URLs while your app is in testing, in review by App Review, or live in the App Store. This way, you can use one server environment to handle both Sandbox and Production environments. It is necessary to pass App Review. However, I'm not manually hitting these URLs - I'm using Apple's libraries. Specifically, the environment is used in SignedDataVerifier and AppStoreServerAPIClient. (I can't link to these because, for some reason, the domain apple.github.io is not allowed. The documentation for these is only found there. You can find it quickly by searching these terms and the domain.) Here is how SignedDataVerifier is being used: const verifier = new SignedDataVerifier( appleRootCertificates, APPLE_ENABLE_ONLINE_CHECKS, APPLE_ENVIRONMENT, APPLE_BUNDLE_ID, APPLE_APP_ID ) const verifiedNotification: ResponseBodyV2DecodedPayload = await verifier.verifyAndDecodeNotification(signedPayload) if (!verifiedNotification) { // Failure return } Here is how AppStoreServerAPIClient is being used: const appStoreServerAPIClient = new AppStoreServerAPIClient( SIGNING_KEY, APPLE_IAP_KEY_ID, APPLE_IAP_ISSUER_ID, APPLE_BUNDLE_ID, APPLE_ENVIRONMENT ) const statusResponse: StatusResponse = await appStoreServerAPIClient.getAllSubscriptionStatuses(originalTransactionId, [Status.ACTIVE]) In the source code for SignedDataVerifier.verifyAndDecodeNotification, I can see that it throws a VerificationException(VerificationStatus.INVALID_ENVIRONMENT) error . So for SignedDataVerifier is it as simple as wrapping my code in a try/catch and checking that the error's status code is 21007? I'm unsure about this because if you scroll to the bottom of the linked source code file, you can see the enumeration VerificationStatus, but it's unclear if this member has a value of 21007. The source code for AppStoreServerAPIClient only says that it throws an APIException if a response could not be processed, so I'm not too sure about how to handle this one.
2
2
964
Sep ’25
URGENT: Severe Performance Issue with App Store Connect API (In-App Purchases Retrieval)
Hello Apple Support Team, We are currently experiencing a critical business issue caused by a sudden performance degradation in the App Store Connect API. This problem is blocking key parts of our production systems at wappier Optimizing game performance - website: https://wappier.com/ Since October 15, requests to the following endpoint have been taking extremely long to complete when fetching more than approximately 200 in-app purchase items. In many cases, these requests never complete even after several hours, making it impossible for us to retrieve all required data. Endpoint: https://api.appstoreconnect.apple.com/v1/apps/1252850847/inAppPurchasesV2 Parameters: { "include": "appStoreReviewScreenshot,inAppPurchaseLocalizations", "cursor": "Jd6I", "limit": "200" } We confirm that: This behavior started suddenly on October 15. No changes were made on our end. We found no corresponding updates or API change announcements in your release notes. Requests for fewer than 200 in-app products continue to perform normally. This issue is blocking our operations, as our systems depend on timely responses from this endpoint for in-app purchase data synchronization. We kindly ask your team to investigate this issue urgently and provide us guidance, and if possible, revert any recent change introduced around October 15 that could have impacted this endpoint’s performance. Thank you very much for your prompt attention and support. wappier Dev Team
0
2
207
Oct ’25
Unexpected 401 Unauthorized response from production endpoint when using sandbox transactionId with Get Transaction Info API
We have encountered an issue when verifying transactions using the Get Transaction Info API. We tested the behavior in both the sandbox and production environments and observed the following results. When calling the production endpoint: https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionId} with a transactionId generated in the sandbox environment, the API returns HTTP 401 Unauthorized. However, based on the documentation and common understanding, we expected HTTP 404 Not Found in this case. Using the same JWT token, if we call the sandbox endpoint: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/{transactionId}, we receive HTTP 200 OK with the expected response body. We have also confirmed that the same behavior occurs when using the Get Transaction History API — it works correctly in the sandbox environment but returns 401 in production. Could you please confirm whether this behavior (receiving 401 instead of 404) is expected by design, or if it indicates a potential issue? If this is not the intended behavior, we would appreciate any guidance or instructions to resolve it. Thank you very much for your technical support. 「Get Transaction Info」APIを用いてトランザクションの検証を行ったところ、以下の問題が発生しました。 サンドボックス環境および本番環境の両方で検証を行い、次の結果を確認しています。 本番環境エンドポイント https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionId} に対して サンドボックス環境で生成された transactionId を使用すると、HTTP 401 Unauthorized が返却されます。 (一般的には、この場合 404 Not Found が返る想定であると理解しています。) 同一のJWTトークン を用いて サンドボックス環境のエンドポイント https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/{transactionId} を呼び出した場合は、HTTP 200 OK が返り、期待通りのレスポンスボディを受け取ることができています。 また、同様の挙動が Get Transaction History を使用した場合にも発生することを確認しています。 サンドボックス環境では正常に動作しますが、本番環境では401が返却されます。 この挙動(401が返却されること)は仕様上想定されたものか、または何らかの問題によるものかご確認をお願いいたします。 もし想定外の挙動である場合は、解決に向けたご案内をいただけますと幸いです。 本件について、技術的なサポートをお願いいたします。 よろしくお願いいたします。
2
0
290
Nov ’25
Mismatch between App Store Server API `expiresDate` (July 23) and iOS UI “Expires on” date (July 22) for 1-month subscription
Hi everyone, I’m seeing a consistent one-day discrepancy between the expiresDate returned by the App Store Server API and the “Expires on” date shown in the iOS Settings / App Store subscription list. I’d like to confirm whether this behavior is expected or if I’m misunderstanding the way Apple rounds dates. Reproduction steps Step Action Result 1 Purchase a 1-month auto-renewable subscription on 23 June 2025 14:00 JST (UTC+9) Transaction succeeds 2 Immediately fetch the transaction with GET /inApps/v1/subscriptions/{transactionId} Response contains "expiresDate": "2025-07-23T05:00:00Z" (= 23 July 2025 14:00 JST) 3 On the same device open Settings › Apple ID › Subscriptions (or App Store › Account › Subscriptions) UI shows Expires on: 22 July 2025 The same happens for every monthly renewal and on multiple devices. Region is Japan, device time zone Asia/Tokyo. What I understand so far (and my hypothesis) Apple’s docs say a monthly subscription renews “on the same calendar date” of the next month, so renewal in this example is 23 July. If the renewal is scheduled for 23 July at 14:00 JST, the subscription is fully usable until the end of 22 July in calendar terms, because the new billing period starts the moment the 23rd begins in Apple’s canonical time zone. Therefore, it might be intentional for the UI to display 22 July—i.e., “you can keep using it through the 22nd; on the 23rd it renews.” This hypothesis makes sense internally, yet it still looks confusing to end users who read “Expires on 22 July” and assume access ends at 00:00 on the 22nd, a whole day earlier than in reality. Questions Is showing the day before the renewal date the official/expected behavior? If so, could Apple clarify that the “Expires on” label represents the last full calendar day rather than the exact expiry timestamp? Which value should we surface in-app when telling users “Your subscription is valid until …”? The server’s expiresDate (precise to the second, converted to user time zone), or A UI-style date that’s one day earlier, matching Settings / App Store? Does Apple have a public document describing this rounding/visual convention? Have other developers encountered user confusion about the apparent 1-day “shortening” and, if so, how did you word your in-app messaging? Any insight from Apple engineers or fellow developers would be greatly appreciated. Thank you!
0
1
284
Jun ’25
Getting 401 Unauthenticated when calling StoreKit In-App API with JWT
Hello, I am trying to call the StoreKit In-App API, but I am consistently receiving a 401 Unauthenticated error. Here is what I have done so far: JWT creation (via https://jwt.io): Header: { "alg": "ES256", "kid": "**********", "typ": "JWT" } Payload: { "iss": "********-e662-43d2-be42-012d0138ce39", "aud": "appstoreconnect-v1", "iat": 1757389187, "exp": 1757390987 } Private Key (.p8): -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY----- Algorithm used: ES256 This generates the JWT successfully. API Call: I then include the JWT in the request header as follows: Authorization: Bearer ************ Endpoint: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/2000001003740262 Response: Status: 401 Unauthenticated Request ID: S3KCYHDVRMDKUT3TZVTY3QRRWM.0.0 Has anyone else faced this issue? Is there something incorrect with how I’m generating the JWT (e.g., iat/exp values, formatting, or encoding)? Do I need to generate separate keys for Sandbox and Production, or is the same key valid for both? Any guidance would be appreciated. Thanks in advance!
0
1
184
Sep ’25
Why Non-Consumable product has originalTransactionId?
I try to call Get Transaction Info from App Store Server API, and the transactionId is for a Non-consumable type product, but it is odd that there are so many different transactionId and they have a same originalTransactionId { "bundleId": "${bundleId}", "environment": "Production", "inAppOwnershipType": "PURCHASED", "originalPurchaseDate": 1691220528000, "originalTransactionId": "${originalTransactionId}", "productId": "${productId}", "purchaseDate": 1691220528000, "quantity": 1, "signedDate": 1692590989925, "storefront": "USA", "storefrontId": "143441", "transactionId": "${originalTransactionId}", "transactionReason": "PURCHASE", "type": "Non-Consumable" } the defination of Non-Consumable is can only purchase once for same apple account. But why there would have originalTransactionId?
3
0
1.2k
May ’25
Notification Received on Consumable Purchase
Hello, I am encountering an issue where I receive an App Store Server Notification V2 upon the purchase of a consumable item. I have configured the App Store Server Notification V2 endpoint to handle notifications related to subscription products. However, I did not expect to receive notifications for consumable purchases. The notification includes the following signedPayload decoded into the ResponseBodyV2DecodedPayload object with the following values: notificationUUID: 3cd6410b-0c89-4247-aba5-20710e79895e notificationType: null subtype: null The transaction information decoded from the ResponseBodyV2DecodedPayload object is as follows: transactionId: 2000000633622618 webOrderLineItemId: null productId: heart_2 To debug, I called the Get Notification History API of the App Store Server API, and the mentioned notification for the consumable product purchase is not included in the history. Only notifications related to subscription product purchases are retrieved. According to the notification type documentation, there is no explanation for cases where both notificationType and subtype are null, nor is there any mention of receiving notifications for consumable purchases. Therefore, I am uncertain how to interpret and handle this notification. Could you please provide an explanation or guidance on this issue? Thank you. References: https://developer.apple.com/forums/thread/737592 https://developer.apple.com/documentation/appstoreservernotifications/notificationtype
3
0
1.3k
May ’25
Resending notifications from Apple
Regarding App Store Server Notifications V2,we are currently using Notifications V2 in a production environment. It is set up so that if the server receives the notification successfully, it returns 200 after about 30 seconds, and if an error occurs, it returns 400 or 500. However, the notification is being resent multiple times from Apple's server, at 1 hour, 12 hours, and 24 hours. Is it necessary to return the notification using Apple's API?
2
0
149
Apr ’25
Apple Pay v2 (signedTransactionInfo) : how to verify new token format and migrate from legacy EC_v1?
I’m updating a legacy application that used Apple Pay v1 token format, and in my new revamped version I’m now receiving the newer Apple Pay v2 format. The old (v1) payload looked like this: php { "version": "EC_v1", "data": "...", "signature": "...", "header": { "ephemeralPublicKey": "...", "publicKeyHash": "...", "transactionId": "..." } } In the new revamp (v2), Apple Pay returns this instead: php { "signedTransactionInfo": "eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlF..." } From what I understand: v1 tokens were elliptic-curve encrypted JSON objects containing a header and signature. v2 tokens seem to be JWS (JSON Web Signature) strings using the ES256 algorithm, possibly containing transaction and subscription details inside. Questions Is there any official Apple documentation or migration note explaining the move from EC_v1 → signedTransactionInfo? How should I verify or decode the new signedTransactionInfo payload? Should the verification now use Apple’s public keys instead of the legacy Merchant ID certificate? Are there any example implementations or SDKs that can handle both v1 and v2 formats during migration? Is there a recommended way to maintain backward compatibility while transitioning existing users? Goal Ensure that my revamped app can handle Apple Pay v2 tokens securely while keeping the legacy v1 integration functional until all users are migrated.
1
0
503
Feb ’26
Requesting Code-Level Support: Node.js Script to Fetch US Education Apps with "Exam Prep" by Revenue
Hi Apple Developer Support, I’m working on a Node.js script to fetch all apps listed under the Education category and Reference subcategory from the US App Store, where the app name includes "exam prep". My goal is to list these apps in descending order of their earned revenue (including both paid apps and those with subscriptions). To proceed, I’m looking for guidance or code-level support on: Accessing App Store metadata programmatically via Apple-approved APIs. Filtering apps by category, subcategory, and keywords in the app name. Sorting the result set by revenue (paid and subscription earnings). Is there any recommended API or service (official or via App Store Connect) that I should be using to achieve this? Appreciate any direction, documentation, or sample code that can help. Thanks in advance!
0
0
139
Apr ’25
App Store Server API JWT Authentication Issue
Issue Description I am experiencing persistent 401 Unauthorized errors when attempting to access the App Store Server API using JWT authentication. Despite following Apple's documentation and regenerating keys, I am unable to successfully authenticate. Implementation Details I'm implementing JWT authentication for the App Store Server API to retrieve transaction information from the following endpoint: https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionID} My JWT generation code (in PHP/Laravel) follows Apple's documentation: php$kid = '6W6H649LJ4'; $header = [ "alg" => "ES256", "kid" => $kid, "typ" => "JWT" ]; $iss = 'b8d99de7-b43b-4cbb-aada-546ec784e249'; // App Store Connect API Key Issuer ID $bid = 'com.gitiho.learnCourse'; // Bundle ID $payload = [ "iss" => $iss, "iat" => time(), "exp" => time() + 3600, "aud" => "appstoreconnect-v1", "bid" => $bid ]; $pathFileAuthKeyP8 = "AuthKey_6W6H649LJ4.p8"; $contentFileAuthKey = \File::get(base_path($pathFileAuthKeyP8)); $alg = "ES256"; $jwt = \Firebase\JWT\JWT::encode($payload, $contentFileAuthKey, $alg, null, $header); Steps Taken to Troubleshoot Verified that the Issuer ID is correct and in UUID format Confirmed that the Key ID matches the private key filename Regenerated the key with proper App Store Server API permissions Ensured the private key file is properly formatted with correct headers and footers Verified that the JWT is being properly encoded using the ES256 algorithm Confirmed the bundle ID is correct for our application Checked that the API endpoint URL is correct Additional Information This implementation previously worked correctly We started experiencing 401 errors recently without changing our implementation We are using the Firebase JWT library for PHP to encode the JWT Request Could you please help identify what might be causing these authentication failures? Is there any recent change in the authentication requirements or endpoint URLs that might be affecting our integration? Thanks for support me.
0
0
107
Apr ’25
StoreKit 2: jwsRepresentation Validation, Rate-Limit Relief, and Send Consumption Info Effectiveness
Hi everyone, We operate an online game where all in-app assets are stored server-side and require a logged-in account (no device binding). I’d like guidance on four areas: Do we really need deviceVerification / deviceVerificationNonce? – Because every purchase is tied to an account and we enforce a global transactionId UNIQUE constraint, replay or cross-account reuse appears infeasible. Under these conditions, is omitting device verification acceptable, or are there situations where Apple still recommends it? Permanent rate-limit increase for the App Store Server API – During anniversary events we saw bursts of ~18 000 requests per hour, breaching the current hourly cap on the App Store Server API (verifyTransaction, getNotificationHistory, etc.). Is there a formal process to request a long-term rate-limit expansion (or an alternative tier) from Apple? When is an App Store Server API call required for a StoreKit 2 jwsRepresentation? Docs say “call the API if you’re unsure,” but there’s no clear cut-off. Because we fully validate the JWS signature plus the entire certificate chain (including CRL/OCSP checks) on our server, local cryptographic validation seems sufficient for consumables. For subscriptions we still plan to hit the API to fetch the latest status. Does this separation match Apple’s best practice? If Apple does recommend hitting the API for consumables as well, we’d like a concrete rule of thumb—e.g. “if the item price is USD 50 or higher, always use the API.” Is establishing such thresholds consistent with Apple’s intent? Refund-risk reduction from Send Consumption Info – Adapty reports a 40–60 % refund-rate drop for subscriptions when using Send Consumption Info (blog reference). Can we expect similar reduction for consumable IAP in social/online games? Any real-world results would be helpful. Thanks in advance for any guidance!
0
0
197
Apr ’25
In-App Purchase Products Not Fetching via Unity IAP in TestFlight Builds
We are experiencing an issue with our iOS TestFlight builds where in-app purchase (IAP) products are not being retrieved as expected. We are using Unity IAP to handle our purchases, and despite having all the products correctly configured and approved in App Store Connect, we consistently receive errors such as: UnityIAP: Received 0 products Unavailable product [product_id] We have thoroughly verified that: The product identifiers are correctly configured in App Store Connect. The bundle ID mappings are correctly set on both Unity and our backend. The same setup works on the live App Store build, where purchases are fetched and validated correctly for the same set of In App products. Sandbox test accounts are being used during TestFlight testing. This issue only started appearing recently and affects the TestFlight builds only. Note: My App ID and Product ID are correct, the IAP is live on the App Store, and the product is recognized in sandbox. Looking forward to your support on this matter.
Replies
4
Boosts
16
Views
960
Activity
May ’25
Cancel subscription not working in TestFlight
Hi, I have deployed my app on Test Flight, I have two subscriptions, monthly and yearly. User can have one of them at a time and upgrade, downgrade to the other. Upgrade, downgrade, cancel from the Apple Settings worked fine in the sandbox environment when testing locally. Now when I have deployed the app on TestFlight, I was able to purchase the subscription successfully from my app. Now when I want to cancel my subscription from the Apple Settings it gives me the following error after confirming cancellation, 'Your request is temporarily unable to be processed. Please try again later.' Also the other subscription offer (yearly) is also not shown to which I could upgrade, even though in the sandbox I was able to upgrade downgrade from the settings. Another thing I have noticed is that the app Icon or name is not shown anywhere in settings with the subscription. Instead of app icon only empty square is shown. Even though app icon shows fine everywhere else. Can someone please help me figure out this issue?
Replies
22
Boosts
15
Views
4.5k
Activity
Oct ’25
Transaction ID Misassociation in IAP Subscription API
Dear Apple Support Team, Hello! I am currently developing the in-app subscription functionality using Apple IAP API and have encountered a serious technical issue while processing subscription data. I would like to report this issue to you. Issue Description: When calling the subscription API endpoint, the same OriginalTransactionId returns inconsistent results. Specifically, a particular transaction ID (let's call it TransactionId_A) should belong to the subscription order with OriginalTransactionId_A, but it is currently incorrectly associated with OriginalTransactionId_B. This issue severely affects our ability to accurately manage and process subscription data. Here are the relevant log details for your reference: API Endpoint Requested: https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{TransactionId_A} (Note: The link is a placeholder for the actual API endpoint.) Log Information on February 21, 2025, at 09:40:09: { "AppAccountToken": "{AppAccountToken}", "BundleId": "{BundleId}", "Currency": "CNY", "Environment": "Production", "ExpiresDate": {ExpiresDate}, "InAppOwnershipType": "PURCHASED", "IsUpgraded": false, "OfferDiscountType": "", "OfferIdentifier": "", "OfferType": 0, "OriginalPurchaseDate": {OriginalPurchaseDate}, "OriginalTransactionId": "{OriginalTransactionId_A}", "Price": {Price}, "ProductId": "{ProductId}", "PurchaseDate": {PurchaseDate}, "Quantity": 1, "RevocationDate": 0, "RevocationReason": 0, "SignedDate": {SignedDate}, "Storefront": "CHN", "StorefrontId": {StorefrontId}, "SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}", "TransactionId": "{TransactionId_A}", "TransactionReason": "PURCHASE", "Type": "Auto-Renewable Subscription", "WebOrderLineItemId": "{WebOrderLineItemId}" } Log Information on March 21, 2025, at 09:38:49: { "AppAccountToken": "{AppAccountToken}", "BundleId": "{BundleId}", "Currency": "CNY", "Environment": "Production", "ExpiresDate": {ExpiresDate}, "InAppOwnershipType": "PURCHASED", "IsUpgraded": false, "OfferDiscountType": "", "OfferIdentifier": "", "OfferType": 0, "OriginalPurchaseDate": {OriginalPurchaseDate}, "OriginalTransactionId": "{OriginalTransactionId_B}", "Price": {Price}, "ProductId": "{ProductId}", "PurchaseDate": {PurchaseDate}, "Quantity": 1, "RevocationDate": 0, "RevocationReason": 0, "SignedDate": {SignedDate}, "Storefront": "CHN", "StorefrontId": {StorefrontId}, "SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}", "TransactionId": "{TransactionId_A}", "TransactionReason": "PURCHASE", "Type": "Auto-Renewable Subscription", "WebOrderLineItemId": "{WebOrderLineItemId}" } From the above logs, it is evident that the same transaction (TransactionId_A) returns different OriginalTransactionId values at different times, which is clearly not expected and severely impacts our ability to correctly process and manage subscription data. I hope you can address and investigate this issue as soon as possible. If you need any further information or assistance, please feel free to contact me. Thank you for your support! Best regards!
Replies
6
Boosts
4
Views
1.1k
Activity
Apr ’25
When will ONE_TIME_CHARGE notify type be available in a production environment?
https://developer.apple.com/documentation/appstoreservernotifications/app-store-server-notifications-changelog#June-10-2024 ONE_TIME_CHARGE notify type running in a sandbox environment for almost a year, the feature is not yet available for production environment. The notification is already available in Google subscriptions. Our services often miss orders because of the absence of this notification. Can you give us an approximate time range?
Replies
2
Boosts
3
Views
520
Activity
May ’25
StoreKit appAccountToken Not Preserved During Apple ID Email Migration
I'm encountering an issue with the App Store Server API where the appAccountToken is not preserved when users migrate their Apple ID email addresses. I've submitted Feedback Assistant ticket FB18709241 but wanted to check if anyone else has experienced this and get community input on best practices. The Issue When a user migrates their Apple ID from one email to another (e.g., from olduser@example.com to newuser@icloud.com), the App Store creates a new subscription transaction with a different originalTransactionId, but the appAccountToken is not carried forward from the original transaction. What I'm Seeing note: these values are fake When querying /inApps/v1/subscriptions/{originalTransactionId} with the either post-migration transaction ID or the pre-migration transaction ID, the API returns both transactions: Pre-migration transaction (status: 2 - inactive): originalTransactionId: "12345678910111" Contains: "appAccountToken": "abc123-def456-ghi789" Post-migration transaction (status: 1 - active): originalTransactionId: "67891011121314" Missing: appAccountToken entirely The Problem The appAccountToken is our only way to link App Store subscriptions to user accounts. Without it on the new transaction: Users lose access to premium features despite having valid subscriptions Server-side renewal notifications can't be matched to user accounts Manual support intervention is required for each affected user Questions for the Community Has anyone else encountered this issue with Apple ID migrations? What's the recommended approach for handling this scenario? Is there an alternative mechanism to maintain the subscription-to-user linkage across migrations? Questions for Apple Engineers Is this the expected behavior, or should the appAccountToken be preserved? Are there any planned improvements to handle this migration scenario? What's the best practice for developers to handle this case? Interestingly, both the old and new transaction IDs return the same JSON response from the App Store Server API, suggesting Apple maintains internal linkage between these transactions, but the appAccountToken isn't carried forward to the active transaction. Any insights or similar experiences would be greatly appreciated! Thank you!! Feedback Assistant: FB18709241
Replies
0
Boosts
3
Views
196
Activity
Jul ’25
Apple Server Notifications Webhooks stopped retrying on HTTP 400
Hey We have noticed a change in the retry behavior of Apple Server Notifications webhooks V2 starting around March 12–13, 2026. Previously, when our webhook endpoint returned an HTTP 400 response, Apple would retry the notification delivery multiple times according to the documented retry policy. However, beginning around March 12–13, it appears that Apple no longer retries the webhook when a 400 response is returned. The notification is sent only once and no further retry attempts are made. From our understanding of the documentation, retries should occur when delivery fails, and historically we observed retries even for some 4xx responses. We would like to confirm: Has Apple recently changed the retry behavior for Server Notifications? Are HTTP 4xx responses (specifically 400) now considered terminal failures that will not trigger retries? Is this change intentional or related to a rollout in the webhook delivery system? We have called the "Notification History" endpoint for some users who purchased a sub and we are only getting one attempt with the following data in it: { attemptDate: 1773469202552, (2026-03-14T06:20:02.552Z) sendAttemptResult: 'UNSUCCESSFUL_HTTP_RESPONSE_CODE', } This was 2 days ago, based on the docs, the user should have a few attempts at least. This behavior change affects systems that rely on retries to handle temporary validation issues or transient failures. Thanks!
Replies
3
Boosts
2
Views
170
Activity
1w
App Store Server Notifications and API Client - Toggling Sandbox vs Production Environment
The documentation mentions the following: Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code. This approach ensures you don’t have to switch between URLs while your app is in testing, in review by App Review, or live in the App Store. This way, you can use one server environment to handle both Sandbox and Production environments. It is necessary to pass App Review. However, I'm not manually hitting these URLs - I'm using Apple's libraries. Specifically, the environment is used in SignedDataVerifier and AppStoreServerAPIClient. (I can't link to these because, for some reason, the domain apple.github.io is not allowed. The documentation for these is only found there. You can find it quickly by searching these terms and the domain.) Here is how SignedDataVerifier is being used: const verifier = new SignedDataVerifier( appleRootCertificates, APPLE_ENABLE_ONLINE_CHECKS, APPLE_ENVIRONMENT, APPLE_BUNDLE_ID, APPLE_APP_ID ) const verifiedNotification: ResponseBodyV2DecodedPayload = await verifier.verifyAndDecodeNotification(signedPayload) if (!verifiedNotification) { // Failure return } Here is how AppStoreServerAPIClient is being used: const appStoreServerAPIClient = new AppStoreServerAPIClient( SIGNING_KEY, APPLE_IAP_KEY_ID, APPLE_IAP_ISSUER_ID, APPLE_BUNDLE_ID, APPLE_ENVIRONMENT ) const statusResponse: StatusResponse = await appStoreServerAPIClient.getAllSubscriptionStatuses(originalTransactionId, [Status.ACTIVE]) In the source code for SignedDataVerifier.verifyAndDecodeNotification, I can see that it throws a VerificationException(VerificationStatus.INVALID_ENVIRONMENT) error . So for SignedDataVerifier is it as simple as wrapping my code in a try/catch and checking that the error's status code is 21007? I'm unsure about this because if you scroll to the bottom of the linked source code file, you can see the enumeration VerificationStatus, but it's unclear if this member has a value of 21007. The source code for AppStoreServerAPIClient only says that it throws an APIException if a response could not be processed, so I'm not too sure about how to handle this one.
Replies
2
Boosts
2
Views
964
Activity
Sep ’25
85% of Subscriptions are in Billing Retry State
One of our apps has 85% stuck in Billing Retry -- We are so confused. All the users are from the US, and have a one-week free trial. We had 1,000 subscriptions expire from this issue. So any help would be so appreciated.
Replies
2
Boosts
2
Views
221
Activity
Jan ’26
URGENT: Severe Performance Issue with App Store Connect API (In-App Purchases Retrieval)
Hello Apple Support Team, We are currently experiencing a critical business issue caused by a sudden performance degradation in the App Store Connect API. This problem is blocking key parts of our production systems at wappier Optimizing game performance - website: https://wappier.com/ Since October 15, requests to the following endpoint have been taking extremely long to complete when fetching more than approximately 200 in-app purchase items. In many cases, these requests never complete even after several hours, making it impossible for us to retrieve all required data. Endpoint: https://api.appstoreconnect.apple.com/v1/apps/1252850847/inAppPurchasesV2 Parameters: { "include": "appStoreReviewScreenshot,inAppPurchaseLocalizations", "cursor": "Jd6I", "limit": "200" } We confirm that: This behavior started suddenly on October 15. No changes were made on our end. We found no corresponding updates or API change announcements in your release notes. Requests for fewer than 200 in-app products continue to perform normally. This issue is blocking our operations, as our systems depend on timely responses from this endpoint for in-app purchase data synchronization. We kindly ask your team to investigate this issue urgently and provide us guidance, and if possible, revert any recent change introduced around October 15 that could have impacted this endpoint’s performance. Thank you very much for your prompt attention and support. wappier Dev Team
Replies
0
Boosts
2
Views
207
Activity
Oct ’25
Unexpected 401 Unauthorized response from production endpoint when using sandbox transactionId with Get Transaction Info API
We have encountered an issue when verifying transactions using the Get Transaction Info API. We tested the behavior in both the sandbox and production environments and observed the following results. When calling the production endpoint: https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionId} with a transactionId generated in the sandbox environment, the API returns HTTP 401 Unauthorized. However, based on the documentation and common understanding, we expected HTTP 404 Not Found in this case. Using the same JWT token, if we call the sandbox endpoint: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/{transactionId}, we receive HTTP 200 OK with the expected response body. We have also confirmed that the same behavior occurs when using the Get Transaction History API — it works correctly in the sandbox environment but returns 401 in production. Could you please confirm whether this behavior (receiving 401 instead of 404) is expected by design, or if it indicates a potential issue? If this is not the intended behavior, we would appreciate any guidance or instructions to resolve it. Thank you very much for your technical support. 「Get Transaction Info」APIを用いてトランザクションの検証を行ったところ、以下の問題が発生しました。 サンドボックス環境および本番環境の両方で検証を行い、次の結果を確認しています。 本番環境エンドポイント https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionId} に対して サンドボックス環境で生成された transactionId を使用すると、HTTP 401 Unauthorized が返却されます。 (一般的には、この場合 404 Not Found が返る想定であると理解しています。) 同一のJWTトークン を用いて サンドボックス環境のエンドポイント https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/{transactionId} を呼び出した場合は、HTTP 200 OK が返り、期待通りのレスポンスボディを受け取ることができています。 また、同様の挙動が Get Transaction History を使用した場合にも発生することを確認しています。 サンドボックス環境では正常に動作しますが、本番環境では401が返却されます。 この挙動(401が返却されること)は仕様上想定されたものか、または何らかの問題によるものかご確認をお願いいたします。 もし想定外の挙動である場合は、解決に向けたご案内をいただけますと幸いです。 本件について、技術的なサポートをお願いいたします。 よろしくお願いいたします。
Replies
2
Boosts
0
Views
290
Activity
Nov ’25
Mismatch between App Store Server API `expiresDate` (July 23) and iOS UI “Expires on” date (July 22) for 1-month subscription
Hi everyone, I’m seeing a consistent one-day discrepancy between the expiresDate returned by the App Store Server API and the “Expires on” date shown in the iOS Settings / App Store subscription list. I’d like to confirm whether this behavior is expected or if I’m misunderstanding the way Apple rounds dates. Reproduction steps Step Action Result 1 Purchase a 1-month auto-renewable subscription on 23 June 2025 14:00 JST (UTC+9) Transaction succeeds 2 Immediately fetch the transaction with GET /inApps/v1/subscriptions/{transactionId} Response contains "expiresDate": "2025-07-23T05:00:00Z" (= 23 July 2025 14:00 JST) 3 On the same device open Settings › Apple ID › Subscriptions (or App Store › Account › Subscriptions) UI shows Expires on: 22 July 2025 The same happens for every monthly renewal and on multiple devices. Region is Japan, device time zone Asia/Tokyo. What I understand so far (and my hypothesis) Apple’s docs say a monthly subscription renews “on the same calendar date” of the next month, so renewal in this example is 23 July. If the renewal is scheduled for 23 July at 14:00 JST, the subscription is fully usable until the end of 22 July in calendar terms, because the new billing period starts the moment the 23rd begins in Apple’s canonical time zone. Therefore, it might be intentional for the UI to display 22 July—i.e., “you can keep using it through the 22nd; on the 23rd it renews.” This hypothesis makes sense internally, yet it still looks confusing to end users who read “Expires on 22 July” and assume access ends at 00:00 on the 22nd, a whole day earlier than in reality. Questions Is showing the day before the renewal date the official/expected behavior? If so, could Apple clarify that the “Expires on” label represents the last full calendar day rather than the exact expiry timestamp? Which value should we surface in-app when telling users “Your subscription is valid until …”? The server’s expiresDate (precise to the second, converted to user time zone), or A UI-style date that’s one day earlier, matching Settings / App Store? Does Apple have a public document describing this rounding/visual convention? Have other developers encountered user confusion about the apparent 1-day “shortening” and, if so, how did you word your in-app messaging? Any insight from Apple engineers or fellow developers would be greatly appreciated. Thank you!
Replies
0
Boosts
1
Views
284
Activity
Jun ’25
Getting 401 Unauthenticated when calling StoreKit In-App API with JWT
Hello, I am trying to call the StoreKit In-App API, but I am consistently receiving a 401 Unauthenticated error. Here is what I have done so far: JWT creation (via https://jwt.io): Header: { "alg": "ES256", "kid": "**********", "typ": "JWT" } Payload: { "iss": "********-e662-43d2-be42-012d0138ce39", "aud": "appstoreconnect-v1", "iat": 1757389187, "exp": 1757390987 } Private Key (.p8): -----BEGIN PRIVATE KEY----- -----END PRIVATE KEY----- Algorithm used: ES256 This generates the JWT successfully. API Call: I then include the JWT in the request header as follows: Authorization: Bearer ************ Endpoint: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/2000001003740262 Response: Status: 401 Unauthenticated Request ID: S3KCYHDVRMDKUT3TZVTY3QRRWM.0.0 Has anyone else faced this issue? Is there something incorrect with how I’m generating the JWT (e.g., iat/exp values, formatting, or encoding)? Do I need to generate separate keys for Sandbox and Production, or is the same key valid for both? Any guidance would be appreciated. Thanks in advance!
Replies
0
Boosts
1
Views
184
Activity
Sep ’25
How to identify free trial subscription transaction
In the verifyReceipt API response, there is a "is_trial_period" field. As detailed in WWDC 2023 the verifyReceipt is deprecated, how to fetch the fact that the subscription is during the free trial period via recommended App Store server APIs?
Replies
5
Boosts
0
Views
2.8k
Activity
Dec ’25
Why Non-Consumable product has originalTransactionId?
I try to call Get Transaction Info from App Store Server API, and the transactionId is for a Non-consumable type product, but it is odd that there are so many different transactionId and they have a same originalTransactionId { "bundleId": "${bundleId}", "environment": "Production", "inAppOwnershipType": "PURCHASED", "originalPurchaseDate": 1691220528000, "originalTransactionId": "${originalTransactionId}", "productId": "${productId}", "purchaseDate": 1691220528000, "quantity": 1, "signedDate": 1692590989925, "storefront": "USA", "storefrontId": "143441", "transactionId": "${originalTransactionId}", "transactionReason": "PURCHASE", "type": "Non-Consumable" } the defination of Non-Consumable is can only purchase once for same apple account. But why there would have originalTransactionId?
Replies
3
Boosts
0
Views
1.2k
Activity
May ’25
Notification Received on Consumable Purchase
Hello, I am encountering an issue where I receive an App Store Server Notification V2 upon the purchase of a consumable item. I have configured the App Store Server Notification V2 endpoint to handle notifications related to subscription products. However, I did not expect to receive notifications for consumable purchases. The notification includes the following signedPayload decoded into the ResponseBodyV2DecodedPayload object with the following values: notificationUUID: 3cd6410b-0c89-4247-aba5-20710e79895e notificationType: null subtype: null The transaction information decoded from the ResponseBodyV2DecodedPayload object is as follows: transactionId: 2000000633622618 webOrderLineItemId: null productId: heart_2 To debug, I called the Get Notification History API of the App Store Server API, and the mentioned notification for the consumable product purchase is not included in the history. Only notifications related to subscription product purchases are retrieved. According to the notification type documentation, there is no explanation for cases where both notificationType and subtype are null, nor is there any mention of receiving notifications for consumable purchases. Therefore, I am uncertain how to interpret and handle this notification. Could you please provide an explanation or guidance on this issue? Thank you. References: https://developer.apple.com/forums/thread/737592 https://developer.apple.com/documentation/appstoreservernotifications/notificationtype
Replies
3
Boosts
0
Views
1.3k
Activity
May ’25
Resending notifications from Apple
Regarding App Store Server Notifications V2,we are currently using Notifications V2 in a production environment. It is set up so that if the server receives the notification successfully, it returns 200 after about 30 seconds, and if an error occurs, it returns 400 or 500. However, the notification is being resent multiple times from Apple's server, at 1 hour, 12 hours, and 24 hours. Is it necessary to return the notification using Apple's API?
Replies
2
Boosts
0
Views
149
Activity
Apr ’25
Apple Pay v2 (signedTransactionInfo) : how to verify new token format and migrate from legacy EC_v1?
I’m updating a legacy application that used Apple Pay v1 token format, and in my new revamped version I’m now receiving the newer Apple Pay v2 format. The old (v1) payload looked like this: php { "version": "EC_v1", "data": "...", "signature": "...", "header": { "ephemeralPublicKey": "...", "publicKeyHash": "...", "transactionId": "..." } } In the new revamp (v2), Apple Pay returns this instead: php { "signedTransactionInfo": "eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlF..." } From what I understand: v1 tokens were elliptic-curve encrypted JSON objects containing a header and signature. v2 tokens seem to be JWS (JSON Web Signature) strings using the ES256 algorithm, possibly containing transaction and subscription details inside. Questions Is there any official Apple documentation or migration note explaining the move from EC_v1 → signedTransactionInfo? How should I verify or decode the new signedTransactionInfo payload? Should the verification now use Apple’s public keys instead of the legacy Merchant ID certificate? Are there any example implementations or SDKs that can handle both v1 and v2 formats during migration? Is there a recommended way to maintain backward compatibility while transitioning existing users? Goal Ensure that my revamped app can handle Apple Pay v2 tokens securely while keeping the legacy v1 integration functional until all users are migrated.
Replies
1
Boosts
0
Views
503
Activity
Feb ’26
Requesting Code-Level Support: Node.js Script to Fetch US Education Apps with "Exam Prep" by Revenue
Hi Apple Developer Support, I’m working on a Node.js script to fetch all apps listed under the Education category and Reference subcategory from the US App Store, where the app name includes "exam prep". My goal is to list these apps in descending order of their earned revenue (including both paid apps and those with subscriptions). To proceed, I’m looking for guidance or code-level support on: Accessing App Store metadata programmatically via Apple-approved APIs. Filtering apps by category, subcategory, and keywords in the app name. Sorting the result set by revenue (paid and subscription earnings). Is there any recommended API or service (official or via App Store Connect) that I should be using to achieve this? Appreciate any direction, documentation, or sample code that can help. Thanks in advance!
Replies
0
Boosts
0
Views
139
Activity
Apr ’25
App Store Server API JWT Authentication Issue
Issue Description I am experiencing persistent 401 Unauthorized errors when attempting to access the App Store Server API using JWT authentication. Despite following Apple's documentation and regenerating keys, I am unable to successfully authenticate. Implementation Details I'm implementing JWT authentication for the App Store Server API to retrieve transaction information from the following endpoint: https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionID} My JWT generation code (in PHP/Laravel) follows Apple's documentation: php$kid = '6W6H649LJ4'; $header = [ "alg" => "ES256", "kid" => $kid, "typ" => "JWT" ]; $iss = 'b8d99de7-b43b-4cbb-aada-546ec784e249'; // App Store Connect API Key Issuer ID $bid = 'com.gitiho.learnCourse'; // Bundle ID $payload = [ "iss" => $iss, "iat" => time(), "exp" => time() + 3600, "aud" => "appstoreconnect-v1", "bid" => $bid ]; $pathFileAuthKeyP8 = "AuthKey_6W6H649LJ4.p8"; $contentFileAuthKey = \File::get(base_path($pathFileAuthKeyP8)); $alg = "ES256"; $jwt = \Firebase\JWT\JWT::encode($payload, $contentFileAuthKey, $alg, null, $header); Steps Taken to Troubleshoot Verified that the Issuer ID is correct and in UUID format Confirmed that the Key ID matches the private key filename Regenerated the key with proper App Store Server API permissions Ensured the private key file is properly formatted with correct headers and footers Verified that the JWT is being properly encoded using the ES256 algorithm Confirmed the bundle ID is correct for our application Checked that the API endpoint URL is correct Additional Information This implementation previously worked correctly We started experiencing 401 errors recently without changing our implementation We are using the Firebase JWT library for PHP to encode the JWT Request Could you please help identify what might be causing these authentication failures? Is there any recent change in the authentication requirements or endpoint URLs that might be affecting our integration? Thanks for support me.
Replies
0
Boosts
0
Views
107
Activity
Apr ’25
StoreKit 2: jwsRepresentation Validation, Rate-Limit Relief, and Send Consumption Info Effectiveness
Hi everyone, We operate an online game where all in-app assets are stored server-side and require a logged-in account (no device binding). I’d like guidance on four areas: Do we really need deviceVerification / deviceVerificationNonce? – Because every purchase is tied to an account and we enforce a global transactionId UNIQUE constraint, replay or cross-account reuse appears infeasible. Under these conditions, is omitting device verification acceptable, or are there situations where Apple still recommends it? Permanent rate-limit increase for the App Store Server API – During anniversary events we saw bursts of ~18 000 requests per hour, breaching the current hourly cap on the App Store Server API (verifyTransaction, getNotificationHistory, etc.). Is there a formal process to request a long-term rate-limit expansion (or an alternative tier) from Apple? When is an App Store Server API call required for a StoreKit 2 jwsRepresentation? Docs say “call the API if you’re unsure,” but there’s no clear cut-off. Because we fully validate the JWS signature plus the entire certificate chain (including CRL/OCSP checks) on our server, local cryptographic validation seems sufficient for consumables. For subscriptions we still plan to hit the API to fetch the latest status. Does this separation match Apple’s best practice? If Apple does recommend hitting the API for consumables as well, we’d like a concrete rule of thumb—e.g. “if the item price is USD 50 or higher, always use the API.” Is establishing such thresholds consistent with Apple’s intent? Refund-risk reduction from Send Consumption Info – Adapty reports a 40–60 % refund-rate drop for subscriptions when using Send Consumption Info (blog reference). Can we expect similar reduction for consumable IAP in social/online games? Any real-world results would be helpful. Thanks in advance for any guidance!
Replies
0
Boosts
0
Views
197
Activity
Apr ’25