StoreKit

RSS for tag

Support in-app purchases and interactions with the App Store using StoreKit.

StoreKit Documentation

Posts under StoreKit subtopic

Post

Replies

Boosts

Views

Activity

In-App Purchase Resources
General: Forums topic: StoreKit Forums tag: In-App Purchase App Store Pathway Simple and safe In-App Purchases Auto-renewable subscriptions In-App Purchase documentation Getting started with In-App Purchase using StoreKit views documentation Supporting business model changes by using the app transaction documentation Testing at all stages of development with Xcode and the sandbox documentation App Store Server Notifications documentation App Store Server API documentation Simplifying your implementation by using the App Store Server Library documentation TN3185: Troubleshooting In-App Purchases availability in Xcode technote TN3186: Troubleshooting In-App Purchases availability in the sandbox technote TN3188: Troubleshooting In-App Purchases availability in the App Store technote Understanding StoreKit workflows sample code Implementing a store in your app using the StoreKit API sample code What’s new in StoreKit and In-App Purchase video
0
0
2.3k
Jun ’26
StoreKit 2 returns no products for a non-renewing subscription in TestFlight Sandbox (China mainland)
I’m testing the first in-app purchase for an iOS app. It is a non-renewing subscription that grants 12 months of access. On November 9, a physical iPhone running our TestFlight build reproduced the same issue twice in the China mainland Sandbox storefront. Setup checked at the time The annual product was Ready to Submit in App Store Connect, with China mainland availability, a CNY 98 price, and a Simplified Chinese localization. The annual product identifier matched the identifier requested by the app. The explicit Bundle ID matched App Store Connect and had In-App Purchase enabled. The Paid Apps Agreement was active, and banking and tax records were in place. We used a mainland-China Sandbox tester and called the native StoreKit 2 Product.products(for:) API. The request included the configured annual product and an old monthly identifier that has no corresponding product in App Store Connect. Steps and results Install the app from TestFlight on a physical iPhone and open the purchase screen in Sandbox. Refresh the available products. We expect the annual product and its localized price to appear. Product.products(for:) completes with an empty array. Device logs show an HTTP 200 response from the China mainland Sandbox catalog followed by Ignoring empty product response. After the 600-second cache lifetime, the query received a different server correlation key and still returned no products. This occurs during product lookup, before any purchase call. TN3186 says that Sandbox testing can take place before submission for review. Has anyone reproduced this specifically with a non-renewing subscription? Is there another way to verify Sandbox catalog visibility for the configured annual product or diagnose why it is omitted? An annual-only StoreKit query would be a useful follow-up test. We can share the exact app and product identifiers, request correlation keys, and device diagnostics with Apple through Feedback Assistant.
0
0
11
22m
Question About StoreKit Request Rate Limits and Capacity
Hello, We are looking for information about the capacity limits for requests sent directly to the App Store through the StoreKit SDK when clients make in-app purchases. In our expected usage, we anticipate a peak request volume of approximately 30 transactions per second (TPS) through this communication path. Does anyone know if Apple imposes any rate limits or maximum request processing limits on requests sent directly to the App Store via the StoreKit SDK? If such limits exist, it would be helpful if you could share any details about the applicable thresholds. Thank you!
0
0
72
11h
StoreKit 2 – AppStore.sync() fails with StoreKitError.unknown (code 2) in TestFlight**
Subject: StoreKit 2 – AppStore.sync() fails with StoreKitError.unknown (code 2) in TestFlight Hello Apple Developer forum We are investigating a reproducible issue with StoreKit 2's AppStore.sync() in our iOS application, Elins Nystan. Environment App: Elins Nystan Bundle Identifier: poworg.ElinsNystan-2 TestFlight version: 1.43 (build 8) Device: iPhone 16 Date: November 10, 2026 Environment: TestFlight / App Store sandbox StoreKit: StoreKit 2 Problem The app correctly recognizes an existing subscription and grants Premium access to the account associated with the original purchase. Premium remains active after restarting the application, and subscription-dependent functionality works correctly. However, when the user selects “Restore Purchases,” the app calls AppStore.sync(). An Apple account authentication dialog appears and the user enters their password. After approximately 26 seconds, AppStore.sync() throws an error. Captured device logs All timestamps below are UTC: 2026-11-10 21:33:10 — restore.started 2026-11-10 21:33:10 — restore.syncStarted 2026-11-10 21:33:36 — restore.syncFailed Error details: Domain: StoreKit.StoreKitError Code: 2 Classification: unknownThe three log events share the same operation identifier. The app reports that Restore could not be completed due to an unknown error. Additional observations Premium was active before Restore. Previous testing confirmed that Premium remained active after a failed Restore. No corresponding backend reconciliation request was observed during an earlier Restore failure. No confirmed application-side cancellation or overlapping Restore request has been identified. AppStore.sync() has been part of the Restore implementation since December 2025. We have not identified a source-code regression that explains the StoreKit error. We have not verified a previously successful Restore under equivalent TestFlight conditions. We are not attempting to change subscription ownership or bypass purchase verification. Questions What conditions can cause AppStore.sync() to throw StoreKitError.unknown (code 2) in TestFlight? Could this be related to the sandbox Apple Account, authentication, or an existing subscription with multiple renewal transactions? Are there additional StoreKit or system diagnostics that would help identify the underlying cause? Is there a recommended way to recover from this error while preserving the existing verified subscription entitlement? Is this a known TestFlight/sandbox issue, or should we investigate a specific application configuration? We can provide redacted device logs and additional technical details if required. Thank you for your assistance.
0
0
36
15h
Subscriptions load in TestFlight sandbox but not during App Review — 2.1(b), third rejection
Our first submission has now been rejected under Guideline 2.1(b), with the message: "the in-app purchases do not load successfully." Each review was performed on an iPad Air 11-inch (M3) running iPadOS 26.6. The app sells only auto-renewable subscriptions. We cannot reproduce the failure, and we have verified every part of the configuration we can think of. WHAT WE VERIFIED (via the App Store Connect API, not just the UI) Two subscriptions in one group, state READY_TO_SUBMIT Product IDs exactly match what the app requests Available in 175 territories, including the United States Prices set, en-US localizations present for both products and for the group App review screenshots attached to both, state COMPLETE Both subscriptions are included in the review submission (READY_FOR_REVIEW) Paid Apps Agreement: Active. Bank account: Active. Tax forms: Active. WHAT WORKS On our own devices, installed via TestFlight (sandbox environment), the products load correctly and a purchase completes and activates as expected. This works on both a real Apple ID and a Sandbox Tester account. WHAT WE OBSERVED FROM THE REVIEW SESSION We use RevenueCat. Their server-side API returns our offering with both packages and the correct product identifiers, so the offering metadata is fine. Our backend also shows that the reviewer's session reached our servers and signed in successfully at the review timestamp, so the device had working network connectivity. That leaves StoreKit itself returning no products on the reviewer's device, which is what empties the offering. QUESTIONS Are there known conditions under which StoreKit returns no products in the App Review sandbox for subscriptions that are in "Ready to Submit" and are attached to the same submission as the binary? For an app that has never been approved, is product loading during review handled differently from a normal sandbox session on a released app? Is there any way to obtain diagnostics from a review session, or to ask the reviewer for a screenshot of the failing screen? Replies in Resolution Center so far have only repeated the original rejection text. Is there anything specific to iPadOS 26.6 that could affect StoreKit 2 product lookups? For the next submission we have added a timeout and automatic retries around the product lookup, plus a visible retry control instead of a spinner, in case the failure is a transient cold-start timeout. But we would rather understand the actual cause than keep guessing. Any pointers appreciated.
2
1
510
20h
Sandbox IAP: AuthKit succeeds, then AMSServerErrorDomain -5000 (cancel-purchase-batch)
Every sandbox purchase of our auto-renewable subscriptions cancels right after AuthKit sign-in succeeds. It's blocking our 1.0 release. Filed as FB25469063, no reply yet. Capacitor iOS app, bundle io.xrplive.app, 1.0.0 (TestFlight), products io.xrplive.app.pro.monthly / .yearly, iPhone 17 Pro Max on iOS 27.0.1, StoreKit via @capgo/native-purchases. Console on every attempt: (1) AMSAuthKitUpdateTask: "The AuthKit authentication succeeded." (2) Then: Error Domain=AMSServerErrorDomain Code=-5000 UserInfo={failureType=-5000, m-allowed=false, cancel-purchase-batch=true, customerMessage=Check the account information you entered and try again.} Also AMSErrorDomain Code=100 (Authentication Failed), Code=2 ("Password reuse not available for account"), and a 401 from sandbox.itunes.apple.com/commerce/messages/app/inbox. We already fixed a purchase(confirmIn:) presentation issue. This failure is in sandbox verification after a successful sign-in, which we can't fix from the client. Is -5000 with cancel-purchase-batch a known sandbox account or commerce issue? Is there a sandbox tester or storefront state that fixes it when AuthKit succeeds but verification still fails?
0
0
31
23h
StoreKit 2 returns USD product metadata in TestFlight while the storefront is FRA/EUR
Hello, We would appreciate some guidance regarding an unexpected StoreKit currency result in a TestFlight build. Our iPhone language and region are both set to France. The Sandbox tester is also configured for France, and our subscription products have French availability and pricing configured in App Store Connect. In the TestFlight build we diagnosed, StoreKit reports the current storefront as France with EUR: storefront=FRA/143442/EUR However, all 10 subscription products are returned with USD product metadata: products=10/10 formatCurrencies=USD localeCurrencies=USD error=NONE Example: formatCurrency=USD locale=fr_US_currency_USD localeCurrency=USD display=1,99 $US price=1.99 We first observed this through Flutter's in_app_purchase integration. To determine whether the Flutter plugin was involved, we added a native StoreKit 2 diagnostic to the same TestFlight build. The native result was identical: receipt=sandboxReceipt storefront before=FRA/143442/EUR storefront after=FRA/143442/EUR products=10/10 formatCurrencies=USD localeCurrencies=USD error=NONE The issue appears specific to the TestFlight distribution. When the application is installed directly from the development computer, prices are returned in euros on the same device. We also tested with the regular Media & Purchases account signed out and a French Sandbox tester connected. Once the products loaded successfully, StoreKit still returned USD metadata. In another configuration, the application displayed the USD price while Apple's purchase sheet displayed the price in euros. We are using the price and formatting information returned directly by StoreKit. We do not want to infer the currency from the device region or perform a client-side currency conversion, because StoreKit should remain the authoritative source. Could you please help us understand: Is it expected for Storefront.current to report FRA/EUR while Product.priceFormatStyle.currencyCode, its locale currency, and Product.displayPrice use USD? Could a TestFlight or App Store Connect configuration cause product metadata to use a different currency from the current storefront? Is there another account, availability, pricing or distribution setting that we should verify? Is there a recommended way to refresh or invalidate the product metadata used by a TestFlight installation? We have already filed Feedback Assistant report FB24723329, which is currently under investigation. Thank you very much for any clarification or additional diagnostic steps you can suggest.
10
1
1.5k
1d
StoreKit returns USD prices instead of EUR in TestFlight, blocking app release (iOS 27.0.1)
We are experiencing the same issue with two independent native iOS apps on an iPhone running iOS 27.0.1, using TestFlight in France. Our annual subscription displays US$34.90 instead of €39.90, and our non-consumable purchase displays US$5.99 instead of €6.99. Both apps displayed the correct EUR prices during local Xcode testing. In TestFlight, Apple's native purchase sheets still show the correct EUR prices, and both purchases work successfully. We have contacted Apple Developer Support (case 103017935062). As this issue is delaying the time-sensitive release of our educational app, could Apple confirm whether a workaround is available or whether a fix is planned? https://developer.apple.com/forums/thread/845478 Thank you.
0
0
33
1d
First iOS App Stuck in Waiting for Review for Over 30 Days –– No Support Response
Hello Apple App Review Team, My first iOS app, Loopa – Video & Audio Editor (version 1.0.0), has been stuck in "Waiting for Review" for approximately 30 days. I have already contacted Apple Developer Support through the official contact form but have not received a response. Could an Apple representative please investigate whether my submission is progressing normally or whether additional information is required? I would appreciate any assistance. Thank you.
0
0
24
2d
All App Store Server Notifications V2 TIMED_OUT at creation time (Sandbox + Production), even to webhook.site - app transferred on 2 Oct
Since we configured App Store Server Notifications V2 on 15 October 2026, every notification for our app is recorded as TIMED_OUT, with the attemptDate equal to the signedDate (same second), and no HTTP request ever reaches our server. 35 Sandbox notifications (TEST, SUBSCRIBED, DID_RENEW, EXPIRED): one attempt each, TIMED_OUT. 2 Production TEST notifications: retried 5–6 times over a week, all TIMED_OUT. Our endpoint is public, TLS 1.3, valid certificate, answers in < 400 ms, and processes the signedPayload correctly when we POST it ourselves. Today we pointed the Sandbox URL to a webhook.site URL and requested a test notification: TIMED_OUT within 10 s, nothing received on webhook.site either. The app (com.virginactive.revolution, appAppleId 1620160868) was transferred to our current developer account on 2 October 2026; notifications have never been delivered under the new team, so we suspect a server-side state issue after the transfer. Latest test tokens: Sandbox: be12b40b-19a7-4723-aebf-764db83b4690_1793289992274 (29 Oct 2026 16:06 UTC) Production: 80597167-2939-4cc9-a43c-2c3c29c6a161_1792741270174 (23 Oct 2026 07:41 UTC) Feedback Assistant: FB25363489 Is there anything on our side that could make the App Store server fail before attempting the connection, or does this need to be fixed on Apple's side?
1
0
100
3d
Subscriptions suddenly stopped working in all my apps – StoreKit returns 0 products
Since November 5, in-app subscriptions have suddenly stopped working in all three of my apps on the App Store. Everything worked perfectly before, and no changes were made to the apps. The subscription purchase buttons no longer display prices, only a dash ("–"). Existing apps can still be downloaded normally. I reproduced the problem in Xcode on my own device. StoreKit reports: STOREKIT: Received 0 products STOREKIT: Invalid IDs = ( "TEE_year", "TEE_month", "TEE_week" ) All subscription products are still configured in App Store Connect, and the agreements appear to be active. Interestingly, the problem started around the time I accepted updated Apple agreements and changed my address in my developer account. I don't know whether this is related. Several customers have already independently reported the same problem, so this is not limited to my own device or Apple ID. I strongly suspect an App Store Connect or StoreKit backend issue rather than an app-specific programming error. I've contacted Apple Developer Support (case ID is 30000008123797) but haven't received a solution yet. Has anyone else experienced subscriptions suddenly becoming unavailable across multiple apps? Could this be related to updated agreements or account information?
0
0
78
3d
Free promotional offer for subscribers who stay within an in-app time limit
Our app, Unscroll, has an auto-renewable monthly subscription. Users set a daily time limit inside the app. We plan to give a monthly subscriber a free next month through a promotional offer (type: Free, duration: 1 month) when they stayed within their limit on at least 20 days of the current subscription period. Eligibility is computed on the device from the app's own measurement of time spent inside Unscroll. We do not use Screen Time, Family Controls or DeviceActivity data for it. Every paid feature stays available to every subscriber. The free month is an extra, and nothing depends on it. The offer is shown inside the app; notifications are not required. The full monthly price is shown first on the subscription screen, with the condition written next to it. Questions: Is this use of promotional offers acceptable under App Review Guidelines 3.1.1, 3.1.2 and 3.2.2(x)? Can the same customer redeem the same free promotional offer again in later periods (once per qualifying period)? For an active monthly subscriber, does a free promotional offer for the same product take effect at the next renewal date? Thank you.
0
0
52
4d
App Store Server API: originalTransactionId stability across expiration and resubscription
DTS recommended that we post this question in the Developer Forums. We would like clarification on the supported production behavior of originalTransactionId in the App Store Server API, particularly after a subscription expires and the customer resubscribes. Our main backend design question is: Can we continue using a stored originalTransactionId to identify and retrieve subsequent subscription activity within the same subscription group, or must we support discovering and associating new identifiers? Integration context Our backend uses: GET /inApps/v1/subscriptions/{transactionId} GET /inApps/v2/history/{transactionId} App and subscription details: Bundle ID: com.lgeha.nuts Subscription group identifier: 22350255 Product A: thinq_g_unlimitedpro Product B: thinq_g_single We use originalTransactionId as a key for subscription records and associate those records with user accounts in our service. We do not use it as an identifier for the Apple Account itself. Please assume the same Apple Account and app, with both products in the same subscription group, using ordinary auto-renewable subscriptions without a special subscription migration. This question concerns the identifiers and lookup behavior exposed to our backend by the App Store Server API. Sandbox observation and scope During sandbox testing, purchase history was cleared, and a new originalTransactionId was subsequently observed. We understand that this observation involved a sandbox history reset and does not establish production behavior. Our questions below concern production behavior without any purchase-history reset. Preservation across subscription lifecycle events For each scenario below, is originalTransactionId guaranteed to remain unchanged for subsequent transactions, or can Apple assign a different value? Automatic renewal of the same product. An upgrade, downgrade, or crossgrade between products A and B while the subscription is active. Turning off automatic renewal, then re-enabling it before expiration. Turning off automatic renewal, allowing the subscription to expire, and later resubscribing to the same product. Turning off automatic renewal for product A, allowing it to expire, and later subscribing to product B within the same subscription group. Scenarios 4 and 5 are our primary concern. We would like to distinguish commonly observed behavior from supported guarantees that a backend can rely on. Conditions for a new identifier after expiration For scenarios 4 and 5, can a new purchase legitimately receive a different originalTransactionId in production despite the Apple Account, app, and subscription group remaining unchanged? If so, what conditions determine this? Does it depend on: Time elapsed since expiration. Billing retry or billing grace-period status or history. Whether the purchase uses StoreKit 1 or StoreKit 2. Whether the customer resubscribes inside the app or through App Store subscription management. Our concern is whether these factors affect the identifiers subsequently returned by the App Store Server API. Stability of an existing transaction Separately from a new purchase receiving a new identifier, if the same transactionId is retrieved at two different times, is its associated originalTransactionId guaranteed to remain unchanged? Can an Apple-supported correction process change that association, or should such a result be treated as an inconsistency and reported through Feedback Assistant? This question concerns the same returned transactionId, rather than a different latest transaction returned by a subsequent status query. We have not confirmed such a change in production. Lookup behavior using a previously stored identifier If resubscription can create a new originalTransactionId, how does that affect each endpoint? For GET /inApps/v1/subscriptions/{transactionId}: Can a request using the previous originalTransactionId return the current status of a later resubscription with a different originalTransactionId, assuming the same Apple Account, app, and subscription group? Or must the backend obtain the new identifier separately? For GET /inApps/v2/history/{transactionId}: Can a request using the previous originalTransactionId return transactions from that later resubscription, assuming all applicable pages are retrieved and no filters exclude those transactions? Please clarify any endpoint-specific guarantees or limitations on using an older identifier to discover subsequent subscription activity. Backend account association If resubscription can create a new identifier, should our backend support multiple originalTransactionId values for one service user within the same subscription group? Is there a documented server-side relationship that links subscriptions with different originalTransactionId values? Alternatively, should that association rely on an application-managed identifier such as appAccountToken, where available? Please clarify any limitations, especially for resubscriptions initiated outside the app. Related discussions We reviewed these discussions as background: Transaction ID Misassociation in IAP Subscription API (https://developer.apple.com/forums/thread/777433) original_transaction_id associated to web_order_line_item_id of auto-renewable subscription changed (https://developer.apple.com/forums/thread/778301) We do not assume that these reports establish supported behavior or share the cause of our sandbox observation. Could Apple clarify the supported preservation or replacement rules, particularly after expiration and resubscription, and point us to documentation describing the behavior a backend can rely on? If investigating a specific inconsistency requires a separate Feedback Assistant report, please indicate which server-side request and response details should be included. Thank you.
1
0
430
5d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
0
0
67
6d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
0
0
41
6d
macOS StoreKit 2 purchase produces an Xcode test transaction when launched from Finder
I am trying to test a non-consumable in-app purchase in the Apple sandbox using a development-signed, sandboxed macOS app. The app is launched from Finder rather than from an Xcode scheme. A purchase attempt instead produces a transaction that my diagnostic build identifies as an Xcode test transaction. Environment macOS 27.1; Xcode 27.2 (27B52). StoreKit 2; native Swift code called by an Electron macOS app. The app has an Apple Development signature and a development provisioning profile that includes this Mac. The app uses a fixed app bundle ID and a non-consumable product ID configured in App Store Connect. What I observed After I removed the app’s existing test transaction in Xcode’s transaction manager, the diagnostic app found no current entitlement for the product. I attempted a purchase from the Finder-launched app. There was no Apple account login or purchase confirmation prompt. A new transaction appeared in Xcode’s transaction manager, and the app returned its own verificationFailed error. The diagnostic build later found a verified current entitlement for this product and app bundle whose Transaction.environment was .xcode. The app intentionally rejects Xcode test transactions for production entitlement access. I quit Xcode and launched the app again from Finder. After removing the app’s test transaction, the same result occurred on another purchase attempt. The app’s verificationFailed label is used both when StoreKit returns an unverified result and when my own transaction acceptance checks reject it. Therefore, that label alone does not prove that StoreKit signature verification failed. I have not confirmed an actual Apple sandbox purchase or restore. Earlier automated StoreKitTest work on this machine used the same app product identifier; the current tests use a separate test-only identifier. I do not know whether the earlier tests are related. I do not yet have a focused minimal reproduction project. The app checks the product ID, app bundle ID, non-consumable type, and revocation date; in builds without the test-only flag it also rejects .xcode transactions. Its diagnostics iterate Transaction.currentEntitlements and report .xcode only for a verified matching transaction. Questions What determines whether a development-signed macOS app launched outside Xcode uses Xcode StoreKit testing or the Apple sandbox? What non-destructive checks can identify any remaining Xcode/StoreKitTest configuration associated with this app or process, without deleting unrelated apps’ transactions or resetting shared test data? What is the recommended way to transition this app to an Apple sandbox account and confirm the transaction environment before testing purchase and restore? No account details, receipts, certificates, provisioning profiles, user files, or transaction identifiers are included. I can provide a focused reproduction or additional diagnostics if needed, after preparing them.
0
0
91
6d
Best practices for backend server transition timing to Production App Store Server API
Hello, I would like to clarify the best practices and timing for our backend server to transition its main connection to the production App Store Server API. Currently, we are considering the following approach: We plan to switch our backend’s primary API endpoint from Sandbox to Production once our app passes the App Store review and its status changes to "Ready for Sale." Could you please confirm if this timing is standard and correct? Additionally, to handle App Store reviews (which run in the Sandbox environment) and TestFlight tests seamlessly without manual configuration changes, we are planning to implement an automatic fallback mechanism: Our backend always requests the Production App Store Server API first. If it returns a "TransactionNotFound" (e.g., 4040010) error, the backend automatically retries the request using the Sandbox API. Is this automatic fallback from Production to Sandbox considered a safe and recommended practice by Apple, especially for App Store reviews and post-release testing? Any advice or insights on backend transition timing and fallback strategies would be highly appreciated. Thank you!
1
0
134
6d
Questions on App Store Server API behaviors: Production accounts in Sandbox, and Cleared Sandbox data
Hello, I would like to clarify the exact technical behavior of the App Store Server API (V2) and StoreKit under the following two specific scenarios: Case A (Production Account on Sandbox Endpoint): If a user with a production Apple Account attempts to purchase through a build pointing to the Apple Sandbox environment (or Sandbox API), how does the Apple server handle this transaction and its data lifecycle? (Does StoreKit block this at the client-side, or does the API return a specific error code?) Case B (Restoring Cleared Sandbox Data): If a Sandbox tester's purchase history is cleared/deleted on the Apple server, and the app subsequently requests a "Restore Purchase" or queries the App Store Server API using a previously valid transactionID from that account, what specific error code (such as 4040010 TransactionNotFound) or empty response does the Apple server return? I would highly appreciate your confirmation or any technical insights on these behaviors. Thank you!
2
0
312
6d
Is dynamic fallback to Sandbox API correct when receiving error 4040010 (TransactionIdNotFoundError) during App Review?
Hi, During the App Review process, a test purchase was made using what appeared to be a production Apple account. When our app server sent this transactionId to the Production App Store Server API, it returned the error code 4040010 (TransactionIdNotFoundError). To handle this gracefully and prevent review rejections, we are considering implementing a dynamic fallback mechanism on our app server. Specifically, when the Production API returns 4040010, the server will automatically retry the request using the Sandbox App Store Server API URL. Could you please clarify the following points regarding this design? Is it expected behavior for an App Review purchase to return 4040010 on the Production API, and can it be successfully verified by routing it to the Sandbox API? Is this dynamic fallback logic (Production API ➔ if 4040010 ➔ Sandbox API) a recommended and officially supported best practice for handling App Review and TestFlight transactions? Any confirmation or advice from Apple engineers or the community would be greatly appreciated.Thank you.
1
0
114
6d
StoreKit 2 assigned subscriptions: authenticating member enrollment into an application account
Our iPad application uses authenticated accounts in our own service. Before enabling access for a member receiving an assigned subscription, we need to establish that the actual assigned Apple member authorized enrollment into the intended account in our service. The unresolved case is another authenticated application account presenting forwarded, genuinely Apple-signed member transaction or app transaction evidence. We need to understand the supported verification boundary that prevents possession of that evidence from being sufficient to acquire another member's access. Personal purchase ownership will remain separate from assigned-member access. Proposed flow for review: The app obtains AppTransaction and the assigned Transaction directly from StoreKit and checks both against the current device using the documented device-verification procedure. It then proposes an App Attest assertion over the exact evidence and a server-issued challenge associated with the authenticated application account. The proposed client method accepts no forwarded JWS input. Our server would separately authenticate the service session and verify the attestation, assertion, Apple-signed evidence, current assignment and subscription lifecycle before granting access. Is this composition supported for authenticating assigned-member enrollment? Specifically, may the server rely on the direct StoreKit capture and local device checks within the attested app to establish that the same Apple member authorized the intended application-account association? What connects the StoreKit member/device verification, the App Attest key and the intended account, so that a valid assertion over forwarded authentic evidence would not be sufficient? Please identify the required server validation and trust assumptions, or an additional supported API/protocol if the proposal is insufficient. We also need to understand recovery after reinstall or an application-account switch, and the applicable Sandbox, TestFlight and Production support. Matching identifiers or a first successful claim must not transfer another member's access. What we have checked: The StoreKit deviceVerification documentation describes checking whether a transaction belongs to the device. The App Attest server-validation guide describes attestation, assertions, one-time challenges and per-user/device key association. We have not found an explicit assigned-member enrollment contract covering their composition. The closest existing discussions are "Scoping App Attest keys to an appTransactionID" and "Is keying off Storekit's AppTransactionID a valid pattern for storing keys?" They discuss key organization for anonymous users; they do not resolve this assigned-member enrollment question. This is an API and trust-contract clarification. A focused, newly authored sample was supplied privately to DTS. It contains no customer records, credentials, captured transaction evidence or production source. The sample was prepared using Xcode 27.0 on macOS 27.0.1 and targets iOS/iPadOS with the iOS 27 SDK. Swift syntax and project-file parsing passed, but it has not been compiled, signed, installed or device-tested. The default app displays the question; it invokes no StoreKit, App Attest, purchase, enrollment or network calls. We have not enabled assigned-member grants or claimed a reproduced Apple defect. References: https://developer.apple.com/documentation/storekit/transaction/deviceverification https://developer.apple.com/documentation/devicecheck/validating-apps-that-connect-to-your-server https://developer.apple.com/videos/play/wwdc2026/391/ https://developer.apple.com/documentation/appstoreserverapi/get-customer-groups https://developer.apple.com/forums/thread/833174 https://developer.apple.com/forums/thread/831468
1
0
330
6d
TestFlight says already subscribed, but app finds no entitlement; restore fails with error 14
My app, At My Table, has a subscription issue on one TestFlight device. Version: 1.0.0, Build 26 Library: expo-iap 6.4.1 Product: com.atmytable.premium.monthly Affected device: iPhone 15 Plus, iOS 27.0.1 Tapping Subscribe displays Apple’s “You’re currently subscribed” message. However, the app reports zero active subscriptions, no current entitlement, no latest transaction, and zero available purchases. Restore Purchases prompts for Apple sign-in and then fails with: service-error: The operation couldn’t be completed. (SKInternalErrorDomain error 14.) The error persists after restarting the phone and testing separately on Wi-Fi and cellular. Another tester’s iPhone 14 Pro Max, running the same iOS version and TestFlight build, recognizes its active membership and saves changes successfully. What diagnostics would help distinguish a sandbox account or device issue from an integration problem? I have screenshots but do not yet have a minimal native Xcode reproduction.
0
0
75
6d
In-App Purchase Resources
General: Forums topic: StoreKit Forums tag: In-App Purchase App Store Pathway Simple and safe In-App Purchases Auto-renewable subscriptions In-App Purchase documentation Getting started with In-App Purchase using StoreKit views documentation Supporting business model changes by using the app transaction documentation Testing at all stages of development with Xcode and the sandbox documentation App Store Server Notifications documentation App Store Server API documentation Simplifying your implementation by using the App Store Server Library documentation TN3185: Troubleshooting In-App Purchases availability in Xcode technote TN3186: Troubleshooting In-App Purchases availability in the sandbox technote TN3188: Troubleshooting In-App Purchases availability in the App Store technote Understanding StoreKit workflows sample code Implementing a store in your app using the StoreKit API sample code What’s new in StoreKit and In-App Purchase video
Replies
0
Boosts
0
Views
2.3k
Activity
Jun ’26
StoreKit 2 returns no products for a non-renewing subscription in TestFlight Sandbox (China mainland)
I’m testing the first in-app purchase for an iOS app. It is a non-renewing subscription that grants 12 months of access. On November 9, a physical iPhone running our TestFlight build reproduced the same issue twice in the China mainland Sandbox storefront. Setup checked at the time The annual product was Ready to Submit in App Store Connect, with China mainland availability, a CNY 98 price, and a Simplified Chinese localization. The annual product identifier matched the identifier requested by the app. The explicit Bundle ID matched App Store Connect and had In-App Purchase enabled. The Paid Apps Agreement was active, and banking and tax records were in place. We used a mainland-China Sandbox tester and called the native StoreKit 2 Product.products(for:) API. The request included the configured annual product and an old monthly identifier that has no corresponding product in App Store Connect. Steps and results Install the app from TestFlight on a physical iPhone and open the purchase screen in Sandbox. Refresh the available products. We expect the annual product and its localized price to appear. Product.products(for:) completes with an empty array. Device logs show an HTTP 200 response from the China mainland Sandbox catalog followed by Ignoring empty product response. After the 600-second cache lifetime, the query received a different server correlation key and still returned no products. This occurs during product lookup, before any purchase call. TN3186 says that Sandbox testing can take place before submission for review. Has anyone reproduced this specifically with a non-renewing subscription? Is there another way to verify Sandbox catalog visibility for the configured annual product or diagnose why it is omitted? An annual-only StoreKit query would be a useful follow-up test. We can share the exact app and product identifiers, request correlation keys, and device diagnostics with Apple through Feedback Assistant.
Replies
0
Boosts
0
Views
11
Activity
22m
Question About StoreKit Request Rate Limits and Capacity
Hello, We are looking for information about the capacity limits for requests sent directly to the App Store through the StoreKit SDK when clients make in-app purchases. In our expected usage, we anticipate a peak request volume of approximately 30 transactions per second (TPS) through this communication path. Does anyone know if Apple imposes any rate limits or maximum request processing limits on requests sent directly to the App Store via the StoreKit SDK? If such limits exist, it would be helpful if you could share any details about the applicable thresholds. Thank you!
Replies
0
Boosts
0
Views
72
Activity
11h
StoreKit 2 – AppStore.sync() fails with StoreKitError.unknown (code 2) in TestFlight**
Subject: StoreKit 2 – AppStore.sync() fails with StoreKitError.unknown (code 2) in TestFlight Hello Apple Developer forum We are investigating a reproducible issue with StoreKit 2's AppStore.sync() in our iOS application, Elins Nystan. Environment App: Elins Nystan Bundle Identifier: poworg.ElinsNystan-2 TestFlight version: 1.43 (build 8) Device: iPhone 16 Date: November 10, 2026 Environment: TestFlight / App Store sandbox StoreKit: StoreKit 2 Problem The app correctly recognizes an existing subscription and grants Premium access to the account associated with the original purchase. Premium remains active after restarting the application, and subscription-dependent functionality works correctly. However, when the user selects “Restore Purchases,” the app calls AppStore.sync(). An Apple account authentication dialog appears and the user enters their password. After approximately 26 seconds, AppStore.sync() throws an error. Captured device logs All timestamps below are UTC: 2026-11-10 21:33:10 — restore.started 2026-11-10 21:33:10 — restore.syncStarted 2026-11-10 21:33:36 — restore.syncFailed Error details: Domain: StoreKit.StoreKitError Code: 2 Classification: unknownThe three log events share the same operation identifier. The app reports that Restore could not be completed due to an unknown error. Additional observations Premium was active before Restore. Previous testing confirmed that Premium remained active after a failed Restore. No corresponding backend reconciliation request was observed during an earlier Restore failure. No confirmed application-side cancellation or overlapping Restore request has been identified. AppStore.sync() has been part of the Restore implementation since December 2025. We have not identified a source-code regression that explains the StoreKit error. We have not verified a previously successful Restore under equivalent TestFlight conditions. We are not attempting to change subscription ownership or bypass purchase verification. Questions What conditions can cause AppStore.sync() to throw StoreKitError.unknown (code 2) in TestFlight? Could this be related to the sandbox Apple Account, authentication, or an existing subscription with multiple renewal transactions? Are there additional StoreKit or system diagnostics that would help identify the underlying cause? Is there a recommended way to recover from this error while preserving the existing verified subscription entitlement? Is this a known TestFlight/sandbox issue, or should we investigate a specific application configuration? We can provide redacted device logs and additional technical details if required. Thank you for your assistance.
Replies
0
Boosts
0
Views
36
Activity
15h
Subscriptions load in TestFlight sandbox but not during App Review — 2.1(b), third rejection
Our first submission has now been rejected under Guideline 2.1(b), with the message: "the in-app purchases do not load successfully." Each review was performed on an iPad Air 11-inch (M3) running iPadOS 26.6. The app sells only auto-renewable subscriptions. We cannot reproduce the failure, and we have verified every part of the configuration we can think of. WHAT WE VERIFIED (via the App Store Connect API, not just the UI) Two subscriptions in one group, state READY_TO_SUBMIT Product IDs exactly match what the app requests Available in 175 territories, including the United States Prices set, en-US localizations present for both products and for the group App review screenshots attached to both, state COMPLETE Both subscriptions are included in the review submission (READY_FOR_REVIEW) Paid Apps Agreement: Active. Bank account: Active. Tax forms: Active. WHAT WORKS On our own devices, installed via TestFlight (sandbox environment), the products load correctly and a purchase completes and activates as expected. This works on both a real Apple ID and a Sandbox Tester account. WHAT WE OBSERVED FROM THE REVIEW SESSION We use RevenueCat. Their server-side API returns our offering with both packages and the correct product identifiers, so the offering metadata is fine. Our backend also shows that the reviewer's session reached our servers and signed in successfully at the review timestamp, so the device had working network connectivity. That leaves StoreKit itself returning no products on the reviewer's device, which is what empties the offering. QUESTIONS Are there known conditions under which StoreKit returns no products in the App Review sandbox for subscriptions that are in "Ready to Submit" and are attached to the same submission as the binary? For an app that has never been approved, is product loading during review handled differently from a normal sandbox session on a released app? Is there any way to obtain diagnostics from a review session, or to ask the reviewer for a screenshot of the failing screen? Replies in Resolution Center so far have only repeated the original rejection text. Is there anything specific to iPadOS 26.6 that could affect StoreKit 2 product lookups? For the next submission we have added a timeout and automatic retries around the product lookup, plus a visible retry control instead of a spinner, in case the failure is a transient cold-start timeout. But we would rather understand the actual cause than keep guessing. Any pointers appreciated.
Replies
2
Boosts
1
Views
510
Activity
20h
Sandbox IAP: AuthKit succeeds, then AMSServerErrorDomain -5000 (cancel-purchase-batch)
Every sandbox purchase of our auto-renewable subscriptions cancels right after AuthKit sign-in succeeds. It's blocking our 1.0 release. Filed as FB25469063, no reply yet. Capacitor iOS app, bundle io.xrplive.app, 1.0.0 (TestFlight), products io.xrplive.app.pro.monthly / .yearly, iPhone 17 Pro Max on iOS 27.0.1, StoreKit via @capgo/native-purchases. Console on every attempt: (1) AMSAuthKitUpdateTask: "The AuthKit authentication succeeded." (2) Then: Error Domain=AMSServerErrorDomain Code=-5000 UserInfo={failureType=-5000, m-allowed=false, cancel-purchase-batch=true, customerMessage=Check the account information you entered and try again.} Also AMSErrorDomain Code=100 (Authentication Failed), Code=2 ("Password reuse not available for account"), and a 401 from sandbox.itunes.apple.com/commerce/messages/app/inbox. We already fixed a purchase(confirmIn:) presentation issue. This failure is in sandbox verification after a successful sign-in, which we can't fix from the client. Is -5000 with cancel-purchase-batch a known sandbox account or commerce issue? Is there a sandbox tester or storefront state that fixes it when AuthKit succeeds but verification still fails?
Replies
0
Boosts
0
Views
31
Activity
23h
StoreKit 2 returns USD product metadata in TestFlight while the storefront is FRA/EUR
Hello, We would appreciate some guidance regarding an unexpected StoreKit currency result in a TestFlight build. Our iPhone language and region are both set to France. The Sandbox tester is also configured for France, and our subscription products have French availability and pricing configured in App Store Connect. In the TestFlight build we diagnosed, StoreKit reports the current storefront as France with EUR: storefront=FRA/143442/EUR However, all 10 subscription products are returned with USD product metadata: products=10/10 formatCurrencies=USD localeCurrencies=USD error=NONE Example: formatCurrency=USD locale=fr_US_currency_USD localeCurrency=USD display=1,99 $US price=1.99 We first observed this through Flutter's in_app_purchase integration. To determine whether the Flutter plugin was involved, we added a native StoreKit 2 diagnostic to the same TestFlight build. The native result was identical: receipt=sandboxReceipt storefront before=FRA/143442/EUR storefront after=FRA/143442/EUR products=10/10 formatCurrencies=USD localeCurrencies=USD error=NONE The issue appears specific to the TestFlight distribution. When the application is installed directly from the development computer, prices are returned in euros on the same device. We also tested with the regular Media & Purchases account signed out and a French Sandbox tester connected. Once the products loaded successfully, StoreKit still returned USD metadata. In another configuration, the application displayed the USD price while Apple's purchase sheet displayed the price in euros. We are using the price and formatting information returned directly by StoreKit. We do not want to infer the currency from the device region or perform a client-side currency conversion, because StoreKit should remain the authoritative source. Could you please help us understand: Is it expected for Storefront.current to report FRA/EUR while Product.priceFormatStyle.currencyCode, its locale currency, and Product.displayPrice use USD? Could a TestFlight or App Store Connect configuration cause product metadata to use a different currency from the current storefront? Is there another account, availability, pricing or distribution setting that we should verify? Is there a recommended way to refresh or invalidate the product metadata used by a TestFlight installation? We have already filed Feedback Assistant report FB24723329, which is currently under investigation. Thank you very much for any clarification or additional diagnostic steps you can suggest.
Replies
10
Boosts
1
Views
1.5k
Activity
1d
StoreKit returns USD prices instead of EUR in TestFlight, blocking app release (iOS 27.0.1)
We are experiencing the same issue with two independent native iOS apps on an iPhone running iOS 27.0.1, using TestFlight in France. Our annual subscription displays US$34.90 instead of €39.90, and our non-consumable purchase displays US$5.99 instead of €6.99. Both apps displayed the correct EUR prices during local Xcode testing. In TestFlight, Apple's native purchase sheets still show the correct EUR prices, and both purchases work successfully. We have contacted Apple Developer Support (case 103017935062). As this issue is delaying the time-sensitive release of our educational app, could Apple confirm whether a workaround is available or whether a fix is planned? https://developer.apple.com/forums/thread/845478 Thank you.
Replies
0
Boosts
0
Views
33
Activity
1d
First iOS App Stuck in Waiting for Review for Over 30 Days –– No Support Response
Hello Apple App Review Team, My first iOS app, Loopa – Video & Audio Editor (version 1.0.0), has been stuck in "Waiting for Review" for approximately 30 days. I have already contacted Apple Developer Support through the official contact form but have not received a response. Could an Apple representative please investigate whether my submission is progressing normally or whether additional information is required? I would appreciate any assistance. Thank you.
Replies
0
Boosts
0
Views
24
Activity
2d
All App Store Server Notifications V2 TIMED_OUT at creation time (Sandbox + Production), even to webhook.site - app transferred on 2 Oct
Since we configured App Store Server Notifications V2 on 15 October 2026, every notification for our app is recorded as TIMED_OUT, with the attemptDate equal to the signedDate (same second), and no HTTP request ever reaches our server. 35 Sandbox notifications (TEST, SUBSCRIBED, DID_RENEW, EXPIRED): one attempt each, TIMED_OUT. 2 Production TEST notifications: retried 5–6 times over a week, all TIMED_OUT. Our endpoint is public, TLS 1.3, valid certificate, answers in < 400 ms, and processes the signedPayload correctly when we POST it ourselves. Today we pointed the Sandbox URL to a webhook.site URL and requested a test notification: TIMED_OUT within 10 s, nothing received on webhook.site either. The app (com.virginactive.revolution, appAppleId 1620160868) was transferred to our current developer account on 2 October 2026; notifications have never been delivered under the new team, so we suspect a server-side state issue after the transfer. Latest test tokens: Sandbox: be12b40b-19a7-4723-aebf-764db83b4690_1793289992274 (29 Oct 2026 16:06 UTC) Production: 80597167-2939-4cc9-a43c-2c3c29c6a161_1792741270174 (23 Oct 2026 07:41 UTC) Feedback Assistant: FB25363489 Is there anything on our side that could make the App Store server fail before attempting the connection, or does this need to be fixed on Apple's side?
Replies
1
Boosts
0
Views
100
Activity
3d
Subscriptions suddenly stopped working in all my apps – StoreKit returns 0 products
Since November 5, in-app subscriptions have suddenly stopped working in all three of my apps on the App Store. Everything worked perfectly before, and no changes were made to the apps. The subscription purchase buttons no longer display prices, only a dash ("–"). Existing apps can still be downloaded normally. I reproduced the problem in Xcode on my own device. StoreKit reports: STOREKIT: Received 0 products STOREKIT: Invalid IDs = ( "TEE_year", "TEE_month", "TEE_week" ) All subscription products are still configured in App Store Connect, and the agreements appear to be active. Interestingly, the problem started around the time I accepted updated Apple agreements and changed my address in my developer account. I don't know whether this is related. Several customers have already independently reported the same problem, so this is not limited to my own device or Apple ID. I strongly suspect an App Store Connect or StoreKit backend issue rather than an app-specific programming error. I've contacted Apple Developer Support (case ID is 30000008123797) but haven't received a solution yet. Has anyone else experienced subscriptions suddenly becoming unavailable across multiple apps? Could this be related to updated agreements or account information?
Replies
0
Boosts
0
Views
78
Activity
3d
Free promotional offer for subscribers who stay within an in-app time limit
Our app, Unscroll, has an auto-renewable monthly subscription. Users set a daily time limit inside the app. We plan to give a monthly subscriber a free next month through a promotional offer (type: Free, duration: 1 month) when they stayed within their limit on at least 20 days of the current subscription period. Eligibility is computed on the device from the app's own measurement of time spent inside Unscroll. We do not use Screen Time, Family Controls or DeviceActivity data for it. Every paid feature stays available to every subscriber. The free month is an extra, and nothing depends on it. The offer is shown inside the app; notifications are not required. The full monthly price is shown first on the subscription screen, with the condition written next to it. Questions: Is this use of promotional offers acceptable under App Review Guidelines 3.1.1, 3.1.2 and 3.2.2(x)? Can the same customer redeem the same free promotional offer again in later periods (once per qualifying period)? For an active monthly subscriber, does a free promotional offer for the same product take effect at the next renewal date? Thank you.
Replies
0
Boosts
0
Views
52
Activity
4d
App Store Server API: originalTransactionId stability across expiration and resubscription
DTS recommended that we post this question in the Developer Forums. We would like clarification on the supported production behavior of originalTransactionId in the App Store Server API, particularly after a subscription expires and the customer resubscribes. Our main backend design question is: Can we continue using a stored originalTransactionId to identify and retrieve subsequent subscription activity within the same subscription group, or must we support discovering and associating new identifiers? Integration context Our backend uses: GET /inApps/v1/subscriptions/{transactionId} GET /inApps/v2/history/{transactionId} App and subscription details: Bundle ID: com.lgeha.nuts Subscription group identifier: 22350255 Product A: thinq_g_unlimitedpro Product B: thinq_g_single We use originalTransactionId as a key for subscription records and associate those records with user accounts in our service. We do not use it as an identifier for the Apple Account itself. Please assume the same Apple Account and app, with both products in the same subscription group, using ordinary auto-renewable subscriptions without a special subscription migration. This question concerns the identifiers and lookup behavior exposed to our backend by the App Store Server API. Sandbox observation and scope During sandbox testing, purchase history was cleared, and a new originalTransactionId was subsequently observed. We understand that this observation involved a sandbox history reset and does not establish production behavior. Our questions below concern production behavior without any purchase-history reset. Preservation across subscription lifecycle events For each scenario below, is originalTransactionId guaranteed to remain unchanged for subsequent transactions, or can Apple assign a different value? Automatic renewal of the same product. An upgrade, downgrade, or crossgrade between products A and B while the subscription is active. Turning off automatic renewal, then re-enabling it before expiration. Turning off automatic renewal, allowing the subscription to expire, and later resubscribing to the same product. Turning off automatic renewal for product A, allowing it to expire, and later subscribing to product B within the same subscription group. Scenarios 4 and 5 are our primary concern. We would like to distinguish commonly observed behavior from supported guarantees that a backend can rely on. Conditions for a new identifier after expiration For scenarios 4 and 5, can a new purchase legitimately receive a different originalTransactionId in production despite the Apple Account, app, and subscription group remaining unchanged? If so, what conditions determine this? Does it depend on: Time elapsed since expiration. Billing retry or billing grace-period status or history. Whether the purchase uses StoreKit 1 or StoreKit 2. Whether the customer resubscribes inside the app or through App Store subscription management. Our concern is whether these factors affect the identifiers subsequently returned by the App Store Server API. Stability of an existing transaction Separately from a new purchase receiving a new identifier, if the same transactionId is retrieved at two different times, is its associated originalTransactionId guaranteed to remain unchanged? Can an Apple-supported correction process change that association, or should such a result be treated as an inconsistency and reported through Feedback Assistant? This question concerns the same returned transactionId, rather than a different latest transaction returned by a subsequent status query. We have not confirmed such a change in production. Lookup behavior using a previously stored identifier If resubscription can create a new originalTransactionId, how does that affect each endpoint? For GET /inApps/v1/subscriptions/{transactionId}: Can a request using the previous originalTransactionId return the current status of a later resubscription with a different originalTransactionId, assuming the same Apple Account, app, and subscription group? Or must the backend obtain the new identifier separately? For GET /inApps/v2/history/{transactionId}: Can a request using the previous originalTransactionId return transactions from that later resubscription, assuming all applicable pages are retrieved and no filters exclude those transactions? Please clarify any endpoint-specific guarantees or limitations on using an older identifier to discover subsequent subscription activity. Backend account association If resubscription can create a new identifier, should our backend support multiple originalTransactionId values for one service user within the same subscription group? Is there a documented server-side relationship that links subscriptions with different originalTransactionId values? Alternatively, should that association rely on an application-managed identifier such as appAccountToken, where available? Please clarify any limitations, especially for resubscriptions initiated outside the app. Related discussions We reviewed these discussions as background: Transaction ID Misassociation in IAP Subscription API (https://developer.apple.com/forums/thread/777433) original_transaction_id associated to web_order_line_item_id of auto-renewable subscription changed (https://developer.apple.com/forums/thread/778301) We do not assume that these reports establish supported behavior or share the cause of our sandbox observation. Could Apple clarify the supported preservation or replacement rules, particularly after expiration and resubscription, and point us to documentation describing the behavior a backend can rely on? If investigating a specific inconsistency requires a separate Feedback Assistant report, please indicate which server-side request and response details should be included. Thank you.
Replies
1
Boosts
0
Views
430
Activity
5d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
Replies
0
Boosts
0
Views
67
Activity
6d
StoreKit 2 returns USA/USD in TestFlight but DEU/EUR in local Release build on the same device
Hi everyone, We are currently preparing the release of our Flutter-based iOS application and are experiencing an unusual StoreKit 2 storefront issue that only occurs when the app is installed through TestFlight. The problem When our application is installed through TestFlight, StoreKit 2 consistently returns the United States storefront (USA), and all six auto-renewable subscription products are displayed with USD prices. However, both the regular Apple Account and the Sandbox Apple Account are configured for Germany. We have verified the following: All six subscription products are correctly configured in App Store Connect with EUR prices for Germany. The subscriptions are available in Germany, Austria, and Switzerland. We created a completely new Sandbox tester with Germany selected during account creation, using an email address that had never previously been used for sandbox testing. The issue occurs on two different physical devices (iPhone and iPad). No local StoreKit configuration file is used. Our application does not override the storefront, modify localized prices, or contain any hardcoded USD fallback. Controlled comparison We performed additional tests using the same application code on the same iPhone. The results were: Installation method Storefront Currency Local Debug build via Xcode/Flutter DEU EUR Local development-signed Release build via Flutter DEU EUR TestFlight Release build USA USD The locally installed Release build successfully retrieves all six subscription products with their correct German prices. For example, StoreKit returns the following values for one of our subscriptions: Local Release build: Storefront.current.countryCode = DEU Product currencyCode = EUR Product.displayPrice = 6,99 € TestFlight build: Storefront.current.countryCode = USA Product currencyCode = USD Both builds use the same StoreKit 2 integration and product identifiers. Technical environment Framework: Flutter StoreKit integration: StoreKit 2 Flutter plugin: in_app_purchase_storekit 0.4.11+2 Devices: Physical iPhone and iPad iOS/iPadOS: 26.6.2 Subscription products: Six auto-renewable subscriptions Expected storefront: Germany (DEU) Actual TestFlight storefront: United States (USA) We have traced the storefront country code directly to StoreKit 2’s Storefront.current.countryCode and the localized prices to the product information returned by Product.products(for:). There is no application-level storefront override or price conversion. Questions Why would StoreKit 2 return a different storefront in TestFlight compared with a locally installed development-signed Release build on the same physical device? Could TestFlight use a different sandbox storefront or Apple Account context than a locally installed build? Is there a recommended way to diagnose or reset the storefront association used by TestFlight? Has anyone experienced similar behavior where TestFlight consistently returns USA despite using a German Apple Account and newly created German sandbox testers? We have already contacted Apple Developer Support and followed their recommendation to create a completely new German sandbox tester, but the issue persists. Any guidance from Apple engineers or developers who have encountered similar behavior would be greatly appreciated. Thank you!
Replies
0
Boosts
0
Views
41
Activity
6d
macOS StoreKit 2 purchase produces an Xcode test transaction when launched from Finder
I am trying to test a non-consumable in-app purchase in the Apple sandbox using a development-signed, sandboxed macOS app. The app is launched from Finder rather than from an Xcode scheme. A purchase attempt instead produces a transaction that my diagnostic build identifies as an Xcode test transaction. Environment macOS 27.1; Xcode 27.2 (27B52). StoreKit 2; native Swift code called by an Electron macOS app. The app has an Apple Development signature and a development provisioning profile that includes this Mac. The app uses a fixed app bundle ID and a non-consumable product ID configured in App Store Connect. What I observed After I removed the app’s existing test transaction in Xcode’s transaction manager, the diagnostic app found no current entitlement for the product. I attempted a purchase from the Finder-launched app. There was no Apple account login or purchase confirmation prompt. A new transaction appeared in Xcode’s transaction manager, and the app returned its own verificationFailed error. The diagnostic build later found a verified current entitlement for this product and app bundle whose Transaction.environment was .xcode. The app intentionally rejects Xcode test transactions for production entitlement access. I quit Xcode and launched the app again from Finder. After removing the app’s test transaction, the same result occurred on another purchase attempt. The app’s verificationFailed label is used both when StoreKit returns an unverified result and when my own transaction acceptance checks reject it. Therefore, that label alone does not prove that StoreKit signature verification failed. I have not confirmed an actual Apple sandbox purchase or restore. Earlier automated StoreKitTest work on this machine used the same app product identifier; the current tests use a separate test-only identifier. I do not know whether the earlier tests are related. I do not yet have a focused minimal reproduction project. The app checks the product ID, app bundle ID, non-consumable type, and revocation date; in builds without the test-only flag it also rejects .xcode transactions. Its diagnostics iterate Transaction.currentEntitlements and report .xcode only for a verified matching transaction. Questions What determines whether a development-signed macOS app launched outside Xcode uses Xcode StoreKit testing or the Apple sandbox? What non-destructive checks can identify any remaining Xcode/StoreKitTest configuration associated with this app or process, without deleting unrelated apps’ transactions or resetting shared test data? What is the recommended way to transition this app to an Apple sandbox account and confirm the transaction environment before testing purchase and restore? No account details, receipts, certificates, provisioning profiles, user files, or transaction identifiers are included. I can provide a focused reproduction or additional diagnostics if needed, after preparing them.
Replies
0
Boosts
0
Views
91
Activity
6d
Best practices for backend server transition timing to Production App Store Server API
Hello, I would like to clarify the best practices and timing for our backend server to transition its main connection to the production App Store Server API. Currently, we are considering the following approach: We plan to switch our backend’s primary API endpoint from Sandbox to Production once our app passes the App Store review and its status changes to "Ready for Sale." Could you please confirm if this timing is standard and correct? Additionally, to handle App Store reviews (which run in the Sandbox environment) and TestFlight tests seamlessly without manual configuration changes, we are planning to implement an automatic fallback mechanism: Our backend always requests the Production App Store Server API first. If it returns a "TransactionNotFound" (e.g., 4040010) error, the backend automatically retries the request using the Sandbox API. Is this automatic fallback from Production to Sandbox considered a safe and recommended practice by Apple, especially for App Store reviews and post-release testing? Any advice or insights on backend transition timing and fallback strategies would be highly appreciated. Thank you!
Replies
1
Boosts
0
Views
134
Activity
6d
Questions on App Store Server API behaviors: Production accounts in Sandbox, and Cleared Sandbox data
Hello, I would like to clarify the exact technical behavior of the App Store Server API (V2) and StoreKit under the following two specific scenarios: Case A (Production Account on Sandbox Endpoint): If a user with a production Apple Account attempts to purchase through a build pointing to the Apple Sandbox environment (or Sandbox API), how does the Apple server handle this transaction and its data lifecycle? (Does StoreKit block this at the client-side, or does the API return a specific error code?) Case B (Restoring Cleared Sandbox Data): If a Sandbox tester's purchase history is cleared/deleted on the Apple server, and the app subsequently requests a "Restore Purchase" or queries the App Store Server API using a previously valid transactionID from that account, what specific error code (such as 4040010 TransactionNotFound) or empty response does the Apple server return? I would highly appreciate your confirmation or any technical insights on these behaviors. Thank you!
Replies
2
Boosts
0
Views
312
Activity
6d
Is dynamic fallback to Sandbox API correct when receiving error 4040010 (TransactionIdNotFoundError) during App Review?
Hi, During the App Review process, a test purchase was made using what appeared to be a production Apple account. When our app server sent this transactionId to the Production App Store Server API, it returned the error code 4040010 (TransactionIdNotFoundError). To handle this gracefully and prevent review rejections, we are considering implementing a dynamic fallback mechanism on our app server. Specifically, when the Production API returns 4040010, the server will automatically retry the request using the Sandbox App Store Server API URL. Could you please clarify the following points regarding this design? Is it expected behavior for an App Review purchase to return 4040010 on the Production API, and can it be successfully verified by routing it to the Sandbox API? Is this dynamic fallback logic (Production API ➔ if 4040010 ➔ Sandbox API) a recommended and officially supported best practice for handling App Review and TestFlight transactions? Any confirmation or advice from Apple engineers or the community would be greatly appreciated.Thank you.
Replies
1
Boosts
0
Views
114
Activity
6d
StoreKit 2 assigned subscriptions: authenticating member enrollment into an application account
Our iPad application uses authenticated accounts in our own service. Before enabling access for a member receiving an assigned subscription, we need to establish that the actual assigned Apple member authorized enrollment into the intended account in our service. The unresolved case is another authenticated application account presenting forwarded, genuinely Apple-signed member transaction or app transaction evidence. We need to understand the supported verification boundary that prevents possession of that evidence from being sufficient to acquire another member's access. Personal purchase ownership will remain separate from assigned-member access. Proposed flow for review: The app obtains AppTransaction and the assigned Transaction directly from StoreKit and checks both against the current device using the documented device-verification procedure. It then proposes an App Attest assertion over the exact evidence and a server-issued challenge associated with the authenticated application account. The proposed client method accepts no forwarded JWS input. Our server would separately authenticate the service session and verify the attestation, assertion, Apple-signed evidence, current assignment and subscription lifecycle before granting access. Is this composition supported for authenticating assigned-member enrollment? Specifically, may the server rely on the direct StoreKit capture and local device checks within the attested app to establish that the same Apple member authorized the intended application-account association? What connects the StoreKit member/device verification, the App Attest key and the intended account, so that a valid assertion over forwarded authentic evidence would not be sufficient? Please identify the required server validation and trust assumptions, or an additional supported API/protocol if the proposal is insufficient. We also need to understand recovery after reinstall or an application-account switch, and the applicable Sandbox, TestFlight and Production support. Matching identifiers or a first successful claim must not transfer another member's access. What we have checked: The StoreKit deviceVerification documentation describes checking whether a transaction belongs to the device. The App Attest server-validation guide describes attestation, assertions, one-time challenges and per-user/device key association. We have not found an explicit assigned-member enrollment contract covering their composition. The closest existing discussions are "Scoping App Attest keys to an appTransactionID" and "Is keying off Storekit's AppTransactionID a valid pattern for storing keys?" They discuss key organization for anonymous users; they do not resolve this assigned-member enrollment question. This is an API and trust-contract clarification. A focused, newly authored sample was supplied privately to DTS. It contains no customer records, credentials, captured transaction evidence or production source. The sample was prepared using Xcode 27.0 on macOS 27.0.1 and targets iOS/iPadOS with the iOS 27 SDK. Swift syntax and project-file parsing passed, but it has not been compiled, signed, installed or device-tested. The default app displays the question; it invokes no StoreKit, App Attest, purchase, enrollment or network calls. We have not enabled assigned-member grants or claimed a reproduced Apple defect. References: https://developer.apple.com/documentation/storekit/transaction/deviceverification https://developer.apple.com/documentation/devicecheck/validating-apps-that-connect-to-your-server https://developer.apple.com/videos/play/wwdc2026/391/ https://developer.apple.com/documentation/appstoreserverapi/get-customer-groups https://developer.apple.com/forums/thread/833174 https://developer.apple.com/forums/thread/831468
Replies
1
Boosts
0
Views
330
Activity
6d
TestFlight says already subscribed, but app finds no entitlement; restore fails with error 14
My app, At My Table, has a subscription issue on one TestFlight device. Version: 1.0.0, Build 26 Library: expo-iap 6.4.1 Product: com.atmytable.premium.monthly Affected device: iPhone 15 Plus, iOS 27.0.1 Tapping Subscribe displays Apple’s “You’re currently subscribed” message. However, the app reports zero active subscriptions, no current entitlement, no latest transaction, and zero available purchases. Restore Purchases prompts for Apple sign-in and then fails with: service-error: The operation couldn’t be completed. (SKInternalErrorDomain error 14.) The error persists after restarting the phone and testing separately on Wi-Fi and cellular. Another tester’s iPhone 14 Pro Max, running the same iOS version and TestFlight build, recognizes its active membership and saves changes successfully. What diagnostics would help distinguish a sandbox account or device issue from an integration problem? I have screenshots but do not yet have a minimal native Xcode reproduction.
Replies
0
Boosts
0
Views
75
Activity
6d