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

Auto-renewable subscriptions does not work in production
I don't know why the subscription doesn't work in production, the message Subscription Unavailable appears. The subscription is approved in appstoreconnect. Works normally using storekit in xcode, both signing and using subscriber features. According to apple's guidance, first I do the test to validate https://buy.itunes.apple.com/verifyReceipt and then https://sandbox.itunes.apple.com/verifyReceipt. Plus I create the app-specific shared secret and put it in the code to validate the receipts. I have looked for several topics and I can not solve this problem. What do I need to do to make it work in production? I believe I did what's in the official documentation.
6
0
178
Apr ’25
StoreKit.product.purchase returns success, but subscription does not appear in Settings
Description: We are developing an iOS app that offers only one auto-renewable subscription. Recently, a user who had not subscribed for over a year purchased the subscription again through our app. However, when they checked Settings > Subscriptions, the new subscription did not appear. Instead, only their past subscription history was visible, and there was no option to cancel the new subscription. We have verified this issue with a screenshot provided by the user. Additionally, we checked our app’s logs and confirmed that StoreKit.product.purchase successfully returned .success, indicating that the purchase was processed correctly. Code used for purchase: let result = try await product? .purchase(options: [ .appAccountToken(uuid) ]) switch result { case .success(let verificationResult): switch verificationResult { case .verified(let transaction): addPurchaseLog("verificationResult.verified.") case .unverified(_, let verificationError): addPurchaseLog("verificationResult.unverified.") case .userCancelled, .pending, .none: addPurchaseLog("verificationResult.userCancelled or .pending or .none") @unknown default: addPurchaseLog("verificationResult.unknown.") } Despite the successful purchase, the new subscription does not appear under the user's active subscriptions. Could this be a bug in StoreKit? If there are any known issues or workarounds, we would appreciate any guidance. Environment: Xcode: 16.2 iOS version: 16.0+
4
0
239
May ’25
Production review failed because IAP products cannot be loaded
My app has a couple of consumable IAP items. I have tested this extensively and it works in all test scenarios including loads of beta testers using testflight. However, Apple's production reviewer reports that loading of the products hangs in their setup. This is very frustrating as I have no means of recreating the problem. My first product was tested ok an all my IAP items are approved for release. However, I did not explicitly assign them to my build. I read somewhere that you need to do that but could not find in App Store Connect after my first product was approved. Below is the relevant code section. What am I missing? class DonationManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver { @Published var products: [SKProduct] = [] // This is observed by a view. But apparently that view never gets populated in Apple's production review setup @Published var isPurchasing: Bool = false @Published var purchaseMessage: String? = nil let productIDs: Set<String> = ["Donation_5", "Donation_10", "Donation_25", "Donation_50"] override init() { super.init() SKPaymentQueue.default().add(self) fetchProducts() } deinit { SKPaymentQueue.default().remove(self) } func fetchProducts() { print("Attempting to fetch products with IDs: \(productIDs)") let request = SKProductsRequest(productIdentifiers: productIDs) request.delegate = self request.start() } func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { DispatchQueue.main.async { self.products = response.products.sorted { $0.price.compare($1.price) == .orderedAscending } print("Successfully fetched \(self.products.count) products.") if !response.invalidProductIdentifiers.isEmpty { print("Invalid Product Identifiers: \(response.invalidProductIdentifiers)") self.purchaseMessage = NSLocalizedString("Some products could not be loaded. Please check App Store Connect.", comment: "") } else if self.products.isEmpty { print("No products were fetched. This could indicate a problem with App Store Connect configuration or network.") self.purchaseMessage = NSLocalizedString("No products available. Please try again later.", comment: "") } } } ...and the view showing the items: @StateObject private var donationManager = DonationManager() var body: some View { VStack(spacing: 24) { Spacer() // Donation options ------------------- if donationManager.products.isEmpty { ProgressView(NSLocalizedString("Loading donation options...", comment: "")) .foregroundColor(DARK_BROWN) .italic() .font(.title3) .padding(.top, 16) } else { ForEach(donationManager.products, id: \.self) { product in Button(action: { donationManager.buy(product: product) }) { HStack { Image(systemName: "cup.and.saucer.fill") .foregroundColor(.pink) Text("\(product.localizedTitle) \(product.priceLocale.currencySymbol ?? "$")\(product.price)") } .buttonStyle() } .disabled(donationManager.isPurchasing) } }
2
0
202
Jul ’25
In-App Purchase products suddenly not returned by queryProductDetails
Hi, We're currently experiencing an issue with consumable In-App Purchases on our production iOS app. Until the end of May, everything was working as expected, but starting in early June, our app no longer receives any products when calling queryProductDetails() using Flutter’s in_app_purchase plugin (which utilizes StoreKit). Here’s what we’ve confirmed so far: The product IDs are correctly configured in App Store Connect, and all items are marked as “Approved.” No recent changes have been made to the bundle ID or the product IDs. The “Base Territory” setting was updated for each IAP item in early May. After that change, product retrieval and purchases were working normally through the end of May. This issue is happening on real devices in production, and multiple users are affected. The same functionality continues to work correctly on Android. All requested product IDs are being returned in the notFoundIDs list of the queryProductDetails() response. We're quite puzzled by this issue as no clear cause has been identified so far. Any thoughts on this issue would be much appreciated. Thank you!
1
0
170
Jun ’25
StoreKit2 with C++ application. How?
Hello all! My application written with C++ and using StoreKit1. For now my application using bridge C++/Objective-CPP/Objective-C/Swift. Since StoreKit1 declared "deprecated" got a question of how to implement correctly StoreKit2 in C++ application, mostly everything about Renewable Subscriptions. StoreKit2 have no direct API in Objective-C, it's available only in Swift. Which is the way the best and correct way: -- for on-device writing C library and in it implement Swift? In this case how to add correctly StoreKit2 into library itself? -- for on-device somehow write kind of wrapper for Swift StoreKit 2 within translation of all of objects in Objective-C and implement it with C++/Objective-CPP bridge? In this case how to add correctly StoreKit2 in C++ project written with CMake? Here https://github.com/compnerd/swift-cmake-examples/tree/main the one of the examples of interoperability C++/Swift with CMake. But how to use exactly with StoreKit2? -- only using server side solution?
6
0
774
May ’25
tvOS In-app purchase not working
I am trying to implement in-app purchases in Apple TV. I added a "non-consumable" product and started testing in Sandbox, but it did not work properly. While I am trying to fetch the product from the appstore, it won't give any responses like success or failure. So that our app gets rejected in the App Store. Please provide me the steps to implement in-app purhcase in Apple tvos using Swift. Note: The same code is working fine in iOS.
1
0
333
Feb ’25
Consolidate subscriptions between apps
Because of historical reasons we have the same app with different bundle identifiers in different App Stores, e. g. one in Germany and one in Poland and one in France. Every app offers a monthly and a yearly in app subscription. We want to consolidate our apps and user base and want to have only one app in the end. The question is now: Can Apple make the monthly/daily subscriptions from e. g. the app in the store in Poland available or migrate them to the german app in the german App Store when we make the "german" app available also in Poland? The final goal would be that a user who bought a subscription in the polish store would have the subscription also available on his Apple ID in the german store. Is this possible? Can Apple make this possible?
1
0
69
Jun ’25
StoreKit 2: Handle unfinished consumables
I have non-consumable and consumable in-app purchases in my app. The tutorial I was following stated Transaction.currentEntitlements includes unfinished consumables, which is incorrect according to the documentation. Is the correct way to handle unfinished consumables (and non-consumables) to implement Transaction.updates and call finish() if it’s verified? The documentation says that listener will receive unfinished transactions once upon app launch, so with that, do I understand correctly you do not need to implement Transaction.unfinished unless you want to look for unfinished transactions manually later on? Otherwise what is the correct and most recommended way to handle unfinished consumables? Is there a way to test that scenario in Xcode?
1
0
217
Jun ’25
External Link Account API - ExternalLinkAccount.canOpen() always return false
This is a hybrid app built with JavaScript (Vue) + Capacitor. It is a reader app and has been authorized by Apple to use the External Link Account Entitlement, allowing users to manage their subscriptions outside of the app. I have implemented the External Link Account API. When I click on "Gerenciar Assinatura em...", I use the External Link Account API to check if the modal is available (using ExternalLinkAccount.canOpen()). I always get "false". my plugin in swift: my app: I believe this is due to the fact that I am in a development environment. My project is configured correctly in the following files: info.plist and App.entitlements. I also have the authorization in my profile visible in Xcode. I have attached screenshots for validation. The question is: should the External Link Account API work in a test environment? I am testing the build in Xcode with a physical iPhone with iOS 18. file info.plist: file App.entitlements: xcode with authorization in my profile: If you could let me know if I am doing something wrong, I would greatly appreciate it.
2
0
148
Jun ’25
Issue that subscription products (monthly subscription and annual subscription) cannot be obtained from App Store Connect
Dear my friends, I have set up two subscriptions (monthly and annual) in App Store Connect. By configuring with StoreKit, I can import the configurations from App Store Connect into the local .storekit file, and the program can run normally. However, when the StoreKit configuration is set to NONE, I am unable to retrieve product information from App Store Connect. The code for fetching the product list is as follows. Could you please provide suggestions on how to proceed? Thank you very much! private let productIds: [String] = ["subscription.year", "subscription.monthly"] subscriptions = try await Product.products(for: productIds)
2
0
132
Jun ’25
How to Verify the Authenticity of an In-App Purchase Receipt from Apple Pay?
I am an app developer, and I have implemented in-app purchases in my application. When a user completes a purchase, Apple displays a success popup. After the user taps "OK", I send the receiptData to my server to add points to their account. However, I have encountered cases where users either exit the app before tapping "OK" or experience network issues, preventing the receipt from being sent to my server. As a result, they do not receive their points. Later, some users send me a receipt from Apple Pay, claiming that the payment was successful. These receipts include details such as the orderId, email, and other transaction information. However, I am not certain whether the user actually completed the payment but encountered an issue, or if they are providing a fraudulent receipt. My question: How can I verify the authenticity of these receipts? Is there an official way to check if a given Apple Pay invoice corresponds to a real in-app purchase in my app? Any guidance or best practices would be greatly appreciated!
2
0
153
Mar ’25
SubscriptionStoreView Not Working
Hello, I have two auto-renewable subscriptions set up in App Store Connect. However, when I try to use SubscriptionStoreView, I receive the following error: Subscription store should include at least one auto-renewable subscription. I believe my .xcodeproj is misconfigured, as I created a new project since I wanted to start from scratch. What am I missing?
1
0
114
Jun ’25
Purchase information for users with multiple original transaction IDs
We are currently performing maintenance and operation on our app. I would like to ask a question about Apple's purchase processing. When retrieving purchase information for a user who has multiple original transaction IDs, such as original transaction ID AAA and original transaction ID BBB, if "Get All Subscription Statues" is executed with BBB as an argument, is it possible that purchase information for original transaction ID "AAA" will be retrieved? If this kind of issue does occur, please share the conditions under which it occurs.
1
0
189
Mar ’25
Consumable in-app purchases
I implemented consumable in-app purchases in an iPhone app using StoreKit's ProductView(). When I tap the payment button in ProductView(), I am taken to the payment screen and once the payment is completed, the desired code appears to be executed, so there doesn't seem to be a problem, but when I tap the payment button in ProductView() again, the desired code is executed without being taken to the payment screen. So one payment can be used any number of times. I thought I wrote it exactly according to the reference, but will it be okay in a production environment? Is there any code that is necessary?
2
0
232
Jul ’25
The currency information obtained from [priceLocale] differs between the TestFlight version and the official release version.
When creating a subscription charging system for an iOS app, I am trying to change the display to yen, dollars, or euros depending on the user's country. I am using [priceLocale] of [SKProduct] in [StoreKit] to obtain currency information linked to the Apple account from the App Store and change the display. The smartphone I am testing on uses an Apple account created in Japan, and the nationality of the App Store is also set to Japan, so I expect the display to be in yen. As a result, the TestFligh version displayed dollars, but the official release version displayed yen. Why doesn't the TestFligh version display yen?
2
0
145
Apr ’25
Mac OS 15.4 breaks receipt Validation
I'm using Swift to verify receipts in myObjective C Mac Application using the following code: @objc class MyAppTransaction: NSObject{ @objc class func checkReceipt() async -> String { do { let verificationResult = try await AppTransaction.shared switch verificationResult { case .verified(_): return "VERIFIED" case .unverified(_, _): return "NO RECEIPT" } } catch { return "ERROR" //(StoreKit.StoreKitError) unknown } } } Starting today with my upgrade to Sequoia 15.4 and XCode 16.3 receipt validation is broken. The function is going to the catch and returning "ERROR" I can't set a break point in the do {} but if I set one at the return "ERROR", in the debugger error = (StoreKit.StoreKitError) unknown. the Compiler logs an error:Failed to parse AppTransaction: missingValue(for: [StoreKit.AppTransaction.Key.appTransactionID], expected: StoreKit.BackingValue). Reading the developer documentation I can't find anything about these struct members. I tried to use refresh() to get a receipt like I used to with exit(173) but the compiler says refresh () not found. This is extremely troubling because I can't debug my receipt validation code and I don't know if this will happen to my users. Do I just have to trust Apple that my users will have an application with a receipt attached? What can I do?
8
0
277
Apr ’25
Sandbox user can't see StoreKit subscriptions
Hi everyone, I’m struggling to get StoreKit 2 to fetch products in my SwiftUI app while using a sandbox user. I think I’ve followed all necessary setup steps in Xcode, App Store Connect, and my physical test device, but Product.products(for:) always returns an empty array. I’d appreciate any insights! What I’ve Done Local App Setup (Xcode 16.2) Created a blank SwiftUI Xcode project. Enabled In-App Purchase capability under Signing & Capabilities. Implemented minimal StoreKit 2 code to fetch available products (see below). Using the correct bundle identifier, which matches App Store Connect. App Store Connect Configuration Registered the app with the same bundle identifier. Created an Auto-Renewable Subscription with: Product ID: v1 (matches my code). All fields filled (pricing, localization, etc.). Status: Ready for Review. Linked the subscription to the latest app version in App Store Connect. Sandbox User & Testing Setup Created a sandbox tester account. Logged in with the sandbox user under Settings → Developer → Sandbox Apple ID. This was on my physical device (iOS 18.2). Installed and ran the app directly from Xcode (⌘+R). Issue: StoreKit Returns No Products Product.products(for:) does not return any products. There are no errors thrown, just an empty array. I confirmed that StoreKit Configuration is set to None in Xcode. No StoreKit-related logs appear in the Console. Code Snippets //StoreKitManager.swift import StoreKit import SwiftUI @MainActor class StoreKitManager: ObservableObject { @Published var products: [Product] = [] @Published var errorMessage: String? func fetchProducts() async { do { let productIDs: Set<String> = ["v1"] // Matches App Store Connect let fetchedProducts = try await Product.products(for: productIDs) print(fetchedProducts) // Debug output DispatchQueue.main.async { self.products = fetchedProducts } } catch { DispatchQueue.main.async { self.errorMessage = "Failed to fetch products: \(error.localizedDescription)" } } } } //ContentView.swift import SwiftUI struct ContentView: View { @StateObject private var storeKitManager = StoreKitManager() var body: some View { VStack { if let errorMessage = storeKitManager.errorMessage { Text(errorMessage).foregroundColor(.red) } else if storeKitManager.products.isEmpty { Text("No products available") } else { List(storeKitManager.products, id: \.id) { product in VStack(alignment: .leading) { Text(product.displayName).font(.headline) Text(product.description).font(.subheadline) Text("\(product.price.formatted(.currency(code: product.priceFormatStyle.currencyCode ?? "USD")))") .bold() } } } Button("Fetch Products") { Task { await storeKitManager.fetchProducts() } } } .padding() .onAppear { Task { await storeKitManager.fetchProducts() } } } } #Preview { ContentView() } Additional Information iOS Version: 18.2 Xcode Version: 16.2 macOS Version: 15.3.1 Device: Physical iPhone (not simulator) TestFlight Build: Not used (app is run directly from Xcode) StoreKit Configuration: Set to None
2
0
428
Mar ’25
Validating receipt for iOS in-app purchase always returns error 21002
I'm receiving the following error when attempting to validate an in‑app purchase receipt: Certificate verification failed at depth 0 : forge.pki.UnknownCertificateAuthority Certificate chain validation failed: Certificate is not trusted. This error occurs during the certificate chain validation process of the receipt's PKCS#7 container. My implementation uses node‑forge to decode the receipt, extract the embedded certificate chain, and verify that the chain properly links from the leaf certificate (which directly signed the receipt) through the intermediate certificate to the trusted Apple Inc. Root certificate. What the Error Indicates: "UnknownCertificateAuthority" at depth 0: This suggests that the leaf certificate in the receipt is not being recognized as part of a valid chain because it cannot be linked back to a trusted root in my CA store. "Certificate chain validation failed: Certificate is not trusted": This means that the entire certificate chain does not chain up to a trusted certificate authority (in this case, the Apple Inc. Root certificate) as expected. Steps Taken: I verified that the receipt is a valid PKCS#7 container. I extracted the certificate chain from the receipt. However, the receipt only provided the leaf certificate. I manually added the intermediate certificate (AppleWWDRCAG5.pem) to complete the chain. I loaded the official Apple Inc. Root certificate (AppleIncRootCertificate.pem) into my CA store. Despite these steps, the validation still fails at depth 0, indicating that the leaf certificate is not recognized as being issued by a trusted authority. Request for Assistance: Could you please help clarify the following points: Is the certificate chain for receipts (leaf → intermediate → Apple Inc. Root) as expected, or has there been any change in the chain that I should account for? Is there a recommended or updated intermediate certificate I should be using for receipt validation? Are there known issues or recent changes on Apple's side that might cause the leaf certificate to not be recognized as part of a valid chain? Any guidance to resolve this certificate chain validation error would be greatly appreciated.
1
0
323
Mar ’25
Reuse a product id from app A in app B for In-app purchase in my iOS app
I have an app which is already on App Store with In-app purchase. Now I want to integrate In-app purchase in my another app for the same products as in the existing app. Both the apps are using same Apple Account. Can I reuse those Product Ids from the first app in the second one. If yes, what is the ways to use them. Thank you in advance.
1
0
87
Apr ’25