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
Hello,
Is anyone else seeing Purchase.PurchaseResult.UserCancelled, despite a successful transaction?
I had a user notify me today that he:
Attempted a purchase
Entered payment credentials
Was asked to opt in to email subscription notifications
Opted In
Was shown my app's "User Canceled Purchase" UI
Attempted to repurchase
Was alerted that he was "Already Subscribed"
I have adjusted my code to check Transaction.currentEntitlements on receiving a .userCancelled result, to avoid this in the future. Is this logically sound?
Here is my code - please let me know if you see any issues:
func purchase(product: Product, userId: String) async throws -> StoreKit.Transaction {
let purchaseUUID = UUID()
let options: Set<Product.PurchaseOption> = [.appAccountToken(purchaseUUID)]
let result = try await product.purchase(options: options)
switch result {
case .success(let verification):
guard case .verified(let tx) = verification else {
throw PurchaseError.verificationFailed // Show Error UI
}
return try await processVerified(tx)
case .userCancelled:
for await result in Transaction.currentEntitlements {
if case .verified(let tx) = result, tx.productID == product.id, tx.revocationDate == nil {
return try await processVerified(tx)
}
}
throw PurchaseError.cancelled // Show User Cancelled UI
case .pending:
throw PurchaseError.pending // Show Pending UI
@unknown default:
throw PurchaseError.unknown // Show Error UI
}
}
@MainActor
func processVerified(_ transaction: StoreKit.Transaction) async throws -> StoreKit.Transaction {
let id = String(transaction.id)
if await transactionCache.contains(id) {
await transaction.finish()
return transaction // Show Success UI
}
let (ok, error) = await notifyServer(transaction)
guard ok else {
throw error ?? PurchaseError.serverFailure(nil) // Show Error UI
}
await transaction.finish()
await transactionCache.insert(id)
return transaction // Show Success UI
}
The only place the "User Cancelled Purchase" UI is displayed on my app is after the one instance of "throw PurchaseError.cancelled" above.
This happened in Production, but I have also seen userCancelled happen unexpectedly in Sandbox.
Thank you for your time and help.
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!
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!
New subscriptions have been failing to renew in the sandbox for 3 days. I am seeing multiple posts and comments from people that appear to be experiencing the same issue. But I haven't seen any feedback from Apple representatives.
I really do not want to launch a new app without seeing functioning renewals in the sandbox.
Is there somewhere else we are intended to seek assistance?
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.
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
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
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
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?
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!
works perfectly on android but doesn't work at all on IOS and i have used the same bundle id and product ids on both stores.
The error that i get on IOS is : "IAP initialization failed: NoProductsAvailable - No Product returned from store"
Here are the things that i've done:
Created an App ID on the apple developer portal with the correct capabilities
I have enabled the correct capabilities on the xcode project Unity Framework is embed and signed, Storekit (do not embed)
In singin and capabilities in-app purchases is there
I am using testflight to submit the app with a distribution certificate that appears to be valid
I've checked the the bundle identifier and it's the same everywhere (unity project, xcode project, App ID)
All of the products are cleared for sale and are in the status "ready to submit"
I always uninstall the old app version before testing the new one
My banking updates are still processing does this effect TestFlight IAP
Paid Apps Agreement is in Pending User Info state does this effect also
I still haven't filled out the tax forms, so I'm wondering if I need to complete them before my app's in-app purchases (IAPs) work in TestFlight.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
In-App Purchase
Apple Unity Plug-Ins
I've just released my first on app store. I have monthly renewing subscription on my app, there is no pay wall for few days.
When I look at my app store page after release it shows me app price upfront instead of users download the app. I know I have subscription, but I don't want it to be upfront before install
I know other store that have the same model and users get to download their app. What am I missing?