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

Created

Can users create their own subscription plans?
I'm considering developing an app where users can create their own subscription plans by freely setting their prices, similar to YouTube's membership feature. I understand that in-app purchases must be used to unlock features within the app. With that in mind, I searched for APIs to enable this functionality but couldn't find relevant information. When I contacted Apple directly, they mentioned that they couldn't provide specific answers unless the app is under review. If anyone has knowledge about the following points, I would greatly appreciate your response: Is it possible to implement a feature similar to YouTube's membership using in-app purchase APIs? If it's not feasible with in-app purchases, is it allowed to use external payment services like Stripe?
0
0
300
Dec ’24
SKProductsRequest Randomly Returns All Product IDs as Invalid Despite Correct IDs
We're experiencing an unusual issue with SKProductsRequest in our app's in-app purchases. Despite confirming that all our product IDs are correct, the invalidProductIdentifiers property of SKProductsResponse sometimes contains all the requested product IDs. Here are the specifics: The issue occurs randomly and is not persistent. For instance, around 2024-12-26 -8.0 01:06:04, this problem occurred 3 times in quick succession. The didFailWithError method of SKRequestDelegate is not triggered, reporting no errors. Some users report that after encountering this issue, it resolves itself after about an hour. However, other users have reported this problem persisting for several days. We have repeatedly verified the correctness of our product IDs. Given the intermittent nature of the problem, we suspect this might be an issue on the App Store server side. We're looking for suggestions to resolve or mitigate this issue to improve the reliability of in-app purchases in our application. Has anyone encountered a similar issue? Or does anyone have suggestions that could help us further diagnose and resolve this problem?
0
1
339
Dec ’24
How do I finish and track Consumable IAPs with StoreKit 2?
Hi, I'm attempting to use StoreKit 2 and SwiftUI to add a tip jar to my iOS app. I've successfully added consumable IAPs for each of my tip sizes, and used ProductView to show these on my tip jar screen. However, I am at a loss on how to do the following things: How and when do I finish the consumable IAP transaction? I see the finish() function in the documentation, but I am not sure how I can call it given that ProductView is handling the purchase for me (I have no access to a Transaction object). How can I track the amount of consumable IAPs the user has purchased across all their devices? I want to show the user the amount of money they have tipped in total. I have added SKIncludeConsumableInAppPurchaseHistory to my Info.plist and set it to YES as suggested here: https://forums.developer.apple.com/forums/thread/687199 This is my first time using StoreKit 2 (until now, I was using StoreKit 1), so I would really appreciate any advice and guidance you can provide. Thanks!
0
1
254
Jan ’25
StoreKit2 - Maintain property of purchased products
Hi everybody! I'm desperately looking for help as I'm stuck with a rather fundamental problem regarding StoreKit2 - and maybe Swift Concurrency in general: While renovating several freemium apps I'd like to move from local receipt validation with Receigen / OpenSSL to StoreKit2. These apps are using a dedicated "StoreManager" class which is encapsulating all App Store related operations like fetching products, performing purchases and listening on updates. For this purpose the StoreManager holds an array property with IDs of all purchased products, which is checked when a user invokes a premium function. This array can have various states during the app's life cycle: Immediately after app launch (before the receipt / entitlements are checked) the array is empty After checking the receipt the array holds all (locally registered) purchases Later on it might change if an "Ask to Buy" purchase was approved or a purchase was performed It is important that the array is instantly used in other (Objective-C) classes to reflect the "point in time" state of purchased products - basically acting like a cache: No async calls, completion handler, notification observer etc. When moving to StoreKit2 the same logic applies, but the relevant API calls are (of course) in asynchronous functions: Transaction.updates triggers Transaction.currentEntitlements, which needs to update the array property. But Xcode 16 is raising a strict error because of potential data races when accessing the instance variable from an asynchronous function / actor. What is the way to propagate IDs of purchased products app-wide without requiring every calling function as asynchronous? I'm sure I'm missing a general point with Swift Concurrency: Every example I found was working with call-backs / await, and although this talk of WWDC 2021 is addressing "protecting mutable states" I couldn't apply its outcomes to my problem. What am I missing?
3
0
604
Jan ’25
Offer Not Available: Your Account is Not Eligible for this offer. . .
We have in-app purchases live and working fine for standard subscriptions. We also have promotional offers active for existing users (to give existing users a discount as a thank you). Yet, regardless of the user type (existing vs new... we have tested with all types), we get the "Your account is not eligible for this offer" error message when clicking the discounted offer. What is the logic for determining eligibility? I'm trying to debug as it's not clear to me why this message would show up. We are using React Native IAP. In general, how does the eligibility check work? What conditions are being evaluated and compared? And what could break those conditions? I appreciate your help! DDD
0
2
441
Jan ’25
TN3138: Handling App Store receipt signing certificate change
Hi (from France) I have a MacOS application which handles the App Store receipt by requesting at the url "https://buy.itunes.apple.com/verifyReceipt". From the response, I can know what are the inApps bought by the user and that suits for me. I don't know if if I must change something in my code accordingly to this TN3118. Does someone knows the response ? Best regards.
0
0
395
Jan ’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
333
Jan ’25
iOS promotional code eligibility
I am implementing promotional codes for auto-renewing subscriptions in my app. I need to create the codes and have them link to a discounted auto-renewing subscription. So my normal 1 month subscription is $24.99, I would like to offer users (new subscribers and existing/expired subscribers) the ability to enter a promo code that discounts the price of the first month to $4.99, then $24.99 after the initial first month. All users, regardless of whether or not they have has a previous subscription or not should be able to use this code for this discount. From what I am seeing in documentation, promo codes are only available to users that have had a subscription previously? Currently I am receiving the response "Offer Not Available" with the error: <SKPaymentQueue: 0x2815f0d60>: Payment completed with error: Error Domain=ASDServerErrorDomain Code=3904 "Offer Not Available" UserInfo={NSLocalizedDescription=Offer Not Available I simply do NOT understand why apple engineers have to make something that should be somewhat straightforward, be SO COMPLEX, then when you try to figure out whats going wrong, no meaningful error to troubleshoot. WTF I have tried this on users that have had a previous subscription and still the same error.
3
0
487
Jan ’25
MacOS App crashes after Apple ID login fails
I tried to get this post into the StoreKit forum because this issue is relative to In-App Purchases. My App has In-App Purchases, which work, no issues here. My App has been on the App Store for a number of years, with changes along the way. Recently, I uploaded V5.1 (Lottery Snitch) for review and the reviewer found something that had eluded everyone, until now. Since my App has In-App Purchases, of course I have Restore In-App Purchases as a User selectable function, on the menu at the top. The reviewer reported my App as crashing when this option was selected, which was a new thing since my App has been functioning for years. Skipping the next several communications and moving on to the most current findings.. If my App is put onto a Mac, iMac.. Where the User has never used my app before (this eliminates leftover data files), if the User then logs out of their Apple ID prior to running my app, starts my app, selects Restore In-App Purchases the User is then presented with Apple's Request to Log-In (this has nothing to do with me..not my code..it is all 100% Apple Login request). Now, completely ignore the request for login, allow my App to complete its wait period, the User can execute any task they wish. The App runs just fine. As soon as the User selects 'Cancel' on the Apple ID login pop-up screen, my App crashes. The Apple Login request is triggered by the restoreCompletedtransactions function for the StoreKit. The crash report indicates the DispatchQueue was the code running at the time. Thing is, my code has no DispatchQueue running. When the wait-timer completes (obvious on-screen loop) my code has zero Dispatch's running. When my code called the restoreCompletedTransactions it was not inside a Dispatch of my creation. Anyone see this before? Anyone have a suggestion how to make this stop? FYI, go ahead and login to your Apple ID when prompted and everything completes just fine. Yes, this problem exists in the current version(V5.0) available for download on the AppStore. It would take another post just as long to explain how this slid by on Development machines, just as weird. What to do? (JSYK:The App does not crash during development when running inside Xcode)
2
0
449
Jan ’25
Inquiry about Successful Subscription Without Payment Charge
Hi, I'm a server developer working on an iOS app, and I've encountered an interesting case that I'd like to understand better. We received a user report indicating that they were able to successfully start a subscription without any charge being processed on their payment method. The subscription appears to be active in our system and we can verify the receipt with Apple's server, but the user claims no payment was deducted from their account. I'm curious to know: Are there any known scenarios where a subscription might activate without an immediate payment charge? What would be the recommended way to handle such cases from the developer's perspective? Could this be related to any specific subscription states or edge cases in the IAP system? Any insights or documentation references would be greatly appreciated. I want to ensure we're handling our subscription logic correctly and providing the best experience for our users. Thank you in advance for your help!
0
0
181
Jan ’25
Handling non-consumable in-app purchase tiers
How would you go about handling this sort of situation? An app has two tiers of non-consumable in-app purchases. The IAP simply unlocks a certain level of access in the app: The first tier for $1.99 allows the user to add up to 50 things. The second tier for $3.99 allows the user to add up to 200 things. If the user has not bought an IAP the app will show the two tiers available for purchase. The user then buys Tier 1 and happily goes about adding some things to the app. The app now only shows Tier 2 available for purchase, because Tier 1 has been purchased. A few weeks go by and they realise they need to add more than 50 things. Would the user have to suck it up and just accept they should've paid the $3.99? Or, could a new Tier 1.5 be added that's a kind of upgrade price of $2.00 (the difference between the two original tiers) to unlock the higher 200 things level? I doubt this would work properly, because although I can control that tier being displayed or not in the app, I cannot control it in the App Store product pages, and it would be displayed among the Tier 1 and Tier 2 levels, so people would just buy that rather than the full priced Tier 2. How should I handle this situation? Just have the one tier (Tier 2) and make it simpler?
1
0
366
Jan ’25
Example requests for Apple Server Notifications V2
Dear Apple Support, We are currently in the process of migrating from Apple Server Notifications v1 to v2. As you know, once we switch from v1 to v2 in App Store Connect, this change is irreversible. Our team needs to ensure that our backend environment, developed in Python with Django and using the app-store-server-library==1.5.0, is fully prepared to handle all possible notification types before making that final switch. While we can receive a basic test notification from Apple, it doesn’t provide the range of data or scenarios (e.g., INITIAL_BUY, RENEWAL, GRACE_PERIOD, etc.) that our code must be able to process, store in our database, and respond to accordingly. Without comprehensive, example-rich raw notification data, we are left guessing the structure and full scope of incoming v2 notifications. Could you please provide us with a set of raw, fully representative notification payloads for every notification type supported in v2? With these examples, we can simulate the entire lifecycle of subscription events, verify our logic, and confidently complete our migration. Thank you very much for your assistance.
1
0
492
Jan ’25
Transaction.id will be repeated in Apple in-app purchase
In the sandbox environment, when I quickly and repeatedly purchase an item, Transaction.id will be repeated. Will there be duplication in the production environment? func pay(productId: String, orderId: String) async { guard !productId.isEmpty, !orderId.isEmpty else { return } let orderObj = ApplePayOrderModel.init(orderId: orderId, productId: productId) do { let result = try await Product.products(for: [productId]) guard let product = result.first else { return } let purchaseResult = try await product.purchase() switch purchaseResult { case .success(let verification): switch verification { case .verified(let transaction): orderObj.transactionId = String(transaction.id) await transaction.finish() case .unverified(let transaction, let error): await transaction.finish() } case .userCancelled: break case .pending: break @unknown default: break } } catch { print("error \(error.localizedDescription)") } }
1
0
224
Jan ’25
Response of the server-side verifyReceipt endpoint when using offer codes
Hi, We use the (now deprecated) server-side receipt verification API (*1) with the app we are maintaining and there are some points I would like confirm on how its response changes based on whether the purchase being processed was a subscription that used an offer code or not. I am particularly concerned about the following: Are there any properties of the response that are added or missing? Is there any property indicating that an offer code was used? If there is, which field is that and what values does it take? Are there any special steps or options required when processing the receipt which used an offer code on the server side? *1 https://developer.apple.com/documentation/appstorereceipts/verifyreceipt
0
0
244
Jan ’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
281
Jan ’25
Clarification on offerIdentifier Behavior in TransactionPayload and Upgrade Scenarios
Hello everyone, I have some questions regarding the behavior of the offerIdentifier property in the TransactionPayload from App Store Server Notifications. When a user redeems an Offer Code, the offerIdentifier field is populated with the respective identifier. However, I am unsure how this field behaves in different scenarios, and I would appreciate any insights or clarification: Does the offerIdentifier persist throughout the subscription lifecycle (from the initial purchase to expiration)? Does it become null once the Offer Code benefits expire? Is it only present at the time of purchase and omitted in subsequent notifications? Additionally, I would like to understand the behavior of the offerIdentifier in the following scenario: A user purchases a lower-tier subscription using an Offer Code. Later, they upgrade to a higher-tier plan, causing the Offer Code benefits to effectively expire. What happens to the offerIdentifier in the transaction for the upgrade? Will it still appear in transactions after the upgrade, or will it be null? I couldn't find explicit details about these situations in the official documentation, so I hope someone here might have experience or knowledge to share. Thank you in advance for your help!
0
0
387
Jan ’25
unable to get subscription products macos iap xcode swift
Hi Apple Support, I am encountering an issue while testing in-app purchases in the sandbox environment. I have created a sandbox tester account Logged out of the App Store and System Settings on my Mac. My main developer account is signed in under Sign In & Capabilities in Xcode. The Bundle ID matches the one configured in App Store Connect. The Product ID I am querying also matches the configuration. Deleting the app and reinstalling. Restarting my Mac. When running my code in debug mode, I observe the following: Running debug build App Store environment: Production [1b294b55] Error updating Storefront: Error Domain=StoreKit_Shared.StoreKitInternalError Code=7 "(null)" Valid products: [] Invalid product IDs: ["com.x.x.x.monthly"] No products found The Product ID (com.x.x.x.monthly) matches the one I have configured in App Store Connect. The bundle id matches. When I create a StoreKit Configuration file in Xcode and sync it with my app, I can see the product IDs correctly. Below are the relevant code snippets for fetching and handling products: func fetchProducts() { guard !productIDs.isEmpty else { print("No product IDs configured") return } let request = SKProductsRequest(productIdentifiers: productIDs) request.delegate = self print("Starting product request...") request.start() } func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { DispatchQueue.main.async { print("Valid products: \(response.products)") print("Invalid product IDs: \(response.invalidProductIdentifiers)") self.products = response.products if self.products.isEmpty { print("No products found") } else { print("products not empty") for product in self.products { print("Fetched product: \(product.localizedTitle) - \(product.priceLocale.currencySymbol ?? "")\(product.price)") } } } } func debugStoreSetup() { if let receiptURL = Bundle.main.appStoreReceiptURL { if receiptURL.lastPathComponent == "sandboxReceipt" { print("App Store environment: Sandbox") } else { print("App Store environment: Production") } } else { print("No receipt found") } } Could you help identify why my app is not recognizing the Product ID in the sandbox environment? Thank you for your assistance.
2
3
850
Jan ’25