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

Issue with UPI IAP Transactions Stuck in Pending State and No Rewards Granted
Hi everyone, We’ve encountered an issue in some of our games where IAP purchases made using UPI are going into a pending state. Since these purchases are for consumable items, the rewards are not granted at the time of purchase. Even after the transactions are eventually confirmed, the rewards still aren't received. We tested this with two separate UPI transactions, and both resulted in the same pending state issue. Interestingly, when we tried making a purchase using Apple Wallet afterward, the transaction completed successfully on the first attempt, without any pending state. This issue seems specific to UPI transactions. Could anyone help us understand why this is happening or if there’s a recommended way to handle such cases? Thanks in advance!
0
0
80
Apr ’25
subscriptions before submitting a review
We distribute apps that offer auto-renewing subscriptions. In order to test a new service, we would like to create a new subscription group and subscription product (hereinafter referred to as “test subscription”) for this app. If the “In-app purchase statuses” of the test subscription is “Ready to Submit” is the following behavior correct? ・General end users cannot purchase the test subscription. ・Users with SANDBOX Apple accounts can purchase the test subscription.
1
0
88
Aug ’25
AppStore response times for the store test environment to make purchases is very long.
Currently, over the xcode environment to do the testing of product subscriptions through appstore are working correctly using the storeKit. When deployed in testflight to do the testing over the integration environment, the store response times are being excessively high, in excess of 20 minutes. This behavior is not replicated on Xcode, and is happening on recent versions uploaded to testflight, as earlier versions that were already tested and are currently in production. In addition the communication between the appstore webhook and the BE is also failing in this environment. It is being blocked to generate any test to be able to launch to production.
1
0
214
Apr ’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
Inconsistent appTransactionId in Transaction History
Issue Description When using the App Store Server API endpoint GET v2/history/{transactionId} to retrieve transaction history for a specific transaction, I'm observing unexpected changes in the appTransactionId field across related transactions in the same subscription group. Important Context: This is a "clean" auto-renewable subscription with no user intervention - the user has had continuous auto-renewals without any upgrades, downgrades, cancellations, or resubscriptions. The subscription has been renewing automatically and successfully throughout the entire period. API Call GET v2/history/1000000000000001 Response Data The API returns the following transaction history, where I notice the appTransactionId values are inconsistent across what should be a straightforward auto-renewal sequence: Note: The data below has been sanitized for privacy protection (IDs, bundle identifiers, etc. have been replaced with example values), but the logical relationships, date sequences, and the core issue remain identical to the original data. Array ( [0] => Array ( [transactionId] => 1000000000000001 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000001 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1743784032000 [originalPurchaseDate] => 1743784034000 [expiresDate] => 1746376032000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => PURCHASE // Original purchase [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000001 // Different value ) [1] => Array ( [transactionId] => 1000000000000002 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000002 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1746376032000 [originalPurchaseDate] => 1746347349000 [expiresDate] => 1749054432000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => RENEWAL // First auto-renewal [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000002 // Same for renewals ) [2] => Array ( [transactionId] => 1000000000000003 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000003 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1749054432000 [originalPurchaseDate] => 1749025657000 [expiresDate] => 1751646432000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => RENEWAL // Second auto-renewal [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000002 // Same as previous renewal ) [3] => Array ( [transactionId] => 1000000000000004 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000004 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1751646432000 [originalPurchaseDate] => 1751617840000 [expiresDate] => 1754324832000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => RENEWAL // Third auto-renewal [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000002 // Same as previous renewals ) ) Questions Is this behavior expected? Should the appTransactionId change between the original purchase and subsequent renewals within the same subscription group, especially when there are no user actions (upgrades/downgrades/cancellations/resubscriptions)? What determines the appTransactionId value? The documentation doesn't clearly explain when this identifier might change or what triggers a new value. This is particularly puzzling since this is a straightforward auto-renewal scenario. How should we handle this in our backend logic? Should we treat transactions with different appTransactionId values as separate entities, or should we rely on originalTransactionId for grouping related subscription transactions? Is this a known issue? We've seen similar concerns in the community regarding transaction ID inconsistencies, but this specific case involves a clean auto-renewal flow without any complicating factors.
1
0
180
Jul ’25
IAP Product Info Error & Sandbox Webhook/Test API Failures
Hello, I'm suddenly encountering errors with In-App Purchases (IAP) and my sandbox webhooks, which were working correctly just a few days ago. Specifically: Product Information Error: I'm receiving the following error when trying to fetch product information: { "type": "product_info", "result": "error", "error": "An unknown error occurred" } This API call was functioning normally until today. Sandbox Webhook Failure: I have configured a sandbox webhook, but my server is not receiving any notifications from the App Store. Test API 401: When I attempt to call the test API (https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/test), I consistently receive a 401 (Unauthorized) error. Could you please provide some guidance on how to troubleshoot these issues? Thank you.
1
0
111
Nov ’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://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) 2. 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? 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
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
How to switch in-app-purchases from sandbox to production?
Hello all, I am new to implementing payments in an app, and thus completely at sea here. I have created a small app that I have set a one-time (non-consumable) payment for a premium version. In the Xcode simulator (on all platforms) and on any physical test devices I have tried, the payment works as expected. I have a sandbox account and various test accounts, both dummy and actual real accounts (friends and family). Everywhere everything works perfectly fine. Yet, when I submit for review I get a rejection with this contents: We found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, the app still failed to load the in-app purchase. Please review the details and resources below and complete the next steps. Review device details: Device type: iPad Air (5th generation) OS version: iPadOS 18.6 Next Steps When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code "Sandbox receipt used in production," you should validate against the test environment instead. Additionally, note that the Account Holder must accept the Paid Apps Agreement in the Business section of App Store Connect before paid in-app purchases will function. Resources Learn how to set up and test in-app purchase products in >the sandbox environment. Learn more about validating receipts with the App Store. Steps I have done: I have signed all agreements and all bank account details are in order. Everything in the In-app-purchases section of the AppStoreConnect in an Active state. I have triple checked that the configuration of the in-app purchases is correct (product IDs, amounts, etc.) I have created test accounts and tested in sandbox What I don't understand from the reviewer's response is what receipts validation are they talking about? I have no payment servers (the whole concept of using Apple's in-app-purchases service is to not have to deal with my own payment implementation). The StoreKit documentation specifically reads: For each transaction that represents a current purchase, your app delivers the purchased products. To validate purchases, you can verify transactions on your server, or rely on StoreKit’s verification. So now I am confused. The reviewer's response is so vague, and so completely deprived of details that I have no idea what to do... Does the problem concern the product purchase trigger and the that in production environment it does not trigger? Is it that I haven't implemented a receipt validation? Do I need to? Although the documentation mentions that it can be done by StoreKit, I couldn't find anything concerning how to do it :( Can someone give me a hand please? Cheers, Alex
3
0
365
Oct ’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
336
Jul ’25
Show Price Increase Consent
I'm currently still on StoreKit 1, and am testing the paymentQueueShouldShowPriceConsent delegate function. In my local .storekit file, I have a renewable subscription set up with a promotional offer. My test flow is as follows: User subscribes to renewable subscription Let subscription auto-renew once or twice User subscribes to renewable subscription with promotional offer with significant price reduction Promotional offer lapses and price increases to normal Expect paymentQueueShouldShowPriceConsent delegate function to trigger However, #5 never does get invoked, despite re-trying the subscription and promotional offers in various configurations. Manually triggering the Request Price Increase Consent option in the Xcode StoreKit transactions list does invoke the delegate function, but letting the promotional offer lapse does not. My storefront is set to Korea, and my simulator region is set to Korea as well. According to the documentation here and here, consent is required for all price increases in Korea. Is there some way I could check if things are working as intended?
0
0
92
Apr ’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://developer.apple.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
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
How to handle subscription notifications with future purchase date
Our app server has subscription feature and processes purchase life cycles based on App Store Server Notification v1. Last year, when users purchased subscriptions during the following timeframe, we received "INITIAL_BUY" notifications with "unified_receipt.Latest_receipt_info.purchase_date" set to future date(approx. 1 hour after the actual purchase). 2024-11-03 08:00:00 - 2024-11-03 09:00:00 Etc/GMT (UTC) For example, we received the following v1 notification at 2024-11-03 08:36:33 Etc/GMT. "notification_type": "INITIAL_BUY" "unified_receipt.latest_receipt_info[].purchase_date": "2024-11-03 09:36:02 Etc/GMT" Our server grants subscription entitlement based on "purchase_date" so the users had to wait 1 hour before the subscription features became available. The timeframe coincided with the end of daylight saving time in the U.S., so we assume that it affected the behavior, but our country doesn't adopt daylight saving time. We have some questions regarding this behavior. In countries without daylight saving time, how should we handle such notifications with future purchase date in order to properly grant subscription entitlement? In App Store Server Notification v2, could purchase date be set to future date at the end of daylight saving time in the U.S., just as in v1 notifications? JWSTransactionDecodedPayload.purchaseDate
0
0
103
May ’25
IAPs after rejection
Hi everyone, After my app was initially rejected, all my IAPs now show the status “Developer Action Needed.” There’s nothing I need to change on them — they were just returned because it was the first submission and the app itself was rejected. Do I need to do anything with the IAPs before I resubmit, or will they still be attached and reviewed automatically with the next binary? I’ve seen conflicting answers, so I’d like to confirm the correct process. Thanks, Cris
1
0
109
Aug ’25
Validating Mac App Store purchase with StoreKit
For years I've been using Receigen for receipt verification for the Mac App Store build of my application. However, with the deprecation of exit code 173, I am moving to StoreKit-based verification and have a couple of questions. I have followed the instructions from https://developer.apple.com/documentation/storekit/apptransaction/shared and have something like this (simplified): Swift: @objc class ValidateReceipt: NSObject { @objc func validate() async -> Bool { do { let verificationResult = try await AppTransaction.shared switch verificationResult { case .verified(_ /*let appTransaction*/): // StoreKit verified that the user purchased this app and // the properties in the AppTransaction instance return true; default: // The app transaction didn't pass StoreKit's verification return false; } } catch { // Handle errors return false; } } } Objective-C: ValidateReceipt *validateReceipt = [[ValidateReceipt alloc] init]; [validateReceipt validateWithCompletionHandler:^(BOOL result) { if (result) { // Successful app purchase validation } else { // App purchase validation failure } }]; Thing is, I always get a valid result, i.e., in ValidReceipt.validate(), the case .verified block always runs. Even when exporting a new release build of my app and running it (without any _MASReceipt). When using exit code 173, an .app without a _MASReceipt would prompt for app store login. Nothing of the sort happens now. Am I misunderstanding the documentation / doing something wrong / missing something obvious?
5
0
546
Sep ’25
Issue with UPI IAP Transactions Stuck in Pending State and No Rewards Granted
Hi everyone, We’ve encountered an issue in some of our games where IAP purchases made using UPI are going into a pending state. Since these purchases are for consumable items, the rewards are not granted at the time of purchase. Even after the transactions are eventually confirmed, the rewards still aren't received. We tested this with two separate UPI transactions, and both resulted in the same pending state issue. Interestingly, when we tried making a purchase using Apple Wallet afterward, the transaction completed successfully on the first attempt, without any pending state. This issue seems specific to UPI transactions. Could anyone help us understand why this is happening or if there’s a recommended way to handle such cases? Thanks in advance!
Replies
0
Boosts
0
Views
80
Activity
Apr ’25
subscriptions before submitting a review
We distribute apps that offer auto-renewing subscriptions. In order to test a new service, we would like to create a new subscription group and subscription product (hereinafter referred to as “test subscription”) for this app. If the “In-app purchase statuses” of the test subscription is “Ready to Submit” is the following behavior correct? ・General end users cannot purchase the test subscription. ・Users with SANDBOX Apple accounts can purchase the test subscription.
Replies
1
Boosts
0
Views
88
Activity
Aug ’25
AppStore response times for the store test environment to make purchases is very long.
Currently, over the xcode environment to do the testing of product subscriptions through appstore are working correctly using the storeKit. When deployed in testflight to do the testing over the integration environment, the store response times are being excessively high, in excess of 20 minutes. This behavior is not replicated on Xcode, and is happening on recent versions uploaded to testflight, as earlier versions that were already tested and are currently in production. In addition the communication between the appstore webhook and the BE is also failing in this environment. It is being blocked to generate any test to be able to launch to production.
Replies
1
Boosts
0
Views
214
Activity
Apr ’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
Inconsistent appTransactionId in Transaction History
Issue Description When using the App Store Server API endpoint GET v2/history/{transactionId} to retrieve transaction history for a specific transaction, I'm observing unexpected changes in the appTransactionId field across related transactions in the same subscription group. Important Context: This is a "clean" auto-renewable subscription with no user intervention - the user has had continuous auto-renewals without any upgrades, downgrades, cancellations, or resubscriptions. The subscription has been renewing automatically and successfully throughout the entire period. API Call GET v2/history/1000000000000001 Response Data The API returns the following transaction history, where I notice the appTransactionId values are inconsistent across what should be a straightforward auto-renewal sequence: Note: The data below has been sanitized for privacy protection (IDs, bundle identifiers, etc. have been replaced with example values), but the logical relationships, date sequences, and the core issue remain identical to the original data. Array ( [0] => Array ( [transactionId] => 1000000000000001 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000001 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1743784032000 [originalPurchaseDate] => 1743784034000 [expiresDate] => 1746376032000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => PURCHASE // Original purchase [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000001 // Different value ) [1] => Array ( [transactionId] => 1000000000000002 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000002 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1746376032000 [originalPurchaseDate] => 1746347349000 [expiresDate] => 1749054432000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => RENEWAL // First auto-renewal [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000002 // Same for renewals ) [2] => Array ( [transactionId] => 1000000000000003 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000003 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1749054432000 [originalPurchaseDate] => 1749025657000 [expiresDate] => 1751646432000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => RENEWAL // Second auto-renewal [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000002 // Same as previous renewal ) [3] => Array ( [transactionId] => 1000000000000004 [originalTransactionId] => 1000000000000001 [webOrderLineItemId] => 1000000000000004 [bundleId] => com.example.myapp [productId] => MonthlySubscription [subscriptionGroupIdentifier] => 20000000 [purchaseDate] => 1751646432000 [originalPurchaseDate] => 1751617840000 [expiresDate] => 1754324832000 [quantity] => 1 [type] => Auto-Renewable Subscription [inAppOwnershipType] => PURCHASED [signedDate] => 1751868174651 [environment] => Production [transactionReason] => RENEWAL // Third auto-renewal [storefront] => USA [storefrontId] => 143441 [price] => 100000 [currency] => USD [appTransactionId] => 700000000000000002 // Same as previous renewals ) ) Questions Is this behavior expected? Should the appTransactionId change between the original purchase and subsequent renewals within the same subscription group, especially when there are no user actions (upgrades/downgrades/cancellations/resubscriptions)? What determines the appTransactionId value? The documentation doesn't clearly explain when this identifier might change or what triggers a new value. This is particularly puzzling since this is a straightforward auto-renewal scenario. How should we handle this in our backend logic? Should we treat transactions with different appTransactionId values as separate entities, or should we rely on originalTransactionId for grouping related subscription transactions? Is this a known issue? We've seen similar concerns in the community regarding transaction ID inconsistencies, but this specific case involves a clean auto-renewal flow without any complicating factors.
Replies
1
Boosts
0
Views
180
Activity
Jul ’25
Sandbox Account
When trying to login with sandbox account in my simulator, nothing happens, it just become inactive for few seconds and then it become active again prompting that I can login, again and again.
Replies
1
Boosts
0
Views
183
Activity
Sep ’25
Storekit2 Some device failure unknown
iOS Storekit2 Appstore production environment, some user feedback in app purchase faliure, What our log records is StoreKitError.unknown,please How to solve problem, thanks
Replies
1
Boosts
0
Views
122
Activity
Apr ’25
IAP Product Info Error & Sandbox Webhook/Test API Failures
Hello, I'm suddenly encountering errors with In-App Purchases (IAP) and my sandbox webhooks, which were working correctly just a few days ago. Specifically: Product Information Error: I'm receiving the following error when trying to fetch product information: { "type": "product_info", "result": "error", "error": "An unknown error occurred" } This API call was functioning normally until today. Sandbox Webhook Failure: I have configured a sandbox webhook, but my server is not receiving any notifications from the App Store. Test API 401: When I attempt to call the test API (https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/test), I consistently receive a 401 (Unauthorized) error. Could you please provide some guidance on how to troubleshoot these issues? Thank you.
Replies
1
Boosts
0
Views
111
Activity
Nov ’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://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) 2. 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? 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
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
132
Activity
Oct ’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
How to switch in-app-purchases from sandbox to production?
Hello all, I am new to implementing payments in an app, and thus completely at sea here. I have created a small app that I have set a one-time (non-consumable) payment for a premium version. In the Xcode simulator (on all platforms) and on any physical test devices I have tried, the payment works as expected. I have a sandbox account and various test accounts, both dummy and actual real accounts (friends and family). Everywhere everything works perfectly fine. Yet, when I submit for review I get a rejection with this contents: We found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, the app still failed to load the in-app purchase. Please review the details and resources below and complete the next steps. Review device details: Device type: iPad Air (5th generation) OS version: iPadOS 18.6 Next Steps When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code "Sandbox receipt used in production," you should validate against the test environment instead. Additionally, note that the Account Holder must accept the Paid Apps Agreement in the Business section of App Store Connect before paid in-app purchases will function. Resources Learn how to set up and test in-app purchase products in >the sandbox environment. Learn more about validating receipts with the App Store. Steps I have done: I have signed all agreements and all bank account details are in order. Everything in the In-app-purchases section of the AppStoreConnect in an Active state. I have triple checked that the configuration of the in-app purchases is correct (product IDs, amounts, etc.) I have created test accounts and tested in sandbox What I don't understand from the reviewer's response is what receipts validation are they talking about? I have no payment servers (the whole concept of using Apple's in-app-purchases service is to not have to deal with my own payment implementation). The StoreKit documentation specifically reads: For each transaction that represents a current purchase, your app delivers the purchased products. To validate purchases, you can verify transactions on your server, or rely on StoreKit’s verification. So now I am confused. The reviewer's response is so vague, and so completely deprived of details that I have no idea what to do... Does the problem concern the product purchase trigger and the that in production environment it does not trigger? Is it that I haven't implemented a receipt validation? Do I need to? Although the documentation mentions that it can be done by StoreKit, I couldn't find anything concerning how to do it :( Can someone give me a hand please? Cheers, Alex
Replies
3
Boosts
0
Views
365
Activity
Oct ’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
336
Activity
Jul ’25
An In-App Purchase has been returned
There is a warning message displays in my itune connect's In App Purchase page but there is nothing highlighted in the table. This is very stange. Is there anyone having the same problem? Or can anyone help?
Replies
33
Boosts
0
Views
19k
Activity
Feb ’26
Show Price Increase Consent
I'm currently still on StoreKit 1, and am testing the paymentQueueShouldShowPriceConsent delegate function. In my local .storekit file, I have a renewable subscription set up with a promotional offer. My test flow is as follows: User subscribes to renewable subscription Let subscription auto-renew once or twice User subscribes to renewable subscription with promotional offer with significant price reduction Promotional offer lapses and price increases to normal Expect paymentQueueShouldShowPriceConsent delegate function to trigger However, #5 never does get invoked, despite re-trying the subscription and promotional offers in various configurations. Manually triggering the Request Price Increase Consent option in the Xcode StoreKit transactions list does invoke the delegate function, but letting the promotional offer lapse does not. My storefront is set to Korea, and my simulator region is set to Korea as well. According to the documentation here and here, consent is required for all price increases in Korea. Is there some way I could check if things are working as intended?
Replies
0
Boosts
0
Views
92
Activity
Apr ’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://developer.apple.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
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
How to handle subscription notifications with future purchase date
Our app server has subscription feature and processes purchase life cycles based on App Store Server Notification v1. Last year, when users purchased subscriptions during the following timeframe, we received "INITIAL_BUY" notifications with "unified_receipt.Latest_receipt_info.purchase_date" set to future date(approx. 1 hour after the actual purchase). 2024-11-03 08:00:00 - 2024-11-03 09:00:00 Etc/GMT (UTC) For example, we received the following v1 notification at 2024-11-03 08:36:33 Etc/GMT. "notification_type": "INITIAL_BUY" "unified_receipt.latest_receipt_info[].purchase_date": "2024-11-03 09:36:02 Etc/GMT" Our server grants subscription entitlement based on "purchase_date" so the users had to wait 1 hour before the subscription features became available. The timeframe coincided with the end of daylight saving time in the U.S., so we assume that it affected the behavior, but our country doesn't adopt daylight saving time. We have some questions regarding this behavior. In countries without daylight saving time, how should we handle such notifications with future purchase date in order to properly grant subscription entitlement? In App Store Server Notification v2, could purchase date be set to future date at the end of daylight saving time in the U.S., just as in v1 notifications? JWSTransactionDecodedPayload.purchaseDate
Replies
0
Boosts
0
Views
103
Activity
May ’25
IAPs after rejection
Hi everyone, After my app was initially rejected, all my IAPs now show the status “Developer Action Needed.” There’s nothing I need to change on them — they were just returned because it was the first submission and the app itself was rejected. Do I need to do anything with the IAPs before I resubmit, or will they still be attached and reviewed automatically with the next binary? I’ve seen conflicting answers, so I’d like to confirm the correct process. Thanks, Cris
Replies
1
Boosts
0
Views
109
Activity
Aug ’25
Validating Mac App Store purchase with StoreKit
For years I've been using Receigen for receipt verification for the Mac App Store build of my application. However, with the deprecation of exit code 173, I am moving to StoreKit-based verification and have a couple of questions. I have followed the instructions from https://developer.apple.com/documentation/storekit/apptransaction/shared and have something like this (simplified): Swift: @objc class ValidateReceipt: NSObject { @objc func validate() async -> Bool { do { let verificationResult = try await AppTransaction.shared switch verificationResult { case .verified(_ /*let appTransaction*/): // StoreKit verified that the user purchased this app and // the properties in the AppTransaction instance return true; default: // The app transaction didn't pass StoreKit's verification return false; } } catch { // Handle errors return false; } } } Objective-C: ValidateReceipt *validateReceipt = [[ValidateReceipt alloc] init]; [validateReceipt validateWithCompletionHandler:^(BOOL result) { if (result) { // Successful app purchase validation } else { // App purchase validation failure } }]; Thing is, I always get a valid result, i.e., in ValidReceipt.validate(), the case .verified block always runs. Even when exporting a new release build of my app and running it (without any _MASReceipt). When using exit code 173, an .app without a _MASReceipt would prompt for app store login. Nothing of the sort happens now. Am I misunderstanding the documentation / doing something wrong / missing something obvious?
Replies
5
Boosts
0
Views
546
Activity
Sep ’25