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

Subscription Cancellation
Hi Team, I’ve successfully implemented the subscription flow for my app. However, I’m currently facing challenges related to testing the cancellation behavior for auto-renewable subscriptions. Specifically: I’m unable to locate the correct payload structure for the following test endpoint: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/test I’m also unclear on how to simulate or complete the full lifecycle of a subscription (including cancellation) using Apple’s sandbox environment or APIs. Could you please guide me on how to: Retrieve or construct the proper payload for the test notification API? Simulate a cancellation flow end-to-end in the sandbox for auto-renewable subscriptions?
0
0
71
May ’25
Best way to share subscriptions between iOS and watchOS apps
I'm working on a watchOS app that has an iOS counterpart. There will be a subscription required to unlock functionality and I would like the user to be able to make the purchase on either the iPhone or the watch and have both apps unlock. The first link below says that StoreKit 2's Transaction.currentEntitlements will not work in this case like it does with extensions. The second link says it might work but doesn't in the sandbox. What is the best way to make this work? Will it just work in the App Store? Should I use WCSession to send the purchase information from one platform to the other and store it in the keychain? Something else? Via https://www.revenuecat.com/blog/engineering/ios-in-app-subscription-tutorial-with-storekit-2-and-swift/ "Transaction.currentEntitlements can be used in extensions the same way it was used in the previous steps. This works for extensions like Widgets and Intents. However, an iOS app with a companion watchOS app will not work even though Transaction.currentEntitlements can be executed in it. A companion watch app does not stay updated with the same transaction history as its iOS app because they are separate platforms." Via https://developer.apple.com/forums/thread/739963 "In TestFlight I was able to confirm that the Watch app and IOS app share in-app purchases. It seems the problems confirming this with Storekit and Sandbox are limits of the testing environments."
0
1
279
Mar ’25
"purchaseDate" of the Reciepts
I have some questions regarding the specifications of the receipt information that can be obtained from https://developer.apple.com/documentation/appstoreserverapi/get_transaction_info. When a subscription is newly purchased, it is expected that the purchaseDate should reflect the time of purchase and should not be later than this time, such as an hour after the purchase. Is this understanding correct? We observed a phenomenon where, when a user purchased a new subscription between 17:30 and 20:00 JST on November 3, 2024, the purchaseDate in the received receipt was delayed by one hour compared to the actual purchase time. Is this a specification or an issue? When validating the receipt for a newly purchased subscription, if the purchaseDate reflects a time later than when the purchase was made, should I regard the user as having subscription rights at the time of validation?
0
1
449
Nov ’24
The operation could not be completed. (Error 2 in SKErrorDomain.) during subscription upgrade
I have a renewing monthly subscription in my app and recently added upgrade possibilities to yearly and 6 month subscriptions. Those new subscriptions were reviewed, approved and published to App Store. I'm showing a modal for users in the app from where they can upgrade their subscription. Upgrading was tested with real devices on Sandbox and TestFlight. There has been successful purchases through the in app modal in production app, and directly upgrading from App Store. However, for some users there seems to happen a failed transaction with paymentCancelled error code during the upgrade. The IAP is still successful, their subscription is upgraded and they haven't voluntarily canceled the IAP. The localized description of the error is "Toimintoa ei voitu suorittaa. (Virhe 2 kohteessa SKErrorDomain.)" which translates to "The operation could not be completed. (Error 2 in SKErrorDomain.)" These users have various iPhones (iPhone 12 Pro, iPhone 14 Pro, iPhone 15 Pro, iPhone 16 Pro) with up to date iOS versions (>= 18.3.1). I'm receiving DID_CHANGE_RENEWAL_PREF (UPGRADE) server notification of these purchases on my server. I haven't been able to reproduce this error myself. Any ideas why StoreKit might fail the transaction with paymentCancelled error but still successfully upgrade the subscription?
0
0
134
Mar ’25
Do I need IAP inside my app by using this model?
Currently, I have an app running locally on my computer, and there is also a web app. To create an account, users need to pay through the web app, which handles the payment process smoothly. My question is: Do I need to implement In-App Purchases (IAP) if the payment is only for account creation? Let me elaborate on my question. I know the typical answer is yes, but what if users in the mobile app cannot create an account or pay within the app itself? Instead, account creation is only possible via the web app, and only users who have paid outside the mobile platform can access and join the mobile app. This approach is similar to what Netflix and Spotify do – they do not allow account creation inside their mobile apps and do not provide any redirects or buttons indicating alternative payment methods (they do not have IAP).
0
0
253
Nov ’24
Error setting install attribution pingback
Hi there, We have an app targeted for children and we want to use the SkAdNetwork to track installs for campaigns. We don't want to track further in-app events (purchase etc.), just the install event. We added the SDK to our Unity app, listed the network identifiers in the plist file, configured the external campaign according to their instructions, but struggle to see any events for several weeks now. We see the following logs in the app: Registering install attribution pingback. Failed to migrate Install Attribution database schema from 17001 => 17400. SkAdNetwork: No pingbacks found while attempting to register/update. Error setting install attribution pingback registered for app: 1509727806, error: Error Domain=ASDErrorDomain code=1208 How can we debug this further? What does the error mean? Thank you very much! (I hope I posted in the correct forum topic. Apologies if not)
0
0
41
Apr ’25
Reporting to External Purchase Server API when using alternative PSP in the EU
Dear community, Context My company operates in the European Union, where not so long ago there appeared the possibility to accept an ["Alternative Terms Addendum for Apps in the EU"] (https://developer.apple.com/contact/request/download/alternate_eu_terms_addendum.pdf), which, among others, gives us the possibility to use an alternative payment provider, other than Apple's In App Purchase PSP system (ref: Apple docs). My company did accept it and was granted the StoreKit External Purchase Entitlement (com.apple.developer.storekit.external-purchase) entitlement, with which we integrated a different PSP, so now we want to incorporate the reporting to Apple's External Purchase Server API. We are currently integrating with the External Purchase Server API and have encountered a couple of issues I would appreciate clarification on: Question 1 Is there a way to retrieve an overview or summary of the current subscription states on Apple’s servers as a result of the submitted reports to External Purchase Server API? Specifically, I would like to verify the expected outcomes before the monthly invoice is issued by Apple and to understand the subscription states for the test users I used during this process and for future reference as well. Question 2 In one scenario, I initiated a one-year subscription, and in the middle of its period, I submitted a RENEWAL for one month with a higher price. I expected the request to fail due to overlapping periods and/or pricing conflicts, but both submissions were accepted without error. Do you have an idea about: What happens at the end of the renewed month? Will the subscription continue with the renewed (higher) amount, revert to the original (lower) annual rate, or be canceled? Where can I view the final state and billing plan for that subscription? Thank you for your assistance, we are looking forward for any kind of help or information regarding this topic.
0
0
87
Apr ’25
Adding In-App Purchase to app + review required?
I'm trying to understand the IAP development process. I created my first Product on App Store Connect and am trying to build my app to use it. However it keeps failing with "Invalid product ID.". From what I've read, this is because the product has not yet gone through review. But what I don't understand is, of course it hasn't gone through review yet, because trying to use it in any capacity fails, even though I'm using a real physical device and using a Sandbox User. Is this the correct workflow? It seems very backwards that I have to submit the product for review, even before I know how it's going to be used. I'm still building the screen for the product page, and haven't even started touching any backend APIs, yet it's asking for screenshots. Am I misunderstanding something here?
0
0
52
Apr ’25
Is original_transaction_id and transaction_id globally unique?
Hello, Apple App Store Server API Team! I have one questions about the identifiers provided by Apple App Store Server API. Could you please answer? We are running an iOS App. In our app, the transactionId we get from Apple App Store Server API is called T1. (Example) Q1. Is it correct that other iOS apps cannot get T1 for transactionId from Apple App Store Server API? (I'm wondering if the transactionId is globally unique across apps.) Thank you!
0
0
403
Dec ’24
Can I ask user to share his/her email id while doing
We sell magazines through a third party app platform called Pocketmags and our website. The magazines have Print, Digital and Combo options available for purchase. Also, this third party app provides the platform to read the digital version of the magazines. Once a user buys a subscription on the website, he/she receives the email with the login information on PocketMags, where he registers his login details and can start reading his subscription. With us, the customer shares his billing/shipping address along with their email id while they make payment. Now we have our own app where through which we want to sell these magazines and have to integrate In-App purchase for selling these digital subscriptions. How do we send the 3rd party subscription access details on email to the user if they do in app purchase?
0
0
38
Apr ’25
In-App Purchases
The in-app payment system is confusing. In-app payment is initially reviewed without being attached (however, in-app purchase is applied) Once the review is complete (up to in-app payment), the in-app payment module is attached for testing It is reviewed with the attached module Isn't this the logic? If there is another logic, please let me know. Thank you.
0
0
260
Oct ’24
Can StoreKit products be observed with ObservableObject? Can I get notified when a users subscription has lapsed without polling Transaction.currentEntitlements?
I have an auto-renewable subscription. I have two methods helping me keep track of when they are expired @MainActor public func isPurchased(product: Product) async -> Bool { guard let state = await product.currentEntitlement else { return false } switch state { case .unverified(_, _): return false case .verified(let transaction): await transaction.finish() return isTransactionRelevant(transaction) } } private func isTransactionRelevant(_ transaction: Transaction) -> Bool { if let revocationDate = transaction.revocationDate { logger.error("Transaction verification failed: Transaction was revoked on \(revocationDate)") return false } if let expirationDate = transaction.expirationDate, expirationDate < Date() { logger.error("Transaction verification failed: Transaction expired on \(expirationDate)") return false } if transaction.isUpgraded { logger.error("Transaction verification failed: Transaction was upgraded") return false } logger.info("Transaction verification succeeded") return true } I also have this that I can call to get the latest state of purchases @MainActor public func updateStoreKitSubscriptionStatus() async { var currentProductsPurchased: [Product] = [] for await result in Transaction.currentEntitlements { if case .verified(let transaction) = result { if isTransactionRelevant(transaction) { if let product = products.first( where: { $0.id == transaction.productID }) { currentProductsPurchased.append(product) } } await transaction.finish() } } self.purchasedProducts = currentProductsPurchased } Right now when a subscription expires the user needs to manually do some action that triggers updateStoreKitSubscriptionStatus() as it appears that expirations do not come through in Transaction.updates. I am surprised there does not seem to be a better way. Does StoreKit not notify you somewhere that an auto-renewable subscription has expired? Can you observe it in an ObservableObject? Or do I need to just frequently poll Transaction.currentEntitlements even if I dont expect frequent updates?
0
0
47
Jul ’25
In-app purchase fails at first attempt, succeeds at second
Our macOS app has one in-app purchase (IAP) implemented using StoreKit 1. It works for us and beta testers but App Review get SKErrorDomain Error Code 0 / ASDErrorDomain Code 500 / AMSErrorDomain 305 on first attempt to make the in-app purchase. However, the purchase succeeds at second attempt. We've looked through our entire IAP related code and App Store Connect setup but can’t find the reason. It's a standard implementation: LegacyPaymentQueueObserver for SKPaymentQueue observation. AppDelegate for initiation of payment queue observation on app launch LegacyStoreKitPurchasableProduct for initiating a purchase and listening for the result LegacyStoreKitProductsRequester for how we load the product before user can make in-app purchase. It happens this way: PreviewResultsViewModelcalls loadProducts()on an instance of StoreKitPurchaseManager, which asks an instance of LegacyStoreKitProductsRequesterto requestProducts(forIdentifiers:) Any guidance to resolve this would be appreciated.
0
0
326
Jan ’25
Dev Defined IAP Transaction Metadata
I have an app that works by being able to map IAP transactions to a predefined user ID. This means when I consume events from Apple's App Store Server Notifications endpoints I have to do a reverse lookup in order to assign permissions within my app. Workflow: User purchases subscription within the app via IAP. The app persists the subscriptionID from the Apple IAP library in my cloud database (Firestore). Cloud function receives the event from App Store Server Notifications endpoint and looks up the user ID containing the persisted transactionID (with retries to avoid race condition). Question: This workflow works but it seems an improvement would be to allow dev's to append metadata, like the user ID, to the transaction submitted to IAP that we can access within the signedTransactionInfo of the event from the App Store Server Notifications endpoint in order to facilitate a direct lookup of the user document needing it's permissions updated. This would greatly simplify workflows that use non-Apple systems as a source of truth for app permissions. Does this actually exist already? If not, is there a feature request platform?
0
0
29
Mar ’25
InApp purchases ok and ko at the same time (?!)
I'm working on an app the has implemented inapp purchases. They have been working so far, and they keep working currently. But just a couple of days ago, a specific user sent us a support ticket stating that when he purchases and item the bank charges it for the purchase, but within the app, the purchase fails and he doesn't receive the item. He sent us screenshots showing: The iOS native modal when a purchases has been finished correctly ("You're all set - Your purchase was successful "). Right after that modal, the app shows an internal modal showing "The purchase failed, please, try again later". Checking the app logs, that failure modal was triggered by "The operation couldn’t be completed. (StoreKit.StoreKitError error 1.)". Reading docs about this error leads me to think about device or user restrictions (parental controls, usage limits, etc...). It seems that in theses cases the bank charge could be issued but refunded later once Apple ultimately declines the purchase. However the user says that he doesn't have any kind of restriction. The only related thing is a "this device is also restricted by a profile" message, but everyone seems to have this message. What could it be causing this issue? In what scenariowould the app show a native OK modal but a storekit error 1? I'm pretty sure the app is well configured because I keep receiving purchases of all kind, from different users with any problem.
0
0
292
Mar ’25
In App Purchase cross platforms
Hello Apple Dev Team, I’m seeking guidance on how to ensure full compliance with the App Store Review Guidelines, specifically section 3.1.1 (In-App Purchase). In-App Purchase Mechanisms: I want to verify that my app is correctly using in-app purchases to unlock premium content, rather than alternative mechanisms. The guidelines outline various restrictions on unlocking content (e.g., license keys, QR codes, cryptocurrency). If I follow all of these restrictions, would Apple require anything else specific to prove compliance? Subscription Handling Across Platforms: Our app plans to offer a subscription service where users could subscribe on Android and then access the content on iOS with the same credentials (similar to Netflix). Users should also have the option to manage (including canceling) their subscription directly from their iOS device. Are there any specific requirements or precautions I should take to facilitate this cross-platform subscription access while remaining compliant? Restoring Purchases: I see that in-app purchases must have a restore mechanism. Could you confirm if Apple expects any specific UX or technical standards here, particularly if there are multiple types of IAPs? I’d appreciate any insights or examples from other apps that meet these requirements successfully. Thanks in advance! This should help clarify your approach, ensuring alignment with Apple’s guidelines.
0
0
401
Oct ’24
How to test refunds of consumable purchases?
I have consumable IAPs in my app. Currently there is no way for me to test refunds for them as Xcode testing doesn't allow refunds option for my Purchases. According to this official documentation on Transaction.all , i should be getting my refunded consumables in Transaction's all property. But there is no way for me to know what kind of data is in the refunded transaction object. Will there be a 'revocation date' like in the case of non-consumables?
0
0
44
Jun ’25