I enter the payment wall, there it takes more or less 3 to 4 minutes to show the plans, when I select the monthly plan the loader is shown and from there the pop up to make the purchase in sandbox does not appear, I have waited until a maximum of 50 minutes and it is not shown, I go back and close the app I do the same steps and I am still there, without showing the pop up.
Doing this same process in xcode, everything happens immediately without any interruption.
StoreKit
RSS for tagSupport in-app purchases and interactions with the App Store using StoreKit.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
This is a copy of a reply to this post.
https://developer.apple.com/forums/thread/722222?page=1
I'm posting as new in the hope someone might have more up-to-date information, as I'm pulling out what little hair I have left.
I'm using Storekit 2, testing in Xcode with a local Storekit config file. I have created a very minimal system to investigate this issue. I have a SwiftUI-based window using SubscriptionStoreView, and my app set up with the usual listener. I have four types of auto renewing subscription, configured in the local Storekit config file.
With my app running, I subscribe to the lowest-level subscription I offer, via the SubscriptionStoreView. Notification of the inital purchase arrives, but subsequent auto-renewals do not trigger any action in my listener for Transaction.updates. They arrive as expected in the Transaction Manager. Radio silence in my listener.
If I upgrade one subscription (via my SubscriptionStoreView) I see this reflected in the UI immediately, and also in the Transaction Manager, but the update that arrives in Transaction.updates refers to the old subscription, and has the isUpgraded flag set to false.
Also, can anyone remind me what the grey warning triangle next to entries in the Transaction Manager means. I'm assuming it means unfinished, as that's what the sidebar indicates.
Can the testing system really be this broken, or am I wildly off the mark? Unless I'm doing something fundamentally wrong this all seems extremely flakey, but happy to be proved wrong.
I find this all rather unsettling if I can't test reliably, and am concerned that I my app may end up in this situation if I use storekit 2:
https://stackoverflow.com/questions/73530849/storekit-renewal-transactions-missing-in-transaction-all-or-transaction-updates
The sample code provided in https://developer.apple.com/wwdc21/10114 doesn't appear to call finish() on unverified transactions, and I haven't been able to find any documentation regarding what to do with unfinished transactions. However, Apple has always emphasized the importance of finishing transactions, and since a transaction object is provided even with the unverified state, I'd love some guidance!
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!
The majority of our sandbox calls to verifyReceipt end in an ETIMEDOUT error. This is making it very difficult to verify our purchase flow for our pending release. We have not yet migrated to StoreKit 2 and still rely on this API endpoint.
The Apple API status page reports no issues.
Is anyone else encountering this?
We’ve recently encountered an increased rate of purchase errors StoreKit.InvalidRequestError error 1 (https://developer.apple.com/documentation/storekit/invalidrequesterror) specifically on iOS 18.4.
We suspect this might be related to the new Advanced Commerce API introduced by Apple, although we haven’t made any changes related to this API in our app.
Have you experienced similar issues since the release of iOS 18.4 or when integrating the Advanced Commerce API? Any insights or suggestions would be greatly appreciated.
Thanks!
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit
In-App Purchase
Advanced Commerce API
I’m seeing an issue with subscriptions in TestFlight builds on iOS 26. Running from Xcode works as expected, and the App Store build looks fine. But when I install the same build via TestFlight, transaction.subscriptionStatus is nil.
The identical binary behaves correctly on an iOS 18 device.
Is this expected behavior on iOS 26 TestFlight, or am I missing something?
Thanks!
I want to add in-app purchasing to my app, but I can't figure out what part of my workflow is wrong.
I created a product for my app in iTunes Connect (the product ID is com.mycompany.products.***) and it's in "Ready to submit" status.
I created a sandbox test user for this app.
I connected to iTunes on a real device using the sandbox AppleID.
I went back to XCode and added in-app purchasing to my app.
I turned on developer mode on the real device and logged in as the sandbox user.
I built the app and ran it on a real device (not the simulator).
I tried to get product information (com.mycompany.products.***) but nothing was returned.
In-app purchasing is registered in App Store Connect and the status is "Ready to submit".
The code only retrieves product information in a simple way, so I don't think there's a problem.
inAppPurchase.getProducts(["com.mycompany.products.***"]).then(console.log).catch(console.error);
But it only returns an empty array.
What could be wrong?
Any help would be much appreciated.
Dear Apple Support Team,
We are currently implementing auto-renewable subscriptions in our iOS app and are testing the integration using the sandbox environment.
On the iOS app side, the in-app purchase flow completes successfully and displays a "Purchase Successful" message. However, we are not receiving any server notification callbacks on our configured App Store Server Notifications (Sandbox) webhook URL.
For your reference, the webhook URL we have set in App Store Connect (Sandbox) is:
https://9c0f-182-79-123-254.ngrok-free.app/ios/webhook
Despite successfully completing a subscription purchase in the sandbox, there is no evidence that the webhook is being triggered.
We would appreciate your guidance in resolving this issue or confirming if there are any additional configurations or steps required on our end.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
StoreKit Test
StoreKit
In-App Purchase
App Store Receipts
Hi,
Currently, instead of using a real device and test account for in-app purchase testing, we are using Products.storekit with the Simulator.
Our app offers a subscription plan with a 3-day free trial.
We would like to simulate the following test scenarios:
User cancels the subscription within the 3-day free trial period.
User cancels the subscription after the 3-day free trial period.
However, in Xcode, under Debug > StoreKit > Manage Transactions..., we couldn’t find an option to simulate a subscription cancellation.
There is an option to refund the purchase, but we believe this is not the same as a cancellation.
Do you have any idea how we can simulate these two cases using Products.storekit and the Simulator?
Thanks in advance!
Hello, I have 2 subscription group. Each group have different plans and promotional offer. I was set 1 month free promotional offer in all plans. While I subscribe any plan IAP sheet is not showing 1 month free promotional offer. I already used with new sandbox account. How can I get promotional offer in IAP sheet?
Signed renewal info from 'Get Subscription Statuses' or in server notifications never has the offerType or offerDiscountType even when the corresponding transaction does have those values set.
Our offer is a free trial.
Do these properties refer to something different in JWSRenewalInfoDecodedPayload than they do in transactions?
I'm trying to determine whether a subscription (identified by originalTransactionId) is currently in a free trial based on server notifications. The status doesn't tell us if the subscription is currently in free trial and the signedTransactionInfo may be for an older transaction.
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)
Hello,
Our server isn't receiving Apple App Store Server Notification for in-app purchases.
It works for Sandbox Server, even I sent a test notification which I received on the Production Server URL, but the real in-app payment notification isn't coming to the server.
I checked this already: https://developer.apple.com/documentation/appstoreservernotifications/enabling-app-store-server-notifications and everything here has been reviewed.
Transport Layer Security (TLS) version and others things mentioned have been checked, test notification was received. But the main in-app purchase notification for live transaction isn't coming. What's the issue precisely?
Topic:
App & System Services
SubTopic:
StoreKit
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?
I just converted my App to Freemium, but the method is used to give user, that bought the App before it was free, access to the paid futures seems not to be working.
I am getting the original Purchase Date from the AppTransaction (https://developer.apple.com/documentation/storekit/apptransaction/originalpurchasedate) and comparing that to a set date where the App Model changed. In Test Flight this is working without any Problems but on the Live System, users that have purchased the App do not get access!
let shared = try await AppTransaction.refresh()
if case .verified(let appTransaction) = shared {
result(appTransaction.originalPurchaseDate.ISO8601Format()).
}
I am using flutter to develop the App and the result()... send the string back to the flutter side.
Here is the code of the Flutter side:
Future<void> restorePurchases() async {
SubscriptionProvider().updatePayment(PurchaseStatus.pending);
await InAppPurchase.instance.restorePurchases();
if (Platform.isIOS) {
DateTime changedToFreemium = DateTime.utc(2025, 4, 7, 11, 0, 0);
String? purchaseDateRaw = await IosFlutterChannel().getOriginalPurchaseDate();
if (kDebugMode) {
print("Purchase Date Raw: $purchaseDateRaw");
}
if (purchaseDateRaw != null) {
DateTime purchaseDate = DateTime.parse(purchaseDateRaw);
if (purchaseDate.isBefore(changedToFreemium)) {
if (kDebugMode) {
print("Restoring legacy purchases");
}
SubscriptionProvider().update(true, SubscriptionStatus.active, SubscriptionType.fs_lifetime);
} else {
if (kDebugMode) {
print("Not restoring legacy purchases");
}
}
}
}
SubscriptionProvider().updatePayment(PurchaseStatus.purchased);
}
Console Log when running in Test Environment:
flutter: Purchase Date Raw: 2013-08-01T07:00:00Z
flutter: Restoring legacy purchases
Thanks!
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!
Hi there,
I have a plan of creating another app in the same niche, but I would like the actual subscribers to have access to the new app.
So the subscribers of App 1 don't need to subscribe to App 2.
Is that possible?
Thanks
Pedro M.R. Gregorio
Hi 👋! I want to switch the business model in my app from premium to freemium and do it gracefully for existing users. Essentially, I wish to provide newly-paywalled content for free to existing paid users (people who bought the original app).
It seems clear that I should be using appTransaction's originalAppVersion property to check against purchases made in a previous version of the app, per the documentation. However, there seems to be broad confusion over whether originalAppVersion returns the version number or the build number and how to test for it. Examples of confusion can be found here, here and here.
This lack of clarity seems especially dangerous due to the difficulty in testing these values. In the sandbox originalAppVersion returns 1.0 by default, so whether you design for version number or build number, you'll always return a positive as long as your value is more than 1. There is a real risk to unknowingly either never identify previous premium users or accidentally identify everyone as premium (essentially giving away your app for free).
For example, my app's current version number is 1.4.0 and build number is 18, so 1.4.0 (18). As this is a major change, for this new update I might as well go for version number 2.0.0, and let's say I release the app with build number 5, so 2.0.0 (5). If I expect originalAppVersion to return the version number, I would match it against 2, because anything before 2.0.0 needs to be marked as premium. However, if I expect the build number, I should check against 19 and respectively bump up my build number: 5 -> 19.
In the standard version/build "v.v.v (b)" format, does originalAppVersion return app version or app build?
If it indeed does return build, and not version, I guess I'll start all of my future build numbers from 100 just in case: 2.0.0 (100). The only way I imagine I can test this is to print the value on the visual interface in a live version of the app, and ask a random user 🤷♂️.
Topic:
App & System Services
SubTopic:
StoreKit
Hi everyone,
I’m experiencing an issue with In-App Purchases during App Review.
What works
My consumable IAP products load correctly using StoreKit2.
TestFlight (sandbox) purchases work perfectly.
Localizations are filled in and valid.
Paid Apps Agreement, banking, and tax forms are active.
IAP products are properly created in App Store Connect and marked as “Developer Action Needed” only because they wait for approval with the new binary.
What fails
During review I received:
“We found that your in-app purchase products exhibited one or more bugs which create a poor user experience.
Specifically, we were not able to complete a purchase.”
They didn’t provide any more technical details.
Additional context
The StoreKit configuration file is not included in the app archive.
Product identifiers perfectly match those in App Store Connect.
StoreKit2 purchase() works as expected on TestFlight.
The app does not use server-side receipt validation - purchases are handled purely through StoreKit2 APIs, as recommended.
My questions
What could cause a situation where TestFlight purchases work but App Review cannot complete a purchase?
Does Apple expect server-side receipt validation even for simple one-time consumables?
Could there be a delay or sync issue causing IAP products to not be available to the reviewer yet?
Is there anything I should check on the App Store Connect side beyond what I already verified?
Any help or hints would be greatly appreciated - I’m stuck because everything works in sandbox but fails only for reviewers.
Thanks!