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

Transaction.currentEntitlements is not consistent
I've recently published an app, and while developing it, I could always get consistent entitlements from Transaction.currentEntitlements. But now I see some inconsistent behaviour for a subscribed device in the AppStore version. It looks like sometimes the entitlements do not emit value for the subscriptions. It usually happens on the first couple tries when the device goes offline, or on the first couple tries when the device goes online. But it also happens randomly at other times as well. Can there be a problem with Transaction.currentEntitlements when the connectivity was just changed? Of course my implementation may also be broken. I will give you the details of my implementation below. I have a SubscriptionManager that is observable (irrelevant parts of the entity is omitted): final class SubscriptionManager: NSObject, ObservableObject { private let productIds = ["yearly", "monthly"] private(set) var purchasedProductIDs = Set<String>() var hasUnlockedPro: Bool { return !self.purchasedProductIDs.isEmpty } @MainActor func updatePurchasedProducts() async { var purchasedProductIDs = Set<String>() for await result in Transaction.currentEntitlements { guard case .verified(let transaction) = result else { continue } if transaction.revocationDate == nil { purchasedProductIDs.insert(transaction.productID) } else { purchasedProductIDs.remove(transaction.productID) } } // only update if changed to avoid unnecessary published triggers if purchasedProductIDs != self.purchasedProductIDs { self.purchasedProductIDs = purchasedProductIDs } } } And I call the updatePurchasedProducts() when the app first launches in AppDelegate, before returning true on didFinishLaunchingWithOptions as: Task(priority: .high) { await DependencyContainer.shared.subscriptionManager.updatePurchasedProducts() } You may be wondering maybe the request is not finished yet and I fail to refresh my UI, but it is not the case. Because later on, every time I do something related to a subscribed content, I check the hasUnlockedPro computed property of the subscription manager, which still returns false, meaning the purchasedProductIDs is empty. You may also be curious about the dependency container approach, but I ensured by testing multiple times that there is only one instance of the SubscriptionManager at all times in the app. Which makes me think maybe there is something wrong with Transaction.currentEntitlements I would appreciate any help regarding this problem, or would like to know if anyone else experienced similar problems.
6
6
2.8k
May ’25
AppStore.sync() not restoring purchases
On an app that was using the old API for In-App Purchases (StoreKit 1). The app is already published on the App Store. The purchase is non-consumable. While trying to migrate to StoreKit 2, I'm unable to restore purchases. Specifically displaying and purchasing products works as expected, but when deleting and reinstalling the app, and then trying to restore purchases I can't do it. I'm trying to restore them using the new APIs but it doesn't seem to be working. What I have tried so far: I'm listening for transaction updates during the whole lifetime of the app, with: Task.detached { for await result in Transaction.updates { if case let .verified(safe) = result { } } } I have a button that calls this method, but other than prompting to log in again with the Apple ID it doesn't seem to have any effect at all: try? await AppStore.sync() This doesn't return any item for await result in Transaction.currentEntitlements { if case let .verified(transaction) = result { } } This doesn't return any item for await result in Transaction.all { if case let .verified(transaction) = result { } } As mentioned before I'm trying this after purchasing the item and deleting the app. So I'm sure it should be able to restore the purchase. Am trying this both with a Configuration.storekit file on the simulator, and without it on a real device, in the Sandbox Environment. Has anyone being able to restore purchases using StoreKit 2? PD: I already filed a feedback report on Feedback Assistant, but so far the only thing that they have replied is: Because StoreKit Testing in Xcode is a local environment, and the data is tied to the app, when you delete the app you're also deleting all the transaction data for that app in the Xcode environment. The code snippets provided are correct usage of the API. So yes, using a Configuration.storekit file won't work on restoring purchases, but if I can't restore them on the Sandbox Environment I'm afraid that this won't work once released, leaving my users totally unable to restore what they have already purchased.
2
0
1.7k
Jul ’25
SKAdNetwork: Error while updating conversion value
Hello! I make use of the new iOS 15.4 SKAdNetwork.updatePostbackConversionValue feature: SKAdNetwork.updatePostbackConversionValue(0) { error in                 if let error = error {                     print(error.localizedDescription)                 }             } I am not sure why, but I always see this error message in the console: SKAdNetwork: Error while updating conversion value: Error Domain=SKANErrorDomain Code=10 "(null)" The operation couldn’t be completed. (SKANErrorDomain error 10.) Any idea what’s going on there? What does Error Code 10 mean? Couldn't find anything in the documentation about that so far. I have the NSAdvertisingAttributionReportEndpoint key with domain (https://api2.branch.io/v1/skadnetwork/advertiser_app) in my .plist.
7
0
6.8k
May ’25
Can I use AppTransaction to verify purchase of a paid macOS app?
I've tried to use AppTransaction.shared / AppTransaction.refresh() to verify that my app has been purchased from the Mac App Store. It works when testing a release build on my Mac, using a Sandbox Apple ID. But when I submit the app for review, the reviewer says it doesn't work. The error message returned by AppTransaction is "Unable to Complete Request", which is pretty vague. I get the same error when I try to use a real Apple ID for testing on my machine, so I have been wondering if maybe the problem is that App Review is testing a build that doesn't accept Sandbox Apple IDs? My app doesn't have a provisioning profile, could it be that this is the problem? As a Mac app developer, I'm not sure what provisioning profiles are good for, I thought they were only useful for iOS. Has anybody successfully submitted a Mac app that uses AppTransaction?
4
4
1.3k
Nov ’24
Unable to sign in to sandbox StoreKit test accounts (iOS)
The error below started today 10/17/2024 (on iOS 18.1 beta 5/6/7 at least) in StoreKit sandbox testing. Outside code/app, I can't even login to the test account in settings->AppStore->Sandbox Account (goes through email/phone confirmation and then silently fails). Tried a different password for a new sandbox test account with no success...Anyone experiencing this? P.S. Status page (https://developer.apple.com/system-status/) shows some related outage from two days ago, but no current problem. Error: Purchase did not return a transaction: Error Domain=ASDErrorDomain Code=530 "(null)" UserInfo={NSUnderlyingError=0x3009ca040 {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=306 "Reached max retry count Task reached max retry count (3 / 3);" UserInfo={AMSDescription=Reached max retry count, AMSURL=..., NSDebugDescription=Reached max retry count Task reached max retry count (3 / 3);, AMSFailureReason=Task reached max retry count (3 / 3);, AMSStatusCode=200}" ), AMSDescription=Authentication Failed, NSDebugDescription=Authentication Failed The authentication failed., AMSFailureReason=The authentication failed.}}, storefront-country-code=USA, client-environment-type=Sandbox}
9
4
1.8k
Jan ’25
Transactions Finish does not work on iOS 26 beta3
On iOS 26 beta 3, after a user purchases an item, initiating a second order for the same product fails to process payment. The system returns the same transaction ID and displays an interface message stating: "You've already purchased this In-App Purchase. It will be restored for free."​​ ​​I’ve tested this – not only did the legacy StoreKit finishTransaction method fail to work, but StoreKit2 finish method also malfunctioned.​​ ​​When will Apple fix this issue? If unresolved, it will prevent a large number of users from making purchases normally, leading to disastrous consequences.​
4
4
463
Jul ’25
[macOS] AppTransaction questions (internet connection requirement)
Hello, I hope to find out more about how AppTransaction works on macOS, specifically about its internet connection requirements: if I use this to validate that the app is a legit purchase from the Mac App Store, I would not want it to have an always-on requirement just to validate. Does AppTransaction require the user to always be online for AppTransaction.shared ? When an app is downloaded from the Mac App Store, is the data needed for AppTransaction automatically embedded during that download, or is that data downloaded upon first launch of the app, therefore requiring an internet connection at launch time? Once the data/receipt has been downloaded by AppTransaction, is it cached until the app's next update, or is it cleared at some time during the version's life and needs to be re-downloaded, therefore requiring an internet connection at launch? Where is that receipt/data stored? Also, if you don't mind me sneaking in this non-related but sort of related question, in terms of receipt validation: Does macOS Sequoia's MAC address rotation feature affect receipt validation in any way when using IOKit? Thank you kindly, – Matthias
2
4
568
Apr ’25
Transaction ID Misassociation in IAP Subscription API
Dear Apple Support Team, Hello! I am currently developing the in-app subscription functionality using Apple IAP API and have encountered a serious technical issue while processing subscription data. I would like to report this issue to you. Issue Description: When calling the subscription API endpoint, the same OriginalTransactionId returns inconsistent results. Specifically, a particular transaction ID (let's call it TransactionId_A) should belong to the subscription order with OriginalTransactionId_A, but it is currently incorrectly associated with OriginalTransactionId_B. This issue severely affects our ability to accurately manage and process subscription data. Here are the relevant log details for your reference: API Endpoint Requested: https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{TransactionId_A} (Note: The link is a placeholder for the actual API endpoint.) Log Information on February 21, 2025, at 09:40:09: { "AppAccountToken": "{AppAccountToken}", "BundleId": "{BundleId}", "Currency": "CNY", "Environment": "Production", "ExpiresDate": {ExpiresDate}, "InAppOwnershipType": "PURCHASED", "IsUpgraded": false, "OfferDiscountType": "", "OfferIdentifier": "", "OfferType": 0, "OriginalPurchaseDate": {OriginalPurchaseDate}, "OriginalTransactionId": "{OriginalTransactionId_A}", "Price": {Price}, "ProductId": "{ProductId}", "PurchaseDate": {PurchaseDate}, "Quantity": 1, "RevocationDate": 0, "RevocationReason": 0, "SignedDate": {SignedDate}, "Storefront": "CHN", "StorefrontId": {StorefrontId}, "SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}", "TransactionId": "{TransactionId_A}", "TransactionReason": "PURCHASE", "Type": "Auto-Renewable Subscription", "WebOrderLineItemId": "{WebOrderLineItemId}" } Log Information on March 21, 2025, at 09:38:49: { "AppAccountToken": "{AppAccountToken}", "BundleId": "{BundleId}", "Currency": "CNY", "Environment": "Production", "ExpiresDate": {ExpiresDate}, "InAppOwnershipType": "PURCHASED", "IsUpgraded": false, "OfferDiscountType": "", "OfferIdentifier": "", "OfferType": 0, "OriginalPurchaseDate": {OriginalPurchaseDate}, "OriginalTransactionId": "{OriginalTransactionId_B}", "Price": {Price}, "ProductId": "{ProductId}", "PurchaseDate": {PurchaseDate}, "Quantity": 1, "RevocationDate": 0, "RevocationReason": 0, "SignedDate": {SignedDate}, "Storefront": "CHN", "StorefrontId": {StorefrontId}, "SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}", "TransactionId": "{TransactionId_A}", "TransactionReason": "PURCHASE", "Type": "Auto-Renewable Subscription", "WebOrderLineItemId": "{WebOrderLineItemId}" } From the above logs, it is evident that the same transaction (TransactionId_A) returns different OriginalTransactionId values at different times, which is clearly not expected and severely impacts our ability to correctly process and manage subscription data. I hope you can address and investigate this issue as soon as possible. If you need any further information or assistance, please feel free to contact me. Thank you for your support! Best regards!
6
4
903
Apr ’25
StoreKit 2 failure on tvOS 18.2
Please help! I have a subscription IAP failing on tvOS 18.2 at: func makePurchase(_ product: Product) async throws { let result = try await product.purchase() //ERROR OCCURS HERE (See error message below) ... Xcode Console message: "Could not get confirmation scene ID for [insert my IAP id here]" The IAP subscription was working fine on 18.1 and earlier, and the same IAP and code is also running fine on iOS 18.2. The tvOS error on 18.2 happens both in production and sandbox. Are there any changes to StoreKit 2 which might cause this error?
16
4
2.7k
Feb ’25
Transaction.currentEntitlements returning empty response
Hi there 👋🏻 We are facing an issue that started on 24 June 2025 where some users that have an active subscription with an offer are not being able to use/restore their subscription since Transaction.currentEntitlements is empty. We have tried to call the server with this endpoint https://developer.apple.com/documentation/appstoreserverapi/get-transaction-history and it's returning the correct transactions correctly. Any idea what is happening?
2
4
178
Jun ’25
StoreKit Configuration Not Syncing to Xcode
Hello! I am attempting to add Subscriptions to an App that Is already published on the App Store. I cannot get Xcode to actually sync what is in my App Store Connect. When adding the Storekit configuration file, I go through the automatic linking process and select the proper bundleID. The configuration file says 'Synced @ [CurrentTime]' however there are no subscriptions listed in there. I have attempted deleting the file several times, creating a new subscription group. With no success. Do I need to publish the subscriptions without the features first? Upon attempting to write the supporting code that will enable these features within the app, I cannot get Xcode to identify that I have these subscriptions. I have also tried pushing these to TestFlight, still with no success. Thank you.
10
3
1.4k
Jan ’25
subscriptionStorePolicyDestination is broken since iOS 18.0.1
I'm using StoreKit together with SubscriptionStoreView to show the subscriptions in my app. I also utilize subscriptionStorePolicyDestination to show the terms of service and the privacy policy link on the view: .subscriptionStorePolicyDestination(url: URL(string: "https://www.apple.com/legal/internet-services/itunes/dev/stdeula/")!, for: .termsOfService). Everything was working fine until iOS 18.0.1. After the update, when you tap into the terms of service (or the privacy policy) link on the store view, it opens the web view by rendering the page incorrectly. Besides that, it is not possible to close the web view anymore, you have to kill the app. I already submitted a bug (FB15552274) on Feedback Assistant but I didn't hear anything back for 2 weeks. My apps are getting rejected now, because the store view doesn't have: A functional link to the Terms of Use (EULA) A functional link to the privacy policy This is really frustrating because the API was working fine but now it is broken and neither the Apple developers nor the reviewers really care if the API is broken.
3
3
466
Nov ’24
Mac App Store receipt validation exit(173) Not Available on Sequoia
I have 6 Mac App Store apps. They're all upfront paid, with no IAP, and they've all used the same on-device Mac App Store receipt validation code for years, which returns 173 in main() if there's not a valid receipt. Incidentally, the apps are entirely Objective-C. I've just learned that if I compile an app with Xcode 16 and the macOS 15 SDK, I get the alert "exit(173) Not Available" when the app returns 173 on macOS 15 Sequoia. The rest of the alert text says, "The exit(173) API is no longer available. You can use Transaction.all or AppTransaction.shared to verify in-app purchases instead." I have several questions: Why was this done? Where is this behavior change documented? What are my options, given the above description of my apps?
2
3
941
Oct ’24
StoreKit2: Transaction.currentEntitlements returns expired subscriptions (Testing locally with shortened sub periods)
Hi, title says it all: I have Transaction.currentEntitlements returning expired subscriptions (testing both transaction expirationDate & RenewalState). Environment: local via .storekit file. Subscription duration is shortened for testing. Could it be the issue? The sub duration is normally 1 year. The documentation says it should only returns active subscription (RenewalState.subscribed) or in grace period (RenewalState.inGracePeriod).
5
3
2.4k
Dec ’24
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
115
Jul ’25
Specific IAP products returning empty data - Possible StoreKit issue
Hello developers, We're facing a critical issue with our app and need your insights: Since today, 3 specific IAP products return empty data when calling Product.products(for: [productId]). This affects all users, preventing any successful purchases of these items. Other IAP products seem unaffected. let products = try await Product.products(for: [productId]) Key details: Production environment Issue started: 2025.6.17 No recent app updates All products show as "Approved" in App Store Connect Questions: Has anyone experienced similar issues recently? Could this be a StoreKit or App Store system problem? Any suggestions for diagnosing or resolving this, besides contacting Apple Support? Recommendations for temporary workarounds? This is severely impacting our business. Any help is greatly appreciated! Thank you!
7
3
326
Jun ’25
Clarification on Offer-Code Redemption When Streamlined Purchasing Is Turned Off
Background We sell a suite of iPadOS/macOS apps that share a single auto-renewable subscription using this architecture. Per “Offering a Subscription Across Multiple Apps” we require users to sign in before purchasing so we can propagate the entitlement and avoid duplicate subscriptions across apps. To enforce that sign-in step we plan to turn off Streamlined Purchasing in App Store Connect. Question We also want to distribute subscription offer codes (for promotion, retention, appeasing dissatisfied customers, etc.). After Streamlined Purchasing is turned off, will customers still be able to redeem offer codes outside the app (App Store “Redeem Code” UI or redemption URL)? If outside-app redemption remains possible, it bypasses our sign-in gate and could let the same customer buy the suite twice (once via each app). Is there an approved method to limit offer-code redemption to the in-app flow only, or otherwise prevent such duplicate subscriptions? If no such limitation exists, what best-practice workaround does Apple recommend for multi-app suites that must turn off Streamlined Purchasing yet still wish to use offer codes without duplication risk? Environment StoreKit 2; server-side receipt validation & cross-app entitlement propagation. Apps support the in-app presentCodeRedemptionSheet flow. We expect to use both one-time-use and custom offer codes.
2
3
91
Apr ’25
TestFlight user cannot re-purchase expired auto-renewable subscription – only restored purchases returned
I’m testing an auto-renewable subscription on TestFlight. Now the user can't re-purchase the same product – Apple just restores the old (expired) one, and no payment sheet appears. How can I let the same TestFlight user re-subscribe to an expired product? Do I have to create a new productId for every test cycle?
3
3
104
Jul ’25
Issue with "Transaction.currentEntitlements": Some paid users cannot use the features of our subscription plan
Some paid users are unable to use the paid features unlocked by purchasing our subscription plan. It seems that this is due to StoreKit 2's Transaction.currentEntitlements not working the way we would expect it to work. Are you also encountering this issue? Do you have any idea to improve this situation? At launch, our app checks if the user is subscribed to the plan, using Transaction.currentEntitlements. As a result, the currentEntitlements array was empty. Our app then fetches the products from StoreKit 2 using Product.products(for:). As a result, the Product.SubscriptionInfo.RenewalState value of the corresponding Product (product.subscription.status.first.state) is subscribed, which confirms that the user has indeed purchased our plan, but seems to contradict the absence of the corresponding transaction in Transaction.currentEntitlements. Proactive in-app purchase restore and a restore purchase button calling the AppStore.sync() method are implemented, but using the button did not solve the issue.
2
3
608
Jul ’25