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

react native iap not providing the subscription information
I am handling the buy subscription with this function const handleBuySubscription = async (productId) => { 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
78
Aug ’25
Download ID in AppTransaction
Hello, I would like to draw your attention to the following imperfection. For validating purchases of my paid application Guru Maps Pro, I use the download id. This is a unique ID that can replace the Transaction ID for paid applications. However, with the release of the new AppTransaction API, this field is no longer present in the data. I tried parsing the receipt, but that field is absent there as well. The only way to obtain the download id is to send the receipt to the deprecated /verifyReceipt endpoint. This deprecated status concerns me, because at some point it might stop working. Let me explain a little about why I need this. My users have a guru-account, which they can use both in the web version and on Android. When a user purchases the paid version of the application, they can access the paid features on both web and Android. This works great for in-app purchases, where there is a transaction ID, but it may soon stop working for paid applications because there is no way to determine any ID associated with the purchase. Transaction ID or Download ID – I don't mind which.
0
0
322
Feb ’25
My Subscription Screen
Hey everyone, This might be a simple fix that I’m just overlooking, but I’ve been stuck on it for the past 48 hours. The issue is on my subscription screen — after a user completes a successful in-app purchase, the app doesn’t navigate to the main app like it’s supposed to. I’ve added logs, tried various fixes, and even asked AI for help, but nothing has worked. From what I can tell, it seems like my listeners aren’t being registered properly after the transaction. I’ve tried reinitializing them, moving them around, and testing different flows, but still no luck. If anyone has insight into how they’ve set this up or any suggestions I might not have considered, I’d really appreciate it. Thanks in advance!
0
0
63
Aug ’25
StoreKit appAccountToken Not Preserved During Apple ID Email Migration
I'm encountering an issue with the App Store Server API where the appAccountToken is not preserved when users migrate their Apple ID email addresses. I've submitted Feedback Assistant ticket FB18709241 but wanted to check if anyone else has experienced this and get community input on best practices. The Issue When a user migrates their Apple ID from one email to another (e.g., from olduser@example.com to newuser@icloud.com), the App Store creates a new subscription transaction with a different originalTransactionId, but the appAccountToken is not carried forward from the original transaction. What I'm Seeing note: these values are fake When querying /inApps/v1/subscriptions/{originalTransactionId} with the either post-migration transaction ID or the pre-migration transaction ID, the API returns both transactions: Pre-migration transaction (status: 2 - inactive): originalTransactionId: "12345678910111" Contains: "appAccountToken": "abc123-def456-ghi789" Post-migration transaction (status: 1 - active): originalTransactionId: "67891011121314" Missing: appAccountToken entirely The Problem The appAccountToken is our only way to link App Store subscriptions to user accounts. Without it on the new transaction: Users lose access to premium features despite having valid subscriptions Server-side renewal notifications can't be matched to user accounts Manual support intervention is required for each affected user Questions for the Community Has anyone else encountered this issue with Apple ID migrations? What's the recommended approach for handling this scenario? Is there an alternative mechanism to maintain the subscription-to-user linkage across migrations? Questions for Apple Engineers Is this the expected behavior, or should the appAccountToken be preserved? Are there any planned improvements to handle this migration scenario? What's the best practice for developers to handle this case? Interestingly, both the old and new transaction IDs return the same JSON response from the App Store Server API, suggesting Apple maintains internal linkage between these transactions, but the appAccountToken isn't carried forward to the active transaction. Any insights or similar experiences would be greatly appreciated! Thank you!! Feedback Assistant: FB18709241
0
3
167
Jul ’25
How to test each status of Get All Subscription Statuses of App Store Server API
I am currently using the App Store Server API Get All Subscription Statuses in the app I am in charge of. Please let me confirm the following regarding Get All Subscription Statuses. ■Prerequisites The language used is Objective-c, and I am using both XCode 15 and 16. I also have an App Store Connect account. ■Questions Is it possible to set and test each status of the App Store Server API Get All Subscription Statuses with TestFlight?
0
0
58
Mar ’25
StoreKit2 Subscription Verification
My question is simple, I do not have much experience in writing swift code, I am only doing it to create a small executable that I can call from my python application which completes Subcription Management. I was hoping someone with more experience could point out my flaws along with giving me tips on how to verify that the check is working for my applicaiton. Any inight is appreciated, thank you. import Foundation import StoreKit class SubscriptionValidator { static func getReceiptURL() -> URL? { guard let appStoreReceiptURL = Bundle.main.appStoreReceiptURL else { print("No receipt found.") return nil } return appStoreReceiptURL } static func validateReceipt() -> Bool { guard let receiptURL = getReceiptURL(), let receiptData = try? Data(contentsOf: receiptURL) else { print("Could not read receipt.") return false } let receiptString = receiptData.base64EncodedString() let validationResult = sendReceiptToApple(receiptString: receiptString) return validationResult } static func sendReceiptToApple(receiptString: String) -> Bool { let isSandbox = Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" let urlString = isSandbox ? "https://sandbox.itunes.apple.com/verifyReceipt" : "https://buy.itunes.apple.com/verifyReceipt" let url = URL(string: urlString)! let requestData: [String: Any] = [ "receipt-data": receiptString, "password": "0b7f88907b77443997838c72be52f5fc" ] guard let requestBody = try? JSONSerialization.data(withJSONObject: requestData) else { print("Error creating request body.") return false } var request = URLRequest(url: url) request.httpMethod = "POST" request.httpBody = requestBody request.setValue("application/json", forHTTPHeaderField: "Content-Type") let semaphore = DispatchSemaphore(value: 0) var isValid = false let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil, let jsonResponse = try? JSONSerialization.jsonObject(with: data) as? [String: Any], let status = jsonResponse["status"] as? Int else { print("Receipt validation failed.") semaphore.signal() return } if status == 0, let receipt = jsonResponse["receipt"] as? [String: Any], let inApp = receipt["in_app"] as? [[String: Any]] { for purchase in inApp { if let expiresDateMS = purchase["expires_date_ms"] as? String, let expiresDate = Double(expiresDateMS) { let expiryDate = Date(timeIntervalSince1970: expiresDate / 1000.0) if expiryDate > Date() { isValid = true } } } } semaphore.signal() } task.resume() semaphore.wait() return isValid } }
0
0
343
Feb ’25
IAP Product Fetch Returns Empty Array in React Native iOS App
We're experiencing an issue with in-app purchases in our React Native iOS app where RNIap.getProducts() is consistently returning an empty array, preventing users from making purchases. Technical Details: Using react-native-iap library Product ID: '[REDACTED]' Platform: iOS Product Type: Consumable (one-time payment, NOT subscription) Error in logs: "No products returned from App Store. Check App Store Connect." Debugging shows: Products Fetched: [] Steps to Reproduce: Open app and navigate to the quiz feature Attempt to purchase additional quiz attempts Modal opens but fails to load product information What We've Confirmed: IAP Connection initializes successfully No error is thrown during product fetch, just an empty array returned App is configured with correct Bundle ID Using Apple Sandbox test account We are implementing consumable purchases (one-time payments) Potential Issues to Investigate: Product configuration in App Store Connect Ensure product is set as "Consumable" type in App Store Connect Sandbox tester account permissions/activation Bundle ID matching between app and App Store Connect Product ID case sensitivity or typos
0
1
83
Apr ’25
StoreKit 2 not loading subscription products
Hi everyone, I’m seeing a strange behavior with StoreKit 2 and I’d like to know if anyone else experienced this. My subscription group “ROTA Premium” (Monthly + Annual) is currently Waiting for Review in App Store Connect. What works In Xcode’s StoreKit sandbox, everything loads correctly: Products appear Trial starts Purchases work What doesn’t work In TestFlight and App Review, StoreKit 2 returns zero products, so my paywall shows: “No subscription options found.” There are: No geo restrictions No backend No VPN/IP filtering Paid Apps Agreement is accepted App Review said the device was online, but couldn’t give technical help. My question Has anyone seen StoreKit 2 fail to load subscription products when the subscription group is still in Waiting for Review? Do subscription groups need to be reviewed together with the app version for StoreKit 2 to return them in TestFlight/App Review? Any advice would be appreciated! Thanks.
0
1
73
Nov ’25
Mismatch between App Store Server API `expiresDate` (July 23) and iOS UI “Expires on” date (July 22) for 1-month subscription
Hi everyone, I’m seeing a consistent one-day discrepancy between the expiresDate returned by the App Store Server API and the “Expires on” date shown in the iOS Settings / App Store subscription list. I’d like to confirm whether this behavior is expected or if I’m misunderstanding the way Apple rounds dates. Reproduction steps Step Action Result 1 Purchase a 1-month auto-renewable subscription on 23 June 2025 14:00 JST (UTC+9) Transaction succeeds 2 Immediately fetch the transaction with GET /inApps/v1/subscriptions/{transactionId} Response contains "expiresDate": "2025-07-23T05:00:00Z" (= 23 July 2025 14:00 JST) 3 On the same device open Settings › Apple ID › Subscriptions (or App Store › Account › Subscriptions) UI shows Expires on: 22 July 2025 The same happens for every monthly renewal and on multiple devices. Region is Japan, device time zone Asia/Tokyo. What I understand so far (and my hypothesis) Apple’s docs say a monthly subscription renews “on the same calendar date” of the next month, so renewal in this example is 23 July. If the renewal is scheduled for 23 July at 14:00 JST, the subscription is fully usable until the end of 22 July in calendar terms, because the new billing period starts the moment the 23rd begins in Apple’s canonical time zone. Therefore, it might be intentional for the UI to display 22 July—i.e., “you can keep using it through the 22nd; on the 23rd it renews.” This hypothesis makes sense internally, yet it still looks confusing to end users who read “Expires on 22 July” and assume access ends at 00:00 on the 22nd, a whole day earlier than in reality. Questions Is showing the day before the renewal date the official/expected behavior? If so, could Apple clarify that the “Expires on” label represents the last full calendar day rather than the exact expiry timestamp? Which value should we surface in-app when telling users “Your subscription is valid until …”? The server’s expiresDate (precise to the second, converted to user time zone), or A UI-style date that’s one day earlier, matching Settings / App Store? Does Apple have a public document describing this rounding/visual convention? Have other developers encountered user confusion about the apparent 1-day “shortening” and, if so, how did you word your in-app messaging? Any insight from Apple engineers or fellow developers would be greatly appreciated. Thank you!
0
1
248
Jun ’25
AppTransactionId support in Get Transaction Info endpoint — documentation change and actual behavior?
Hello, I have a question regarding the App Store Server API's getTransactionInfo endpoint. Previously, the official documentation for getTransactionInfo mentioned that: “This endpoint doesn’t support an app transaction. To get information about an app transaction, decode the signed app transaction received from the device.” However, as of June 2025, I can no longer find this sentence in the current documentation (link). Now, the docs state that all in-app purchase transaction IDs are supported (consumable, non-consumable, auto-renewable subscriptions, etc.). But in practice, when I call getTransactionInfo with an AppTransactionId (extracted from a signed App Transaction JWS), I receive this error: apiErrorCode: 4000048 “Invalid request. App transactions aren’t supported by this endpoint.” Is this endpoint supposed to support AppTransactionId now, or is the restriction still in place (but not mentioned in the docs)? Is there any official statement about when this restriction was added/removed? Can you clarify if only in-app purchase transaction IDs (and not AppTransactionIds) are supported for this endpoint, or has the policy changed recently? Any clarification or historical context would be greatly appreciated. Additionally, I would like to know about the behavior of an App Transaction in the event of a refund. If a user receives a refund for the app itself (not an in-app purchase), how can changes to the AppTransaction be detected? Does the App Store Server Notification v2 provide notifications for app-level refunds, or are such events only visible by decoding the latest App Transaction JWS on the device? Is there any way to receive app-level refund information server-side, or must we always rely on the device to provide the updated signed app transaction? Any clarification on this refund flow and notification coverage would also be appreciated. Thank you!
0
0
151
Jun ’25
Operation of Server Notifications V2 when Apple account is withdrawal
Please allow me to confirm the Server Notifications V2 specification. I am aware that if withdrawal an Apple account that has a subscription, the subscription will eventually be cancelled. Regarding Server Notifications V2 notifications with a notificationType of EXPIRED, am I correct in thinking that they will be sent when the subscription expires even if the Apple account is withdrawal?
0
0
298
Feb ’25
Making numerical StoreKit transaction IDs in Xcode work with app store server notifications
Hi, I have a setup using App Store Server notifications, which has worked fine for a while now. However, I've never been able to successfully verify a purchase via Xcode, only via TestFlight. The reason for this is that the StoreKit transactions have numerical IDs (e.g. starting from 0, incrementing one-by-one), instead of UUIDs like in TestFlight/production. This means that often the backend will detect an existing transaction with the same ID and not complete the purchase. What are we meant to do here? If I send a custom ID to make it unique the backend won't accept this - I can ask them to change this for our dev environment but it's not ideal. What I'm after is a way to use UUIDs for transaction IDs when running via Xcode. Thanks
0
0
16
Nov ’25
sandbox account isn't logging in on purchase window
I don't know if I am posting this in the right place. I am using xcode's phone simulator and I have setup my sandbox account on appstoreconnect under users and access/sandbox/test accounts then in my app on the simulator when I tap the subscribe button to purchase my product the a window pops up for in app purchases and I get a login prompt for my sandbox credentials, but no matter how many times I enter them after tapping ok all I get is a blank login prompt. also not this a brand new sandbox account and I've only changed the password 3 times, that seems to be important because its inconsistent with some of the errors I am getting on the error log here is error log. Purchase did not return a transaction: Error Domain=ASDErrorDomain Code=530 "(null)" UserInfo={NSUnderlyingError=0x600000d09080 {Error Domain=AMSErrorDomain Code=100 "Authentication Failed The authentication failed." UserInfo={NSMultipleUnderlyingErrorsKey=( "Error Domain=AMSErrorDomain Code=2 "Password reuse not available for account The account state does not support password reuse." UserInfo={NSDebugDescription=Password reuse not available for account The account state does not support password reuse., AMSDescription=Password reuse not available for account, AMSFailureReason=The account state does not support password reuse.}", "Error Domain=AMSErrorDomain Code=0 "Authentication Failed Encountered an unrecognized authentication failure." UserInfo={NSDebugDescription=Authentication Failed Encountered an unrecognized authentication failure., AMSDescription=Authentication Failed, AMSFailureReason=Encountered an unrecognized authentication failure.}" ), AMSDescription=Authentication Failed, NSDebugDescription=Authentication Failed The authentication failed., AMSFailureReason=The authentication failed.}}, client-environment-type=Sandbox}
0
0
99
May ’25
Using Storekit development, unsubscribe and resubscribe callback problem
The app subscription function uses StoreKit. After canceling the subscription, I try to subscribe again and get the following error. I remember it was working fine before iOS 18 was released. { NSLocalizedDescription = "\U53d1\U751f\U672a\U77e5\U9519\U8bef"; NSUnderlyingError = "Error Domain=ASDErrorDomain Code=825 "(null)""; } Hope you can help me solve this problem as soon as possible. Thanks
0
0
301
Jan ’25
How to validate Streamlined Purchasing with storekit 2
users download app with Streamlined Purchasing ,but the logic of checking subscription doesn't work. there the code: func checkSubscriptionStatus() async { for await entitlement in Transaction.currentEntitlements { guard case .verified(let transaction) = entitlement else { continue } if transaction.productID == monthlyProductID || transaction.productID == yearlyProductID { if transaction.revocationDate == nil && !transaction.isUpgraded { let activeSubscribed = transaction.expirationDate ?? .distantFuture > .now if activeSubscribed { hasActiveSubscription = activeSubscribed // other operation } } } } }
0
0
253
Mar ’25
Biometric Authentication Behavior in IAP Sandbox Environment
Where the problem occurs: In-app purchase Non-ApplePay Non-local authentication login Environment where the problem occurs: Sandbox environment (Development environment, TestFlight environment) Problem handling process: Open page A in the app and purchase product B (auto-renewable subscription) on that page. User authentication is required to purchase product B. During the authentication process, the user needs to enter the Apple account and Apple account password. After completing the authentication, complete the purchase of product B. Problem in step 3: Why is FaceID or TouchID not used for authentication? Note: Face ID and Password -> iTunes Store and App Store -> Status is Enabled
0
0
120
Jun ’25
Recent issues in StoreKit products fetch
Hello everyone! We are observing a significant number of failures in the fetch of the products with StoreKit1, meaning that in a completely random way, some product identifiers are considered invalid in the response that we receive from Apple, and after some minutes these products are considered once again valid. The issue started on Thursday 04/24 around 12.00 am (UTC + 02.00) and from our dashboard we can clearly see the trend of these failures has some spikes at precise times. I am attaching a view that we use for monitoring purposes showing this trend, considering the data of this week. We are noticing this problem on multiple developer accounts and on multiple apps, which is leading us to think it could be an issue in the Apple backend processing the request. In our case, the apps are not launched correctly until all the products are fetched, and therefore the impact of this problem is very high. Is anyone experiencing something similar or do you have logs which allows you to identify such issues? The issue happens only in production, while in debug and TestFlight environment everything works well. Thank you for your support
0
24
553
Apr ’25
How to make StoreKit config & App Store Server notifications work together?
Hi, Using StoreKit 2 with App Store Server notifications like so: User selects a purchase App calls Product.purchase() If successful, App Store notifies our backend with the transaction details, importantly with a UUID for the transaction ID. This works fine, but when I try to test contingent pricing via the handy StoreKit config Transaction Manager in Xcode by creating a PurchaseIntent if I then complete the purchase in the app the Transaction ID is sequential, (0 for the first, 1 for the second etc), which doesn't work for us as the backend might already have that ID stored so the purchase never completes. If I disable the config file it works fine, but then I can't use the Transaction Manager debug tool. Is there a way to override the ID of a custom transaction that's created via the StoreKit configuration? Thanks
0
0
61
Jun ’25