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

"Cannot connect to App Store" when trying to purchase subscription using Xcode built app
I'm developing an app and I think I've implemented what I need to in the swift code. However, when I click the Purchase button in my app, I see "Cannot connect to App Store" when the App Store app opens. Attached are images showing how I've configured the Sandbox user. What am I doing wrong? I expect to be able to do a fake purchase to test subscription activation in the app, but it doesn't work.
1
0
219
Oct ’25
Failed to parse signedTransactionInfo in the notification payload. status=VERIFICATION_FAILURE
We are currently using App Store Server Notifications V2 in a production environment, but occasionally encounter the error "Failed to parse signedTransactionInfo in the notification payload. status=VERIFICATION_FAILURE." What could be the cause of this error? Also, is there a way to resolve this error? After the notification from Apple was received on the server side, it was passed to the Apple library and an error occurred in the Apple library when decryption was performed.
1
0
190
Oct ’25
Why does AppStore.requestReview(in:) require NSViewController Parameter?
Looking to update one of my apps that uses SKStoreReviewController +requestReview (deprecated) to AppStore.requestReview(in:) umm...I have a few of questions... Why is an NSViewController parameter required? It's really not so uncommon for an AppKit app to just use NSWindowController with a window that does not use NSViewController... It should be possible to present the review request in a standalone alert (attached to a window is preferred IMO but it still should be possible to ask in separate window). 3)...why Swift..(err nevermind) Ideally: AppStore requestReview should take a NSWindow parameter but that parameter should be optional. If nil the request should be presented in a standalone window (like an alert). If non nil..present as a sheet on the window. Why a view controller? Maybe I'm missing something.
2
0
176
Oct ’25
How to Handle IME Not Generating Receipt in Sandbox IAP
Question: In the sandbox environment, I attempted to perform an In-App Purchase within an IME (Input Method Extension) using a sandbox test account. The purchase flow completed successfully, and I received the success callback. However, I encountered an issue: no receipt file is generated. I tried checking with both the main app’s bundle and the IME’s bundle, but the receipt file was not found in either case. When I attempted to refresh the receipt using SKReceiptRefreshRequest, it failed with an exception (error code: 0). I would appreciate any guidance on how to resolve this issue.
1
0
146
Sep ’25
Issues with Promotional Offers — Purchase Fails or Discount Not Applied
I am developing and testing Apple Promotional Offers and encountered issues during implementation. Purchase Failure When using the following API, the promotional purchase sheet is displayed, but after attempting payment, the transaction fails. API: public static func promotionalOffer( offerID: String, keyID: String, nonce: UUID, signature: Data, timestamp: Int ) -> Product.PurchaseOption Observed behavior: Alert shows: Unable to Purchase [Environment: Xcode] Not Eligible for Offer Console logs: AMSErrorDomain Code=305 ASDErrorDomain Code=3903 Discount Not Applied When calling this API, there are no errors, but the promotional price is not applied, and the user still sees the original price. API: public static func promotionalOffer( _ offerID: String, compactJWS: String ) -> [Product.PurchaseOption] Questions Does Promotional Offers support testing with .storekit files in Xcode? Can Promotional Offers be tested with sandbox accounts using real offers configured in App Store Connect? How should I troubleshoot and resolve the above issues? • Could it be related to the subscription history of the sandbox account? • Do I need to use TestFlight instead of Xcode to test certain scenarios? • Could this be caused by signature parameters or StoreKit configuration?
1
0
121
Sep ’25
Delete Offer Codes
Regarding the offer codes in https://developer.apple.com/help/app-store-connect/manage-subscriptions/set-up-offer-codes, I set up some incorrect offer codes by mistake. Currently, I can only deactivate it but I can't delete it. Is it possible to let me delete the incorrect offer codes due to the below reasons? Thank you. I can't recreate the offer code due to error message This reference name is or has been used by another offer in this subscription group. When I use the offer code redemption view in https://developer.apple.com/documentation/SwiftUI/View/offerCodeRedemption(isPresented:onCompletion:), it shows all the deactivated offer codes. I don't want them to be displayed in the page.
0
0
73
Sep ’25
"Error handling payment sheet request" with Backyard Bird sample application
After downloading Backyard Birds and following the steps in the section "Configure the sample code project" (i.e. enabling local StoreKit testing in the scheme). When I run the macOS app from within XCode, the following error occurs. Whenever I try to purchase any item from within the app, I am presented with the following error dialogue: "Couldn’t communicate with a helper application. Try your operation again. If that fails, quit and relaunch the application and try again." This happens after I click the purchase button (i.e. the button that displays the price). The Xcode logs show the following errors: Error handling payment sheet request: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service created from an endpoint was invalidated from this process." UserInfo={NSDebugDescription=The connection to service created from an endpoint was invalidated from this process.} Type: Error | Timestamp: 2025-09-26 18:05:36.214491+02:00 | Process: Backyard Birds | Library: StoreKit | Subsystem: com.apple.storekit | Category: Default | TID: 0xafed followed by Purchase did not return a transaction: Error Domain=ASDErrorDomain Code=5115 "Received failure in response from Xcode" UserInfo={NSDebugDescription=Received failure in response from Xcode, NSUnderlyingError=0x600001545470 {Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service created from an endpoint was invalidated from this process." UserInfo={AMSDescription=Ein unbekannter Fehler ist aufgetreten. Versuche es erneut., AMSURL=http://localhost:49244/WebObjects/MZBuy.woa/wa/inAppBuy, NSDebugDescription=The connection to service created from an endpoint was invalidated from this process., AMSStatusCode=200, AMSServerPayload={ "app-list" = ( ); dialog = { cancelButtonString = Cancel; defaultButton = Buy; explanation = "Do you want to buy one Box of Nutrition Pellets for $3.99?\n\n[Environment: Xcode]"; initialCheckboxValue = 1; "m-allowed" = 0; message = "Confirm Your In-App Purchase"; okButtonAction = { buyParams = "bid=com.example.apple-samplecode.Backyard-BirdsHQN4U5V5MY&bvrs=1.0&offerName=pellet.box&quantity=1&deviceVerification=0aee9116-fef7-5d20-b21b-b28848615717&storekitViewInitiated=true"; itemName = "pellet.box"; kind = Buy; }; okButtonString = Buy; paymentSheetInfo = { caseControl = true; confirmationTitle = Pay; countryCode = US; currency = USD; designVersion = 2; displayPrice = "$3.99"; flexList = ( { value = ( { style = priceMain; value = "$3.99"; }, { style = priceSub; value = "One-time charge"; } ); }, { header = "$null"; value = "For testing purposes only. You will not be charged for confirming this purchase."; } ); price = "3.99"; requestor = AppStore; salableIcon = "http://localhost:49244/StoreKit/AppIcon?bid=com.example.apple-samplecode.Backyard-BirdsHQN4U5V5MY"; salableIconType = app; salableInfo = ( "Box of Nutrition Pellets %%image_0%%", "Backyard Birds", "In-App Purchase" ); styles = ( { bold = true; name = priceMain; size = large; }, { color = gray; name = priceSub; }, { bold = true; name = priceMainSpaceBefore; size = large; spacingBefore = medium; } ); title = { type = text; value = Xcode; }; }; }; "download-queue-item-count" = 0; dsid = 17322632127; failureType = 5115; jingleAction = inAppBuy; jingleDocType = inAppSuccess; pings = ( ); }}}} Type: Error | Timestamp: 2025-09-26 18:05:36.346918+02:00 | Process: Backyard Birds | Library: StoreKit | Subsystem: com.apple.storekit | Category: Default | TID: 0xafea I am running Xcode Version 26.0.1 (17A400) macOS Sequia 15.7 What I have tried so far: created a new admin user, logged in as that user, installed Xcode and ran the Backyard Bird sample from there. Same error. This also happens with my own app, when I am trying to test purchasing. How can I further debug this problem?
1
0
64
Sep ’25
StoreKit Configuration Not Syncing to Xcode
Hello! I am attempting to add Subscriptions to an App that Is already published on the App Store. I cannot get Xcode to actually sync what is in my App Store Connect. When adding the Storekit configuration file, I go through the automatic linking process and select the proper bundleID. The configuration file says 'Synced @ [CurrentTime]' however there are no subscriptions listed in there. I have attempted deleting the file several times, creating a new subscription group. With no success. Do I need to publish the subscriptions without the features first? Upon attempting to write the supporting code that will enable these features within the app, I cannot get Xcode to identify that I have these subscriptions. I have also tried pushing these to TestFlight, still with no success. Thank you.
13
5
1.7k
Sep ’25
unable to cancel test subscriptions
I tested a subscription with my developer account, it never charges but at the same time I can't cancel it anymore. It does not appear in the list of my official purchsed subscriptions. I tried to login to the sandbox with my developer account, but then when I click on "Manage" I just keep getting the error "Can't connect - retry". I have already tried to logout from all the services, App store, etc. and re-login, nothing worked. Is there anything I can do? Thanks in advance to anyone who can give any tips.
0
0
91
Sep ’25
StoreKit2.Transaction.updates Returning Large Amounts of Historical Transactions, Causing Verification Traffic Surge
Over the past two days, we've observed an unusual spike in requests from some iOS users to our server endpoint responsible for verifying App Store purchase receipts. After sampling and analyzing the data, we found that the cause is related to the behavior of StoreKit2.Transaction.updates. Specifically, when listening for transaction updates, the system returns a large number of historical transactions — some dating back as far as one year. These callbacks are interpreted as "new" transactions, which in turn trigger repeated calls to Apple’s receipt verification servers, leading to an abnormal surge in traffic and putting pressure on our backend services. This behavior is ongoing and is something we've never encountered in our previous experience. It appears to be outside of expected behavior, and we suspect it may be due to some kind of abnormality or unintended usage scenario. We would appreciate guidance on the following: Is this a known behavior or issue with StoreKit2? Are there specific device states or conditions that could cause the system to emit historical transactions in bulk? Are there any recommended practices for mitigating or filtering such transaction floods? We have attached logs for reference. Any help identifying the root cause or suggestions for investigation would be greatly appreciated. 2025-07-24 12:39:58.594 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713445834000, "originalTransactionId" : "430001791317037", "purchaseDate" : 1713445834000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", } 2025-07-24 12:39:58.594 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "c4f79de2-a027-4b34-b777-6851f83f7e64", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713445849000, "originalTransactionId" : "430001791317270", "purchaseDate" : 1713445849000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001791317270", } 2025-07-24 12:39:58.594 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "02f305d7-0b2d-4d55-b427-192e61b99024", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713511999000, "originalTransactionId" : "430001792218708", "purchaseDate" : 1713511999000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001792218708", } 2025-07-24 12:39:58.598 +0400 [INFO] [MKPaymentService:23]: [XLPay] listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "5ca85907-1ab6-4160-828e-8ab6d3574d6f", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713512034000, "originalTransactionId" : "430001792219189", "purchaseDate" : 1713512034000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001792219189", } 2025-07-24 12:39:58.599 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "04869b50-b181-4b69-b4ff-025175e9cf14", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713512049000, "originalTransactionId" : "430001792219440", "purchaseDate" : 1713512049000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001792219440", }
1
1
171
Sep ’25
Best practice to prevent users from switching between subscriptions in the same group?
Hello everyone, For example, our app currently has one subscription group in App Store Connect with 5 plans (2 annual, 2 monthly, and 1 quarterly). By default, users can go into Apple Subscriptions in Settings and freely switch between all of these plans. However, our business requirement is to only allow users to stay on one annual plan and one quarterly plan. We don’t want them to switch to the other plans. My questions are: Is there any best practice or recommended approach to restrict subscription switching within the same group? Would removing the unwanted products from sale be the correct approach, or are there any risks/downsides with this method? Has anyone faced a similar situation and found a practical solution? Any guidance or shared experience would be greatly appreciated. Thanks!
4
0
162
Sep ’25
When subscribing to the change notification in the App Store, it was found that the type of notification received by the server did not match the expected problem.
Description of the Issue We are encountering issues with App Store Server Notifications, where the notification type received does not align with our expectations for subscription changes. Specifically, we receive DID_RENEW notifications in scenarios involving downgrades or intra-tier upgrades, which disrupts our backend subscription management logic and may lead to incorrect user subscription states and billing errors. Below are two reproducible scenarios with associated transaction data. Scenario 1: Downgrade from Premium Yearly (with 7-Day Trial) to Standard Yearly Steps to Reproduce: A user purchases the Premium Yearly subscription with a 7-day free trial (initial transaction ID: 700002116066502). On the day before the trial ends, the user downgrades to the Standard Yearly subscription via the App Store’s subscription management interface. Expected Behavior: We expect to receive a DID_CHANGE_RENEWAL_STATUS or a similar downgrade notification (e.g., DID_CHANGE_RENEWAL_PREF) to indicate the subscription plan has been downgraded, enabling immediate updates to the user’s subscription status. Actual Behavior: Upon downgrade, our server receives a DID_RENEW notification instead of a downgrade-specific notification. This causes our system to incorrectly interpret the action as a renewal of the Premium subscription rather than a downgrade to Standard, with no subsequent downgrade confirmation received. Relevant Transaction Data: New Transaction ID: 700002122810952 Notification Type: DID_RENEW Notification UUID: 26de9b0e-5d61-4893-b679-0bd18ae3d208 Original Transaction ID (Trial): 700002116066502 Scenario 2: Intra-Tier Upgrade from Standard Monthly to Standard Yearly Steps to Reproduce: A user purchases the Standard Monthly subscription. On the day before the monthly subscription expires, the user switches to the Standard Yearly subscription via the App Store’s subscription management interface. Expected Behavior: The original Monthly subscription expires normally, with a DID_EXPIRE notification received. Upon expiration, we expect a DID_RENEW or SUBSCRIBED notification for the new Yearly subscription to confirm its activation, allowing seamless transition of the user’s subscription plan. Actual Behavior: Immediately after the upgrade, our server receives a DID_RENEW notification for the new Yearly plan. No further notifications are received, including no DID_EXPIRE for the original Monthly subscription. This leaves our system unable to confirm the expiration of the Monthly plan, potentially resulting in duplicate active subscriptions in our records. Relevant Transaction Data: Transaction ID: 70002902074491 Notification Type: DID_RENEW Notification UUID: 3d35bc2f-e769-4549-bf50-d84d41b10342 Impact These notification discrepancies disrupt our subscription lifecycle management, potentially causing incorrect user entitlements, over-billing, and a degraded user experience. Requested Assistance Please confirm the correct notification types for these scenarios as per Apple’s documentation (e.g., App Store Server Notifications V2). Provide guidance on handling these edge cases, including any recent changes to notification logic. If this is a backend issue, please investigate the provided transaction IDs and Notification UUIDs. Thank you for your prompt assistance. We look forward to your response to help resolve this issue for our users. 问题描述: 我们在处理 App Store 订阅变更通知时发现,服务器接收到的通知类型与预期不符,具体表现为降级或同级升级场景下错误接收到 DID_RENEW 通知。这影响了我们后端订阅管理的逻辑,可能导致用户订阅状态和计费出现偏差。以下是两个可重现的场景及相关交易数据。 场景 1:高级年费(含 7 天试用)降级至标准年费 重现步骤: 用户购买高级年费订阅并开启 7 天免费试用(初始交易 ID:700002116066502)。 在试用期结束前一天,用户通过 App Store 的订阅管理界面降级至标准年费订阅。 预期行为: 我们预期会收到 DID_CHANGE_RENEWAL_STATUS 或类似的降级通知(如 DID_CHANGE_RENEWAL_PREF),以表明订阅计划已降级,从而允许我们立即更新用户订阅状态。 实际行为: 降级后,服务器立即收到 DID_RENEW 通知,而非降级相关通知。这导致系统误认为高级订阅仍在续订,而非降级为标准订阅,且后续未收到任何降级确认通知。 相关交易数据: 新交易 ID:700002122810952 通知类型:DID_RENEW 通知 UUID:26de9b0e-5d61-4893-b679-0bd18ae3d208 原始交易 ID(试用):700002116066502 场景 2:标准月费订阅升级为标准年费订阅 重现步骤: 用户购买标准月费订阅。 在月费订阅到期前一天,用户通过 App Store 的订阅管理界面切换至标准年费订阅。 预期行为: 原月费订阅正常到期,预期收到 DID_EXPIRE 通知。 月费到期后,预期收到新年费订阅的 DID_RENEW 或 SUBSCRIBED 通知,以确认年费订阅开始,方便我们无缝切换用户订阅计划。 实际行为: 升级后,服务器立即收到新年费订阅的 DID_RENEW 通知。 后续未收到任何通知,包括原月费订阅的 DID_EXPIRE 通知。这导致我们无法确认月费订阅的到期状态,可能在记录中出现重复的活跃订阅。 相关交易数据: 交易 ID:70002902074491 通知类型:DID_RENEW 通知 UUID:3d35bc2f-e769-4549-bf50-d84d41b10342 影响: 这些通知异常干扰了我们的订阅生命周期管理,可能导致用户权益错误、潜在的重复计费以及用户体验下降。 请求协助: 请确认根据 Apple 文档(例如 App Store Server Notifications V2)在上述场景中应返回的正确通知类型。 请提供处理此类边缘场景的指导,包括通知逻辑的任何最新变更。 如果这是后端问题,请调查提供的交易 ID 和通知 UUID。 感谢您的及时协助,期待您的回复以帮助我们为用户解决问题。
1
0
102
Sep ’25
Same same originalTransactionId, productId, but the transactionIds are different.
We are seeing an issue with a potential duplicate charge issue regarding our app. We have received two transactions with the same originalTransactionId but different transactionIds: Order A: TransactionId: [Redacted_TID_1] OriginalTransactionId: [Redacted_OID_A] ProductId: weekly_subscription PurchaseDate: [Redacted_Timestamp_1] SignedDate: [Redacted_Timestamp_2] Price: [Redacted_Price] CAD Order B: TransactionId: [Redacted_TID_2] OriginalTransactionId: [Redacted_OID_A] ProductId: weekly_subscription PurchaseDate: [Redacted_Timestamp_1] SignedDate: [Redacted_Timestamp_3] Price: [Redacted_Price] CAD Both transactions share the same originalTransactionId, productId, and expiresDate, but the transactionIds are different. We wanna confirm: Were customers charged once or twice for this subscription renewal? If only one charge was made, how should we programmatically determine the “valid” transaction among multiple records with the same originalTransactionId to avoid confusion in our server-side receipt validation? We appreciate any clarification so we can handle this correctly in our backend.
1
0
270
Sep ’25
StoreKit 2 Fails to Load Subscription Products
We are experiencing a critical issue where StoreKit 2 is returning empty products when using Product.products(for:), specifically on devices running iOS 18.4.

 This issue does not occur on iOS 18.3 or earlier.

 Steps:

 Created a subscription product (e.g. "upm1") in App Store Connect
 Confirmed the product is active, localised, and part of a valid subscription group
 Call the following Swift code using StoreKit 2:
 Task { do { let products = try await Product.products(for: ["upm1"]) print(products) } catch { print("Error: (error)") } } 4. Result: products is an empty list.

 This regression is blocking subscription testing on iOS 18.4. 

 Kindly someone please advise on a potential fix or workaround.
2
2
286
Sep ’25
Can't fetch products
Use the following method to fetch: let appProducts = try await Product.products(for: productIdentifiers) The following checks have been carried out ✅ Must-check points App ID capabilities Subscription product status (ready to submit) Why The result is an empty array?
0
0
66
Sep ’25
can not verify receipt
I have three questions about verify receipt I use this api (https://buy.itunes.apple.com/verifyReceipt)to verify receipt is success or not. But since last month, this interface has started to return an error(21002). I see this document (https://developer.apple.com/documentation/appstorereceipts/verifyreceipt) say its Deprecated. My question is, is the error suddenly returned recently because the interface has been deprecated or for some other reason? (I haven't modified my code about this recently) I can not understand this document: (https://developer.apple.com/documentation/appstorereceipts/validating_receipts_on_the_device) Does this mean that in the new version, as long as the app returns a payment success (purchaseDetails.status == PurchaseStatus.purchased), the payment is guaranteed to be successful, and my server does not need to request payment result verification from Apple's server? I try to use this (https://github.com/apple/app-store-server-library-java) to get TransactionInfo, but I dont konw to get Transaction status to know is success or not. my java server code : AppStoreServerAPIClient client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment); TransactionInfoResponse response = client.getTransactionInfo(transactionId); (bug i can note get transaction status, how do i konw this Transaction is success or not)
3
0
156
Sep ’25
Help testing sandbox purchases in Xcode
I am attempting to test non-consumable sandbox purchases, however I am unable to select the "Approve Transaction" option after initiating a purchase. Leaving the transaction in a permanent pending state. I can view the transaction in the transaction manager by navigating to Debug -> Storekit -> Manage Transactions.. but the only available options to select are "Refund Transaction" or "Delete Transaction". What am I missing about Xcode or my environment that is preventing me from testing this purchase flow? Some more information about my set up. I have a .storekit file synced to AppStore Connect with my product Id. There's a StoreKitTestCertificate.cert saved in the project. I've tried running the build on my phone as Debug, Release and ReleaseForRunning all with the same behavior after making a purchase. My phone is logged into a sandbox test user apple account in the developer iOS settings
1
0
211
Sep ’25
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
961
Sep ’25
"Cannot connect to App Store" when trying to purchase subscription using Xcode built app
I'm developing an app and I think I've implemented what I need to in the swift code. However, when I click the Purchase button in my app, I see "Cannot connect to App Store" when the App Store app opens. Attached are images showing how I've configured the Sandbox user. What am I doing wrong? I expect to be able to do a fake purchase to test subscription activation in the app, but it doesn't work.
Replies
1
Boosts
0
Views
219
Activity
Oct ’25
Failed to parse signedTransactionInfo in the notification payload. status=VERIFICATION_FAILURE
We are currently using App Store Server Notifications V2 in a production environment, but occasionally encounter the error "Failed to parse signedTransactionInfo in the notification payload. status=VERIFICATION_FAILURE." What could be the cause of this error? Also, is there a way to resolve this error? After the notification from Apple was received on the server side, it was passed to the Apple library and an error occurred in the Apple library when decryption was performed.
Replies
1
Boosts
0
Views
190
Activity
Oct ’25
Why does AppStore.requestReview(in:) require NSViewController Parameter?
Looking to update one of my apps that uses SKStoreReviewController +requestReview (deprecated) to AppStore.requestReview(in:) umm...I have a few of questions... Why is an NSViewController parameter required? It's really not so uncommon for an AppKit app to just use NSWindowController with a window that does not use NSViewController... It should be possible to present the review request in a standalone alert (attached to a window is preferred IMO but it still should be possible to ask in separate window). 3)...why Swift..(err nevermind) Ideally: AppStore requestReview should take a NSWindow parameter but that parameter should be optional. If nil the request should be presented in a standalone window (like an alert). If non nil..present as a sheet on the window. Why a view controller? Maybe I'm missing something.
Replies
2
Boosts
0
Views
176
Activity
Oct ’25
How to Handle IME Not Generating Receipt in Sandbox IAP
Question: In the sandbox environment, I attempted to perform an In-App Purchase within an IME (Input Method Extension) using a sandbox test account. The purchase flow completed successfully, and I received the success callback. However, I encountered an issue: no receipt file is generated. I tried checking with both the main app’s bundle and the IME’s bundle, but the receipt file was not found in either case. When I attempted to refresh the receipt using SKReceiptRefreshRequest, it failed with an exception (error code: 0). I would appreciate any guidance on how to resolve this issue.
Replies
1
Boosts
0
Views
146
Activity
Sep ’25
Issues with Promotional Offers — Purchase Fails or Discount Not Applied
I am developing and testing Apple Promotional Offers and encountered issues during implementation. Purchase Failure When using the following API, the promotional purchase sheet is displayed, but after attempting payment, the transaction fails. API: public static func promotionalOffer( offerID: String, keyID: String, nonce: UUID, signature: Data, timestamp: Int ) -> Product.PurchaseOption Observed behavior: Alert shows: Unable to Purchase [Environment: Xcode] Not Eligible for Offer Console logs: AMSErrorDomain Code=305 ASDErrorDomain Code=3903 Discount Not Applied When calling this API, there are no errors, but the promotional price is not applied, and the user still sees the original price. API: public static func promotionalOffer( _ offerID: String, compactJWS: String ) -> [Product.PurchaseOption] Questions Does Promotional Offers support testing with .storekit files in Xcode? Can Promotional Offers be tested with sandbox accounts using real offers configured in App Store Connect? How should I troubleshoot and resolve the above issues? • Could it be related to the subscription history of the sandbox account? • Do I need to use TestFlight instead of Xcode to test certain scenarios? • Could this be caused by signature parameters or StoreKit configuration?
Replies
1
Boosts
0
Views
121
Activity
Sep ’25
Delete Offer Codes
Regarding the offer codes in https://developer.apple.com/help/app-store-connect/manage-subscriptions/set-up-offer-codes, I set up some incorrect offer codes by mistake. Currently, I can only deactivate it but I can't delete it. Is it possible to let me delete the incorrect offer codes due to the below reasons? Thank you. I can't recreate the offer code due to error message This reference name is or has been used by another offer in this subscription group. When I use the offer code redemption view in https://developer.apple.com/documentation/SwiftUI/View/offerCodeRedemption(isPresented:onCompletion:), it shows all the deactivated offer codes. I don't want them to be displayed in the page.
Replies
0
Boosts
0
Views
73
Activity
Sep ’25
"Error handling payment sheet request" with Backyard Bird sample application
After downloading Backyard Birds and following the steps in the section "Configure the sample code project" (i.e. enabling local StoreKit testing in the scheme). When I run the macOS app from within XCode, the following error occurs. Whenever I try to purchase any item from within the app, I am presented with the following error dialogue: "Couldn’t communicate with a helper application. Try your operation again. If that fails, quit and relaunch the application and try again." This happens after I click the purchase button (i.e. the button that displays the price). The Xcode logs show the following errors: Error handling payment sheet request: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service created from an endpoint was invalidated from this process." UserInfo={NSDebugDescription=The connection to service created from an endpoint was invalidated from this process.} Type: Error | Timestamp: 2025-09-26 18:05:36.214491+02:00 | Process: Backyard Birds | Library: StoreKit | Subsystem: com.apple.storekit | Category: Default | TID: 0xafed followed by Purchase did not return a transaction: Error Domain=ASDErrorDomain Code=5115 "Received failure in response from Xcode" UserInfo={NSDebugDescription=Received failure in response from Xcode, NSUnderlyingError=0x600001545470 {Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service created from an endpoint was invalidated from this process." UserInfo={AMSDescription=Ein unbekannter Fehler ist aufgetreten. Versuche es erneut., AMSURL=http://localhost:49244/WebObjects/MZBuy.woa/wa/inAppBuy, NSDebugDescription=The connection to service created from an endpoint was invalidated from this process., AMSStatusCode=200, AMSServerPayload={ "app-list" = ( ); dialog = { cancelButtonString = Cancel; defaultButton = Buy; explanation = "Do you want to buy one Box of Nutrition Pellets for $3.99?\n\n[Environment: Xcode]"; initialCheckboxValue = 1; "m-allowed" = 0; message = "Confirm Your In-App Purchase"; okButtonAction = { buyParams = "bid=com.example.apple-samplecode.Backyard-BirdsHQN4U5V5MY&bvrs=1.0&offerName=pellet.box&quantity=1&deviceVerification=0aee9116-fef7-5d20-b21b-b28848615717&storekitViewInitiated=true"; itemName = "pellet.box"; kind = Buy; }; okButtonString = Buy; paymentSheetInfo = { caseControl = true; confirmationTitle = Pay; countryCode = US; currency = USD; designVersion = 2; displayPrice = "$3.99"; flexList = ( { value = ( { style = priceMain; value = "$3.99"; }, { style = priceSub; value = "One-time charge"; } ); }, { header = "$null"; value = "For testing purposes only. You will not be charged for confirming this purchase."; } ); price = "3.99"; requestor = AppStore; salableIcon = "http://localhost:49244/StoreKit/AppIcon?bid=com.example.apple-samplecode.Backyard-BirdsHQN4U5V5MY"; salableIconType = app; salableInfo = ( "Box of Nutrition Pellets %%image_0%%", "Backyard Birds", "In-App Purchase" ); styles = ( { bold = true; name = priceMain; size = large; }, { color = gray; name = priceSub; }, { bold = true; name = priceMainSpaceBefore; size = large; spacingBefore = medium; } ); title = { type = text; value = Xcode; }; }; }; "download-queue-item-count" = 0; dsid = 17322632127; failureType = 5115; jingleAction = inAppBuy; jingleDocType = inAppSuccess; pings = ( ); }}}} Type: Error | Timestamp: 2025-09-26 18:05:36.346918+02:00 | Process: Backyard Birds | Library: StoreKit | Subsystem: com.apple.storekit | Category: Default | TID: 0xafea I am running Xcode Version 26.0.1 (17A400) macOS Sequia 15.7 What I have tried so far: created a new admin user, logged in as that user, installed Xcode and ran the Backyard Bird sample from there. Same error. This also happens with my own app, when I am trying to test purchasing. How can I further debug this problem?
Replies
1
Boosts
0
Views
64
Activity
Sep ’25
StoreKit Configuration Not Syncing to Xcode
Hello! I am attempting to add Subscriptions to an App that Is already published on the App Store. I cannot get Xcode to actually sync what is in my App Store Connect. When adding the Storekit configuration file, I go through the automatic linking process and select the proper bundleID. The configuration file says 'Synced @ [CurrentTime]' however there are no subscriptions listed in there. I have attempted deleting the file several times, creating a new subscription group. With no success. Do I need to publish the subscriptions without the features first? Upon attempting to write the supporting code that will enable these features within the app, I cannot get Xcode to identify that I have these subscriptions. I have also tried pushing these to TestFlight, still with no success. Thank you.
Replies
13
Boosts
5
Views
1.7k
Activity
Sep ’25
unable to cancel test subscriptions
I tested a subscription with my developer account, it never charges but at the same time I can't cancel it anymore. It does not appear in the list of my official purchsed subscriptions. I tried to login to the sandbox with my developer account, but then when I click on "Manage" I just keep getting the error "Can't connect - retry". I have already tried to logout from all the services, App store, etc. and re-login, nothing worked. Is there anything I can do? Thanks in advance to anyone who can give any tips.
Replies
0
Boosts
0
Views
91
Activity
Sep ’25
StoreKit2.Transaction.updates Returning Large Amounts of Historical Transactions, Causing Verification Traffic Surge
Over the past two days, we've observed an unusual spike in requests from some iOS users to our server endpoint responsible for verifying App Store purchase receipts. After sampling and analyzing the data, we found that the cause is related to the behavior of StoreKit2.Transaction.updates. Specifically, when listening for transaction updates, the system returns a large number of historical transactions — some dating back as far as one year. These callbacks are interpreted as "new" transactions, which in turn trigger repeated calls to Apple’s receipt verification servers, leading to an abnormal surge in traffic and putting pressure on our backend services. This behavior is ongoing and is something we've never encountered in our previous experience. It appears to be outside of expected behavior, and we suspect it may be due to some kind of abnormality or unintended usage scenario. We would appreciate guidance on the following: Is this a known behavior or issue with StoreKit2? Are there specific device states or conditions that could cause the system to emit historical transactions in bulk? Are there any recommended practices for mitigating or filtering such transaction floods? We have attached logs for reference. Any help identifying the root cause or suggestions for investigation would be greatly appreciated. 2025-07-24 12:39:58.594 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713445834000, "originalTransactionId" : "430001791317037", "purchaseDate" : 1713445834000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", } 2025-07-24 12:39:58.594 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "c4f79de2-a027-4b34-b777-6851f83f7e64", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713445849000, "originalTransactionId" : "430001791317270", "purchaseDate" : 1713445849000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001791317270", } 2025-07-24 12:39:58.594 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "02f305d7-0b2d-4d55-b427-192e61b99024", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713511999000, "originalTransactionId" : "430001792218708", "purchaseDate" : 1713511999000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001792218708", } 2025-07-24 12:39:58.598 +0400 [INFO] [MKPaymentService:23]: [XLPay] listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "5ca85907-1ab6-4160-828e-8ab6d3574d6f", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713512034000, "originalTransactionId" : "430001792219189", "purchaseDate" : 1713512034000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001792219189", } 2025-07-24 12:39:58.599 +0400 listenForTransactions :{ "appTransactionId" : "704289572311513293", "deviceVerificationNonce" : "04869b50-b181-4b69-b4ff-025175e9cf14", "environment" : "Production", "inAppOwnershipType" : "PURCHASED", "originalPurchaseDate" : 1713512049000, "originalTransactionId" : "430001792219440", "purchaseDate" : 1713512049000, "quantity" : 1, "signedDate" : 1753346396278, "storefrontId" : "143481", "transactionId" : "430001792219440", }
Replies
1
Boosts
1
Views
171
Activity
Sep ’25
Best practice to prevent users from switching between subscriptions in the same group?
Hello everyone, For example, our app currently has one subscription group in App Store Connect with 5 plans (2 annual, 2 monthly, and 1 quarterly). By default, users can go into Apple Subscriptions in Settings and freely switch between all of these plans. However, our business requirement is to only allow users to stay on one annual plan and one quarterly plan. We don’t want them to switch to the other plans. My questions are: Is there any best practice or recommended approach to restrict subscription switching within the same group? Would removing the unwanted products from sale be the correct approach, or are there any risks/downsides with this method? Has anyone faced a similar situation and found a practical solution? Any guidance or shared experience would be greatly appreciated. Thanks!
Replies
4
Boosts
0
Views
162
Activity
Sep ’25
When subscribing to the change notification in the App Store, it was found that the type of notification received by the server did not match the expected problem.
Description of the Issue We are encountering issues with App Store Server Notifications, where the notification type received does not align with our expectations for subscription changes. Specifically, we receive DID_RENEW notifications in scenarios involving downgrades or intra-tier upgrades, which disrupts our backend subscription management logic and may lead to incorrect user subscription states and billing errors. Below are two reproducible scenarios with associated transaction data. Scenario 1: Downgrade from Premium Yearly (with 7-Day Trial) to Standard Yearly Steps to Reproduce: A user purchases the Premium Yearly subscription with a 7-day free trial (initial transaction ID: 700002116066502). On the day before the trial ends, the user downgrades to the Standard Yearly subscription via the App Store’s subscription management interface. Expected Behavior: We expect to receive a DID_CHANGE_RENEWAL_STATUS or a similar downgrade notification (e.g., DID_CHANGE_RENEWAL_PREF) to indicate the subscription plan has been downgraded, enabling immediate updates to the user’s subscription status. Actual Behavior: Upon downgrade, our server receives a DID_RENEW notification instead of a downgrade-specific notification. This causes our system to incorrectly interpret the action as a renewal of the Premium subscription rather than a downgrade to Standard, with no subsequent downgrade confirmation received. Relevant Transaction Data: New Transaction ID: 700002122810952 Notification Type: DID_RENEW Notification UUID: 26de9b0e-5d61-4893-b679-0bd18ae3d208 Original Transaction ID (Trial): 700002116066502 Scenario 2: Intra-Tier Upgrade from Standard Monthly to Standard Yearly Steps to Reproduce: A user purchases the Standard Monthly subscription. On the day before the monthly subscription expires, the user switches to the Standard Yearly subscription via the App Store’s subscription management interface. Expected Behavior: The original Monthly subscription expires normally, with a DID_EXPIRE notification received. Upon expiration, we expect a DID_RENEW or SUBSCRIBED notification for the new Yearly subscription to confirm its activation, allowing seamless transition of the user’s subscription plan. Actual Behavior: Immediately after the upgrade, our server receives a DID_RENEW notification for the new Yearly plan. No further notifications are received, including no DID_EXPIRE for the original Monthly subscription. This leaves our system unable to confirm the expiration of the Monthly plan, potentially resulting in duplicate active subscriptions in our records. Relevant Transaction Data: Transaction ID: 70002902074491 Notification Type: DID_RENEW Notification UUID: 3d35bc2f-e769-4549-bf50-d84d41b10342 Impact These notification discrepancies disrupt our subscription lifecycle management, potentially causing incorrect user entitlements, over-billing, and a degraded user experience. Requested Assistance Please confirm the correct notification types for these scenarios as per Apple’s documentation (e.g., App Store Server Notifications V2). Provide guidance on handling these edge cases, including any recent changes to notification logic. If this is a backend issue, please investigate the provided transaction IDs and Notification UUIDs. Thank you for your prompt assistance. We look forward to your response to help resolve this issue for our users. 问题描述: 我们在处理 App Store 订阅变更通知时发现,服务器接收到的通知类型与预期不符,具体表现为降级或同级升级场景下错误接收到 DID_RENEW 通知。这影响了我们后端订阅管理的逻辑,可能导致用户订阅状态和计费出现偏差。以下是两个可重现的场景及相关交易数据。 场景 1:高级年费(含 7 天试用)降级至标准年费 重现步骤: 用户购买高级年费订阅并开启 7 天免费试用(初始交易 ID:700002116066502)。 在试用期结束前一天,用户通过 App Store 的订阅管理界面降级至标准年费订阅。 预期行为: 我们预期会收到 DID_CHANGE_RENEWAL_STATUS 或类似的降级通知(如 DID_CHANGE_RENEWAL_PREF),以表明订阅计划已降级,从而允许我们立即更新用户订阅状态。 实际行为: 降级后,服务器立即收到 DID_RENEW 通知,而非降级相关通知。这导致系统误认为高级订阅仍在续订,而非降级为标准订阅,且后续未收到任何降级确认通知。 相关交易数据: 新交易 ID:700002122810952 通知类型:DID_RENEW 通知 UUID:26de9b0e-5d61-4893-b679-0bd18ae3d208 原始交易 ID(试用):700002116066502 场景 2:标准月费订阅升级为标准年费订阅 重现步骤: 用户购买标准月费订阅。 在月费订阅到期前一天,用户通过 App Store 的订阅管理界面切换至标准年费订阅。 预期行为: 原月费订阅正常到期,预期收到 DID_EXPIRE 通知。 月费到期后,预期收到新年费订阅的 DID_RENEW 或 SUBSCRIBED 通知,以确认年费订阅开始,方便我们无缝切换用户订阅计划。 实际行为: 升级后,服务器立即收到新年费订阅的 DID_RENEW 通知。 后续未收到任何通知,包括原月费订阅的 DID_EXPIRE 通知。这导致我们无法确认月费订阅的到期状态,可能在记录中出现重复的活跃订阅。 相关交易数据: 交易 ID:70002902074491 通知类型:DID_RENEW 通知 UUID:3d35bc2f-e769-4549-bf50-d84d41b10342 影响: 这些通知异常干扰了我们的订阅生命周期管理,可能导致用户权益错误、潜在的重复计费以及用户体验下降。 请求协助: 请确认根据 Apple 文档(例如 App Store Server Notifications V2)在上述场景中应返回的正确通知类型。 请提供处理此类边缘场景的指导,包括通知逻辑的任何最新变更。 如果这是后端问题,请调查提供的交易 ID 和通知 UUID。 感谢您的及时协助,期待您的回复以帮助我们为用户解决问题。
Replies
1
Boosts
0
Views
102
Activity
Sep ’25
Same same originalTransactionId, productId, but the transactionIds are different.
We are seeing an issue with a potential duplicate charge issue regarding our app. We have received two transactions with the same originalTransactionId but different transactionIds: Order A: TransactionId: [Redacted_TID_1] OriginalTransactionId: [Redacted_OID_A] ProductId: weekly_subscription PurchaseDate: [Redacted_Timestamp_1] SignedDate: [Redacted_Timestamp_2] Price: [Redacted_Price] CAD Order B: TransactionId: [Redacted_TID_2] OriginalTransactionId: [Redacted_OID_A] ProductId: weekly_subscription PurchaseDate: [Redacted_Timestamp_1] SignedDate: [Redacted_Timestamp_3] Price: [Redacted_Price] CAD Both transactions share the same originalTransactionId, productId, and expiresDate, but the transactionIds are different. We wanna confirm: Were customers charged once or twice for this subscription renewal? If only one charge was made, how should we programmatically determine the “valid” transaction among multiple records with the same originalTransactionId to avoid confusion in our server-side receipt validation? We appreciate any clarification so we can handle this correctly in our backend.
Replies
1
Boosts
0
Views
270
Activity
Sep ’25
Promotional offer is not showing in In-app subscription sheet.
Hello, I have 2 subscription group. Each group have different plans and promotional offer. I was set 1 month free promotional offer in all plans. While I subscribe any plan IAP sheet is not showing 1 month free promotional offer. I already used with new sandbox account. How can I get promotional offer in IAP sheet?
Replies
4
Boosts
1
Views
925
Activity
Sep ’25
StoreKit 2 Fails to Load Subscription Products
We are experiencing a critical issue where StoreKit 2 is returning empty products when using Product.products(for:), specifically on devices running iOS 18.4.

 This issue does not occur on iOS 18.3 or earlier.

 Steps:

 Created a subscription product (e.g. "upm1") in App Store Connect
 Confirmed the product is active, localised, and part of a valid subscription group
 Call the following Swift code using StoreKit 2:
 Task { do { let products = try await Product.products(for: ["upm1"]) print(products) } catch { print("Error: (error)") } } 4. Result: products is an empty list.

 This regression is blocking subscription testing on iOS 18.4. 

 Kindly someone please advise on a potential fix or workaround.
Replies
2
Boosts
2
Views
286
Activity
Sep ’25
Can't fetch products
Use the following method to fetch: let appProducts = try await Product.products(for: productIdentifiers) The following checks have been carried out ✅ Must-check points App ID capabilities Subscription product status (ready to submit) Why The result is an empty array?
Replies
0
Boosts
0
Views
66
Activity
Sep ’25
SKAN Postback received after 6 months
Hello All, We continue to receive post backs for campaigns which were run 6 months back. Our understanding is post back window is only 3 months, so checking to see if this is expected or any documentation will help. We are on SKAN4.0
Replies
0
Boosts
0
Views
66
Activity
Sep ’25
can not verify receipt
I have three questions about verify receipt I use this api (https://buy.itunes.apple.com/verifyReceipt)to verify receipt is success or not. But since last month, this interface has started to return an error(21002). I see this document (https://developer.apple.com/documentation/appstorereceipts/verifyreceipt) say its Deprecated. My question is, is the error suddenly returned recently because the interface has been deprecated or for some other reason? (I haven't modified my code about this recently) I can not understand this document: (https://developer.apple.com/documentation/appstorereceipts/validating_receipts_on_the_device) Does this mean that in the new version, as long as the app returns a payment success (purchaseDetails.status == PurchaseStatus.purchased), the payment is guaranteed to be successful, and my server does not need to request payment result verification from Apple's server? I try to use this (https://github.com/apple/app-store-server-library-java) to get TransactionInfo, but I dont konw to get Transaction status to know is success or not. my java server code : AppStoreServerAPIClient client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment); TransactionInfoResponse response = client.getTransactionInfo(transactionId); (bug i can note get transaction status, how do i konw this Transaction is success or not)
Replies
3
Boosts
0
Views
156
Activity
Sep ’25
Help testing sandbox purchases in Xcode
I am attempting to test non-consumable sandbox purchases, however I am unable to select the "Approve Transaction" option after initiating a purchase. Leaving the transaction in a permanent pending state. I can view the transaction in the transaction manager by navigating to Debug -> Storekit -> Manage Transactions.. but the only available options to select are "Refund Transaction" or "Delete Transaction". What am I missing about Xcode or my environment that is preventing me from testing this purchase flow? Some more information about my set up. I have a .storekit file synced to AppStore Connect with my product Id. There's a StoreKitTestCertificate.cert saved in the project. I've tried running the build on my phone as Debug, Release and ReleaseForRunning all with the same behavior after making a purchase. My phone is logged into a sandbox test user apple account in the developer iOS settings
Replies
1
Boosts
0
Views
211
Activity
Sep ’25
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
961
Activity
Sep ’25