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

StoreKit 2 – IAP Subscriptions Not Appearing in Sandbox
I am experiencing an issue with my iOS app where StoreKit 2 in-app subscriptions are not appearing when using Product.products(for:). I have done all the necessary configurations, but the products still return an empty array ([]). Here are the details of my setup: • App ID / Bundle ID: com.tstore.vocabely • Product IDs: • com.tstore.vocabely.base • com.tstore.vocabely.pro • com.tstore.vocabely.ultimate • Paid Apps Agreement: Active • IAP Status in App Store Connect: Ready to Submit / Approved • Testing Environment: • Device: iPhone (real device) • iOS Version: [insert your iOS version] • Xcode Version: [insert your Xcode version] • Sandbox Tester Account used • Code Snippet: Using Product.products(for: productIDs) in StoreKitManager to fetch products I have verified: • Product IDs match exactly with App Store Connect • Paid Apps Agreement is Active • Using a real device, not a simulator • Sandbox account is properly signed in Despite all of this, fetchProducts() still returns an empty array. Could you please assist me in troubleshooting why my subscriptions are not appearing in the Sandbox environment? Thank you for your support.
2
0
135
Aug ’25
StoreKit returns restored for SKUs marked Consumable (no purchase sheet); Flutter in_app_purchase + SK2
What platform are you targeting? And what version? iOS, testing in Sandbox on a physical device. What version of Xcode are you using? [Xcode __] What version of the OS are you testing on? iOS 18 on iPhone 15 pro. What specific API are you using? StoreKit 2 via Flutter’s in_app_purchase plugin (Dart), which uses in_app_purchase_storekit under the hood. What are the exact steps you took? In App Store Connect, I created several Consumable IAPs (status “Ready to Submit”). Example product IDs: USD3.99TenMinuteCoffeePlan (Consumable) USD24.99OneHourDinnerPlan (Consumable) USD14.99InviteAFriendAsGenie (Consumable) Signed in as a Sandbox tester on device (Settings → App Store → Sandbox Account). App queries products with InAppPurchase.instance.queryProductDetails(ids) — products load successfully. Call buyConsumable(purchaseParam: PurchaseParam(productDetails: ...)). Listen to purchaseStream and log PurchaseDetails. If something failed, what are the symptoms? The purchase sheet often does not appear. The purchase stream reports PurchaseStatus.restored, immediately, for SKUs that are marked Consumable. Example log lines (from Dart): Products loaded: 6 Product: id=USD3.99TenMinuteCoffeePlan, price=3.99 Product: id=USD24.99OneHourDinnerPlan, price=24.99 Product: id=USD14.99InviteAFriendAsGenie, price=14.99 Purchase update: productID=USD3.99TenMinuteCoffeePlan, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000000991974131 Purchase update: productID=USD24.99OneHourDinnerPlan, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000000992079251 Purchase update: productID=USD14.99InviteAFriendAsGenie, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000000999910991 Purchase update: productID=USD29.99InviteAFriendAsGenie, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000001003571920 If nothing failed, what results did you see? And what were you expecting? Actual: restored events (no sheet) for items configured as Consumable. Expected: For Consumables, a purchase sheet followed by purchased status. Consumables shouldn’t “restore”. What else have you tried? Verified every SKU shows Type = Consumable and Ready to Submit in App Store Connect; “Cleared for Sale” enabled; pricing/localization filled. Created new product IDs (to avoid any prior non-consumable history). Verified I’m not calling restorePurchases. In the listener, I only grant benefits on PurchaseStatus.purchased (not on restored). Observed that queryProductDetails succeeds; some IDs that aren’t fully configured return “not found,” as expected. Minimal code (core bits): final _iap = InAppPurchase.instance; Future<void> init() async { final resp = await _iap.queryProductDetails({ 'USD3.99TenMinuteCoffeePlan', 'USD24.99OneHourDinnerPlan', 'USD14.99InviteAFriendAsGenie', 'USD29.99InviteAFriendAsGenie', }); _products = resp.productDetails; _sub = _iap.purchaseStream.listen(_onUpdates); } Future<void> buy(ProductDetails p) async { final param = PurchaseParam(productDetails: p); await _iap.buyConsumable(purchaseParam: param); // iOS SK2 path } void _onUpdates(List<PurchaseDetails> list) async { for (final pd in list) { print('status=${pd.status}, id=${pd.productID}, pending=${pd.pendingCompletePurchase}, purchaseID=${pd.purchaseID}'); switch (pd.status) { case PurchaseStatus.purchased: // deliver & (if pendingCompletePurchase) completePurchase break; case PurchaseStatus.restored: // for consumables, I do not deliver here break; default: break; } } } Questions for the community/Apple: Under what conditions would StoreKit 2 return restored for a SKU that’s set to Consumable? Is there any server-side caching of old product type or ownership tied to a product ID that could cause this in Sandbox? Is “Ready to Submit” sufficient for Sandbox testing of IAPs, or must the SKUs be attached to a submitted build before StoreKit treats them as consumable? If a product ID was ever created/purchased as Non-Consumable historically, does creating a new ASC entry with the same string ID as Consumable still cause restored for that tester? Besides creating brand-new product IDs and/or resetting the Sandbox tester’s purchase history, is there any other recommended way to clear this state? Happy to provide a device sysdiagnose or a stripped test project if that helps. Thanks!
0
0
188
Sep ’25
In iOS 26 beta3 version, the finishTransaction method is unable to remove transactions from the SKPaymentQueue, causing transactions to remain in the queue even after being processed.
We have some users who have upgraded to iOS 26 beta3. Currently, we observe that when these users make in-app purchases, our code calls [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; method, and we clearly receive the successful removal callback in the delegate method - (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions. However, when users click on products with the same productId again, the method - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions still returns information about previously removed transactions, preventing users from making further in-app purchases.
4
0
344
Jul ’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
107
Sep ’25
Migrating to StoreKit 2
Hi Friends, I have an iOS app, which uses around 500 in app purchases for various modules. I am using StoreKit for in app purchase, now trying to migrate this to StoreKit 2. I am using Product.products(for:) method to fetch all the products by sending identifiers of all the 500 In app purchases. In response, I am getting details of only 160 products, the method is not returning remaining in app purchases. What could be the reason for this behaviour, how to get rid of the issue? May be is this the issue will happen only on TestFlight? If someone from Apple assures about it, we have plan to submit the app. Please advise, Thank you.
0
0
108
May ’25
(verifyreceipt) I cannot verify from the server whether the user's iap payment is successful or not
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://aninterestingwebsite.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) 2. I can not understand this document: (https://aninterestingwebsite.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? 3. 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)
0
0
78
Aug ’25
How to check if user still have valid subscription?
Is there an API Endpoint that I can call to check if user still have valid subscription? I want to be sure that his subscription renewal was succesful (ie: I dont want to give him another month/year/.. if his latest renewal wasnt successful) Would GET https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionId} be the correct API endpoint to call? But I wonder, after subscription auto-renews, do we still use the same transactionId to check whether his subs is still valid?
0
0
54
Jul ’25
subscriptionGroupLookups API returns 404 - No LookUp Key assigned to my subscription group
Hello, I'm encountering an issue when trying to use the subscriptionGroupLookups endpoint in the App Store Connect API. Despite having the correct setup, I continue to receive a 404 NOT FOUND error when making requests to: GET https://api.appstoreconnect.apple.com/v1/subscriptionGroupLookups Here is the current state of my environment: I am the Account Holder of the App Store Connect account The App Store Connect API key has been successfully created I have the correct Key ID, Issuer ID, and .p8 private key I can authenticate and access the apps and subscriptionGroups endpoints However, the subscriptionGroupLookups endpoint always returns: { "errors": [ { "status": "404", "code": "NOT_FOUND", "title": "The specified resource does not exist" } ] } I suspect that LookUp Keys (UUIDs) have not been assigned to our subscription groups, even though they were created and are active in App Store Connect. There is no “Request Access” button visible under the Integrations tab (as mentioned in Apple support instructions), and my keys appear under “App Store Connect API” > “Keys” as active. Questions: How can I ensure that LookUp Keys are assigned to my subscription groups? Is there a way to trigger this manually or via support? Has anyone successfully resolved this? Any advice or experience would be greatly appreciated. Thank you!
0
0
98
May ’25
[Bug/Doc Discrepancy] App Store Server API "price" field does not include quantity as documentation states
According to the App Store Server API documentation , https://aninterestingwebsite.com/documentation/appstoreserverapi/price the price field "shows the total amount of the transaction for the quantity the customer purchased." However, in actual transaction notifications and responses from App Store Server API, the price field appears to represent the unit price, not the total price. For consumable in-app purchases with quantity > 1, the price field equals the unit price of a single item. The total user payment is only correct after multiplying by the quantity. When quantity > 1, the actual amount paid by the user only matches price × quantity, which contradicts the documentation. Please confirm whether the price field is intended to be: The unit price of a single item (requiring multiplication by quantity), or The total price including all quantities (as currently documented). If the former is correct, please update the documentation to clarify that the value represents the unit price, not the total amount.
0
0
46
Oct ’25
in-app purchases
I implemented consumable in-app purchases in an iPhone app using ProductView(). When I tap the payment button in ProductView(), I am taken to the payment screen and once the payment is completed the next code seems to be executed, so there doesn't seem to be a problem, but if I tap the payment button in ProductView() again, the next code is executed without taking me to the payment screen. This means that a single payment can be made multiple times. Can someone help? ProductView(id: "geminiOneMatch") .productViewStyle(.compact) .padding() .onInAppPurchaseCompletion { product, result in if case .success(.success(_)) = result { // 課金が成功した場合の処理 gemini.addOneMatch(amount: 20) popUpVM.geminiOneMatchPopUp = false dataManageVM.generateRespons(locale: locale) } }
0
0
250
Jul ’25
Guidance on Migrating Active Subscriptions from Apple Server Notifications v1 to v2
I’m reaching out regarding our existing in-app subscription implementation that currently uses App Store Server Notifications version 1 (v1). Our live application has a significant number of active recurring subscriptions that are being managed through the v1 webhook integration. We have now developed a revamped version of our application, which uses the same Apple Developer Account and App Store Connect setup, but in this new app version, we’ve implemented App Store Server Notifications version 2 (v2). Before moving forward with the migration, I would like to clarify the following points to ensure a smooth transition and avoid any disruptions to ongoing subscriptions: Backward Compatibility: Will existing active subscriptions (originally created and managed via v1 notifications) continue to work seamlessly once we switch to v2, or do we need to maintain both v1 and v2 endpoints during the transition? Notification Delivery: If both webhook versions are configured simultaneously, will Apple send notifications to both endpoints, or only the one currently configured in App Store Connect? Migration Strategy: What is Apple’s recommended best practice for migrating from v1 to v2 in a scenario where the live app still has active subscriptions tied to the v1 webhook? Potential Risks or Considerations: Are there any known limitations, delays, or issues that we should prepare for during this migration (for example, differences in payload structure or event types between v1 and v2 that could affect subscription lifecycle management)? I would greatly appreciate your guidance or documentation links that outline the correct migration steps and recommended approach for ensuring continuity of service for all existing subscribers.
0
0
145
Oct ’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
68
Sep ’25
integrating In-App Purchases on PWA.
I am trying to launch a PWA as an application on App Store, and got rejected cause of In-App Purchases. Application is about content generation and selling subscriptions for premium content. So thats why needed to implement In-App Purchases. I have created wrapper via PWABuilder. And it is looking great so far, now my question is about How can I implement In-App Purchases in the bundle which is already created. Any suggestions will be appreciated. More clarification:- I have that product running on Web right now, we have integrated Stripe for payment handling for subscriptions. If there is nothing we can do for In-App Purchases then we have to make purchases on website and then user will be able to experience the changes. We tried that, but then we got rejected for showing locked premium content on user's feed. Also can't show any CTA or Subscribe text or button.
0
0
148
Jul ’25
Encountered issues when calling the sandbox environment interface to verify receipts during the development of the payment function
Currently, we are using the Apple V2 interface to develop the payment function. We generate a transaction ID on the mobile client and obtain the receipt. Now, when we call the Apple sandbox environment interface to verify the receipt, we always get a 404 error. The above is the request and response. The token used in it is also the original data after decoding, and there is no problem. Could you help me figure out what other possible reasons there might be?
0
0
45
Oct ’25
"In-App Purchases are not allowed" Error Persists After All Troubleshooting Steps
Hello, I am consistently receiving the error message "In-app purchases are not allowed on this device" whenever I try to make an in-app purchase on my iOS device. Despite following all the recommended solutions I could find online, the issue remains unresolved. Here is a list of the steps I have already taken: Checked Screen Time Settings: I navigated to Settings > Screen Time > Content & Privacy Restrictions > iTunes & App Store Purchases. I have confirmed that "In-App Purchases" is set to "Allow." I have also tried toggling this setting off and on again. Signed Out & In of Apple ID: I signed out of my Apple ID via Settings > [Your Name] > Media & Purchases, restarted the device, and then signed back in. Restarted the Device: I have force-restarted my device multiple times. Updated iOS: I have ensured my device is running the latest version of iOS (checked via Settings > General > Software Update). Verified Payment Method: I have confirmed that my payment method on file is valid and up-to-date. Created a New Sandbox Account: I also created a new Sandbox Tester account in App Store Connect and tested with it, but the result was the same. Device Information: Device Model: iPhone 15, iPhone 13 iOS Version: iOS 17.5, iOS 18 Even after performing all of these steps, the problem persists. Has anyone else encountered such a stubborn issue, or does anyone have a different solution I could try? Thank you in advance for your help.
0
0
230
Jul ’25
App store payment screen not showing
Hello I am trying to add payments on my app. I have added all products I need in subscriptions. I also tried by using storekit but from my understanding testing with storekit is nothing to rely on. My app works on Android (with the same product IDs same unction call) iOS is not why is that?
1
0
58
Sep ’25
react native iap not providing the subscription information
I am handling the buy subscription with this function const handleBuySubscription = async (productId) =&gt; { try { await requestSubscription({ sku: productId, }); setLoading(false); } catch (error) { setLoading(false); if (error instanceof PurchaseError) { errorLog({ message: [${error.code}]: ${error.message}, error }); } else { errorLog({ message: "handleBuySubscription", error }); } } }; but the requestSubscription({ sku: productId, }) does not return anything, and it is stuck at await
0
0
83
Aug ’25
Delete Offer Codes
Regarding the offer codes in https://aninterestingwebsite.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://aninterestingwebsite.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
74
Sep ’25
StoreKit 2 – IAP Subscriptions Not Appearing in Sandbox
I am experiencing an issue with my iOS app where StoreKit 2 in-app subscriptions are not appearing when using Product.products(for:). I have done all the necessary configurations, but the products still return an empty array ([]). Here are the details of my setup: • App ID / Bundle ID: com.tstore.vocabely • Product IDs: • com.tstore.vocabely.base • com.tstore.vocabely.pro • com.tstore.vocabely.ultimate • Paid Apps Agreement: Active • IAP Status in App Store Connect: Ready to Submit / Approved • Testing Environment: • Device: iPhone (real device) • iOS Version: [insert your iOS version] • Xcode Version: [insert your Xcode version] • Sandbox Tester Account used • Code Snippet: Using Product.products(for: productIDs) in StoreKitManager to fetch products I have verified: • Product IDs match exactly with App Store Connect • Paid Apps Agreement is Active • Using a real device, not a simulator • Sandbox account is properly signed in Despite all of this, fetchProducts() still returns an empty array. Could you please assist me in troubleshooting why my subscriptions are not appearing in the Sandbox environment? Thank you for your support.
Replies
2
Boosts
0
Views
135
Activity
Aug ’25
StoreKit returns restored for SKUs marked Consumable (no purchase sheet); Flutter in_app_purchase + SK2
What platform are you targeting? And what version? iOS, testing in Sandbox on a physical device. What version of Xcode are you using? [Xcode __] What version of the OS are you testing on? iOS 18 on iPhone 15 pro. What specific API are you using? StoreKit 2 via Flutter’s in_app_purchase plugin (Dart), which uses in_app_purchase_storekit under the hood. What are the exact steps you took? In App Store Connect, I created several Consumable IAPs (status “Ready to Submit”). Example product IDs: USD3.99TenMinuteCoffeePlan (Consumable) USD24.99OneHourDinnerPlan (Consumable) USD14.99InviteAFriendAsGenie (Consumable) Signed in as a Sandbox tester on device (Settings → App Store → Sandbox Account). App queries products with InAppPurchase.instance.queryProductDetails(ids) — products load successfully. Call buyConsumable(purchaseParam: PurchaseParam(productDetails: ...)). Listen to purchaseStream and log PurchaseDetails. If something failed, what are the symptoms? The purchase sheet often does not appear. The purchase stream reports PurchaseStatus.restored, immediately, for SKUs that are marked Consumable. Example log lines (from Dart): Products loaded: 6 Product: id=USD3.99TenMinuteCoffeePlan, price=3.99 Product: id=USD24.99OneHourDinnerPlan, price=24.99 Product: id=USD14.99InviteAFriendAsGenie, price=14.99 Purchase update: productID=USD3.99TenMinuteCoffeePlan, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000000991974131 Purchase update: productID=USD24.99OneHourDinnerPlan, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000000992079251 Purchase update: productID=USD14.99InviteAFriendAsGenie, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000000999910991 Purchase update: productID=USD29.99InviteAFriendAsGenie, status=PurchaseStatus.restored, pendingComplete=false, purchaseID=2000001003571920 If nothing failed, what results did you see? And what were you expecting? Actual: restored events (no sheet) for items configured as Consumable. Expected: For Consumables, a purchase sheet followed by purchased status. Consumables shouldn’t “restore”. What else have you tried? Verified every SKU shows Type = Consumable and Ready to Submit in App Store Connect; “Cleared for Sale” enabled; pricing/localization filled. Created new product IDs (to avoid any prior non-consumable history). Verified I’m not calling restorePurchases. In the listener, I only grant benefits on PurchaseStatus.purchased (not on restored). Observed that queryProductDetails succeeds; some IDs that aren’t fully configured return “not found,” as expected. Minimal code (core bits): final _iap = InAppPurchase.instance; Future<void> init() async { final resp = await _iap.queryProductDetails({ 'USD3.99TenMinuteCoffeePlan', 'USD24.99OneHourDinnerPlan', 'USD14.99InviteAFriendAsGenie', 'USD29.99InviteAFriendAsGenie', }); _products = resp.productDetails; _sub = _iap.purchaseStream.listen(_onUpdates); } Future<void> buy(ProductDetails p) async { final param = PurchaseParam(productDetails: p); await _iap.buyConsumable(purchaseParam: param); // iOS SK2 path } void _onUpdates(List<PurchaseDetails> list) async { for (final pd in list) { print('status=${pd.status}, id=${pd.productID}, pending=${pd.pendingCompletePurchase}, purchaseID=${pd.purchaseID}'); switch (pd.status) { case PurchaseStatus.purchased: // deliver & (if pendingCompletePurchase) completePurchase break; case PurchaseStatus.restored: // for consumables, I do not deliver here break; default: break; } } } Questions for the community/Apple: Under what conditions would StoreKit 2 return restored for a SKU that’s set to Consumable? Is there any server-side caching of old product type or ownership tied to a product ID that could cause this in Sandbox? Is “Ready to Submit” sufficient for Sandbox testing of IAPs, or must the SKUs be attached to a submitted build before StoreKit treats them as consumable? If a product ID was ever created/purchased as Non-Consumable historically, does creating a new ASC entry with the same string ID as Consumable still cause restored for that tester? Besides creating brand-new product IDs and/or resetting the Sandbox tester’s purchase history, is there any other recommended way to clear this state? Happy to provide a device sysdiagnose or a stripped test project if that helps. Thanks!
Replies
0
Boosts
0
Views
188
Activity
Sep ’25
In iOS 26 beta3 version, the finishTransaction method is unable to remove transactions from the SKPaymentQueue, causing transactions to remain in the queue even after being processed.
We have some users who have upgraded to iOS 26 beta3. Currently, we observe that when these users make in-app purchases, our code calls [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; method, and we clearly receive the successful removal callback in the delegate method - (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions. However, when users click on products with the same productId again, the method - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions still returns information about previously removed transactions, preventing users from making further in-app purchases.
Replies
4
Boosts
0
Views
344
Activity
Jul ’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
107
Activity
Sep ’25
Migrating to StoreKit 2
Hi Friends, I have an iOS app, which uses around 500 in app purchases for various modules. I am using StoreKit for in app purchase, now trying to migrate this to StoreKit 2. I am using Product.products(for:) method to fetch all the products by sending identifiers of all the 500 In app purchases. In response, I am getting details of only 160 products, the method is not returning remaining in app purchases. What could be the reason for this behaviour, how to get rid of the issue? May be is this the issue will happen only on TestFlight? If someone from Apple assures about it, we have plan to submit the app. Please advise, Thank you.
Replies
0
Boosts
0
Views
108
Activity
May ’25
(verifyreceipt) I cannot verify from the server whether the user's iap payment is successful or not
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://aninterestingwebsite.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) 2. I can not understand this document: (https://aninterestingwebsite.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? 3. 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
0
Boosts
0
Views
78
Activity
Aug ’25
How to check if user still have valid subscription?
Is there an API Endpoint that I can call to check if user still have valid subscription? I want to be sure that his subscription renewal was succesful (ie: I dont want to give him another month/year/.. if his latest renewal wasnt successful) Would GET https://api.storekit.itunes.apple.com/inApps/v1/transactions/{transactionId} be the correct API endpoint to call? But I wonder, after subscription auto-renews, do we still use the same transactionId to check whether his subs is still valid?
Replies
0
Boosts
0
Views
54
Activity
Jul ’25
Cannot received webhook about in app purchase
Previously I could get the sub package information after each payment via webhook but today I didn't get it. What happened? My webhook url: https://r-connect-api-dev.mystg-env.com/webhook/appstore/notification/v2
Replies
0
Boosts
0
Views
51
Activity
Nov ’25
subscriptionGroupLookups API returns 404 - No LookUp Key assigned to my subscription group
Hello, I'm encountering an issue when trying to use the subscriptionGroupLookups endpoint in the App Store Connect API. Despite having the correct setup, I continue to receive a 404 NOT FOUND error when making requests to: GET https://api.appstoreconnect.apple.com/v1/subscriptionGroupLookups Here is the current state of my environment: I am the Account Holder of the App Store Connect account The App Store Connect API key has been successfully created I have the correct Key ID, Issuer ID, and .p8 private key I can authenticate and access the apps and subscriptionGroups endpoints However, the subscriptionGroupLookups endpoint always returns: { "errors": [ { "status": "404", "code": "NOT_FOUND", "title": "The specified resource does not exist" } ] } I suspect that LookUp Keys (UUIDs) have not been assigned to our subscription groups, even though they were created and are active in App Store Connect. There is no “Request Access” button visible under the Integrations tab (as mentioned in Apple support instructions), and my keys appear under “App Store Connect API” > “Keys” as active. Questions: How can I ensure that LookUp Keys are assigned to my subscription groups? Is there a way to trigger this manually or via support? Has anyone successfully resolved this? Any advice or experience would be greatly appreciated. Thank you!
Replies
0
Boosts
0
Views
98
Activity
May ’25
[Bug/Doc Discrepancy] App Store Server API "price" field does not include quantity as documentation states
According to the App Store Server API documentation , https://aninterestingwebsite.com/documentation/appstoreserverapi/price the price field "shows the total amount of the transaction for the quantity the customer purchased." However, in actual transaction notifications and responses from App Store Server API, the price field appears to represent the unit price, not the total price. For consumable in-app purchases with quantity > 1, the price field equals the unit price of a single item. The total user payment is only correct after multiplying by the quantity. When quantity > 1, the actual amount paid by the user only matches price × quantity, which contradicts the documentation. Please confirm whether the price field is intended to be: The unit price of a single item (requiring multiplication by quantity), or The total price including all quantities (as currently documented). If the former is correct, please update the documentation to clarify that the value represents the unit price, not the total amount.
Replies
0
Boosts
0
Views
46
Activity
Oct ’25
in-app purchases
I implemented consumable in-app purchases in an iPhone app using ProductView(). When I tap the payment button in ProductView(), I am taken to the payment screen and once the payment is completed the next code seems to be executed, so there doesn't seem to be a problem, but if I tap the payment button in ProductView() again, the next code is executed without taking me to the payment screen. This means that a single payment can be made multiple times. Can someone help? ProductView(id: "geminiOneMatch") .productViewStyle(.compact) .padding() .onInAppPurchaseCompletion { product, result in if case .success(.success(_)) = result { // 課金が成功した場合の処理 gemini.addOneMatch(amount: 20) popUpVM.geminiOneMatchPopUp = false dataManageVM.generateRespons(locale: locale) } }
Replies
0
Boosts
0
Views
250
Activity
Jul ’25
Guidance on Migrating Active Subscriptions from Apple Server Notifications v1 to v2
I’m reaching out regarding our existing in-app subscription implementation that currently uses App Store Server Notifications version 1 (v1). Our live application has a significant number of active recurring subscriptions that are being managed through the v1 webhook integration. We have now developed a revamped version of our application, which uses the same Apple Developer Account and App Store Connect setup, but in this new app version, we’ve implemented App Store Server Notifications version 2 (v2). Before moving forward with the migration, I would like to clarify the following points to ensure a smooth transition and avoid any disruptions to ongoing subscriptions: Backward Compatibility: Will existing active subscriptions (originally created and managed via v1 notifications) continue to work seamlessly once we switch to v2, or do we need to maintain both v1 and v2 endpoints during the transition? Notification Delivery: If both webhook versions are configured simultaneously, will Apple send notifications to both endpoints, or only the one currently configured in App Store Connect? Migration Strategy: What is Apple’s recommended best practice for migrating from v1 to v2 in a scenario where the live app still has active subscriptions tied to the v1 webhook? Potential Risks or Considerations: Are there any known limitations, delays, or issues that we should prepare for during this migration (for example, differences in payload structure or event types between v1 and v2 that could affect subscription lifecycle management)? I would greatly appreciate your guidance or documentation links that outline the correct migration steps and recommended approach for ensuring continuity of service for all existing subscribers.
Replies
0
Boosts
0
Views
145
Activity
Oct ’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
68
Activity
Sep ’25
Clarification Needed: Using action=write-review outside of the app
Hello, is it allowed to include the action=write-review URL parameter in customer support emails to direct users to the App Store review page? Example: https://apps.apple.com/app/id[APP_ID]?action=write-review I want to make it easy for customers to leave feedback after positive support interactions, but only if it's compliant.
Replies
0
Boosts
0
Views
134
Activity
Oct ’25
integrating In-App Purchases on PWA.
I am trying to launch a PWA as an application on App Store, and got rejected cause of In-App Purchases. Application is about content generation and selling subscriptions for premium content. So thats why needed to implement In-App Purchases. I have created wrapper via PWABuilder. And it is looking great so far, now my question is about How can I implement In-App Purchases in the bundle which is already created. Any suggestions will be appreciated. More clarification:- I have that product running on Web right now, we have integrated Stripe for payment handling for subscriptions. If there is nothing we can do for In-App Purchases then we have to make purchases on website and then user will be able to experience the changes. We tried that, but then we got rejected for showing locked premium content on user's feed. Also can't show any CTA or Subscribe text or button.
Replies
0
Boosts
0
Views
148
Activity
Jul ’25
Encountered issues when calling the sandbox environment interface to verify receipts during the development of the payment function
Currently, we are using the Apple V2 interface to develop the payment function. We generate a transaction ID on the mobile client and obtain the receipt. Now, when we call the Apple sandbox environment interface to verify the receipt, we always get a 404 error. The above is the request and response. The token used in it is also the original data after decoding, and there is no problem. Could you help me figure out what other possible reasons there might be?
Replies
0
Boosts
0
Views
45
Activity
Oct ’25
"In-App Purchases are not allowed" Error Persists After All Troubleshooting Steps
Hello, I am consistently receiving the error message "In-app purchases are not allowed on this device" whenever I try to make an in-app purchase on my iOS device. Despite following all the recommended solutions I could find online, the issue remains unresolved. Here is a list of the steps I have already taken: Checked Screen Time Settings: I navigated to Settings > Screen Time > Content & Privacy Restrictions > iTunes & App Store Purchases. I have confirmed that "In-App Purchases" is set to "Allow." I have also tried toggling this setting off and on again. Signed Out & In of Apple ID: I signed out of my Apple ID via Settings > [Your Name] > Media & Purchases, restarted the device, and then signed back in. Restarted the Device: I have force-restarted my device multiple times. Updated iOS: I have ensured my device is running the latest version of iOS (checked via Settings > General > Software Update). Verified Payment Method: I have confirmed that my payment method on file is valid and up-to-date. Created a New Sandbox Account: I also created a new Sandbox Tester account in App Store Connect and tested with it, but the result was the same. Device Information: Device Model: iPhone 15, iPhone 13 iOS Version: iOS 17.5, iOS 18 Even after performing all of these steps, the problem persists. Has anyone else encountered such a stubborn issue, or does anyone have a different solution I could try? Thank you in advance for your help.
Replies
0
Boosts
0
Views
230
Activity
Jul ’25
App store payment screen not showing
Hello I am trying to add payments on my app. I have added all products I need in subscriptions. I also tried by using storekit but from my understanding testing with storekit is nothing to rely on. My app works on Android (with the same product IDs same unction call) iOS is not why is that?
Replies
1
Boosts
0
Views
58
Activity
Sep ’25
react native iap not providing the subscription information
I am handling the buy subscription with this function const handleBuySubscription = async (productId) =&gt; { try { await requestSubscription({ sku: productId, }); setLoading(false); } catch (error) { setLoading(false); if (error instanceof PurchaseError) { errorLog({ message: [${error.code}]: ${error.message}, error }); } else { errorLog({ message: "handleBuySubscription", error }); } } }; but the requestSubscription({ sku: productId, }) does not return anything, and it is stuck at await
Replies
0
Boosts
0
Views
83
Activity
Aug ’25
Delete Offer Codes
Regarding the offer codes in https://aninterestingwebsite.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://aninterestingwebsite.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
74
Activity
Sep ’25