I'm developing storekitV2, my app is providing the way to refund some product, and I use method below.
func beginRefundRequest(in scene: UIWindowScene) async throws -> Transaction.RefundRequestStatus
however when i call the method, the modal view presented but the view shows error with message 'cannot connect'. when I select retry button, something done with indicator and get same result.
how can I solve this problem?
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
Created
Hi! Could you please clarify when and why the subscription auto-renewal rate in TestFlight was changed to a daily cycle? Now, the subscription lasts for 6 days! This is causing significant issues in testing. Previously, the 5-minute auto-renewal for weekly subscriptions was an excellent solution.
Is there a way to adjust the auto-renewal timing for an account in TestFlight?
Documentation link: https://developer.apple.com/help/app-store-connect/test-a-beta-version/subscription-renewal-rate-in-testflight.
Thank you for your clarification!
Hi, I have deployed my app on Test Flight, I have two subscriptions, monthly and yearly. User can have one of them at a time and upgrade, downgrade to the other. Upgrade, downgrade, cancel from the Apple Settings worked fine in the sandbox environment when testing locally. Now when I have deployed the app on TestFlight, I was able to purchase the subscription successfully from my app. Now when I want to cancel my subscription from the Apple Settings it gives me the following error after confirming cancellation, 'Your request is temporarily unable to be processed. Please try again later.' Also the other subscription offer (yearly) is also not shown to which I could upgrade, even though in the sandbox I was able to upgrade downgrade from the settings. Another thing I have noticed is that the app Icon or name is not shown anywhere in settings with the subscription. Instead of app icon only empty square is shown. Even though app icon shows fine everywhere else.
Can someone please help me figure out this issue?
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
In-App Purchase
TestFlight
App Store Server API
My App payment encountered a unkonw((StoreKit.StoreKitError) error = unknown) error in iOS18.2, then the lldb log "Could not find a visible window in the scene for xxx purchase."."xxx" is purchase product id.
Why does this error occur, and how can I fix it?
The documentation mentions the following:
Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code. This approach ensures you don’t have to switch between URLs while your app is in testing, in review by App Review, or live in the App Store.
This way, you can use one server environment to handle both Sandbox and Production environments. It is necessary to pass App Review.
However, I'm not manually hitting these URLs - I'm using Apple's libraries.
Specifically, the environment is used in SignedDataVerifier and AppStoreServerAPIClient.
(I can't link to these because, for some reason, the domain apple.github.io is not allowed. The documentation for these is only found there. You can find it quickly by searching these terms and the domain.)
Here is how SignedDataVerifier is being used:
const verifier = new SignedDataVerifier(
appleRootCertificates,
APPLE_ENABLE_ONLINE_CHECKS,
APPLE_ENVIRONMENT,
APPLE_BUNDLE_ID,
APPLE_APP_ID
)
const verifiedNotification: ResponseBodyV2DecodedPayload = await verifier.verifyAndDecodeNotification(signedPayload)
if (!verifiedNotification)
{
// Failure
return
}
Here is how AppStoreServerAPIClient is being used:
const appStoreServerAPIClient = new AppStoreServerAPIClient(
SIGNING_KEY,
APPLE_IAP_KEY_ID,
APPLE_IAP_ISSUER_ID,
APPLE_BUNDLE_ID,
APPLE_ENVIRONMENT
)
const statusResponse: StatusResponse = await appStoreServerAPIClient.getAllSubscriptionStatuses(originalTransactionId, [Status.ACTIVE])
In the source code for SignedDataVerifier.verifyAndDecodeNotification, I can see that it throws a VerificationException(VerificationStatus.INVALID_ENVIRONMENT) error .
So for SignedDataVerifier is it as simple as wrapping my code in a try/catch and checking that the error's status code is 21007? I'm unsure about this because if you scroll to the bottom of the linked source code file, you can see the enumeration VerificationStatus, but it's unclear if this member has a value of 21007.
The source code for AppStoreServerAPIClient only says that it throws an APIException if a response could not be processed, so I'm not too sure about how to handle this one.
After the release of StoreKit 2.0, the in-app purchase failure rate increased by 63.19%, with the majority of errors being StoreKitError.unknown. When encountering this error, many users repeatedly attempt to make a purchase, but the outcome remains unchanged, resulting in the same unknown error.
In some cases, users who wait approximately 2 minutes before retrying the purchase may either succeed or encounter the following error:
“StoreKit.StoreKitError.systemError(Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.storekitd”)”.
This issue has directly impacted our app's purchasing flow.
Because our app only displays the promotional purchase offer once, these issues have significantly reduced the number of users successfully completing the offer. As a result, the conversion rate for this promotion has dropped well below expectations, negatively impacting our business metrics.
Hello!
I am attempting to add Subscriptions to an App that Is already published on the App Store.
I cannot get Xcode to actually sync what is in my App Store Connect.
When adding the Storekit configuration file, I go through the automatic linking process and select the proper bundleID. The configuration file says 'Synced @ [CurrentTime]' however there are no subscriptions listed in there.
I have attempted deleting the file several times, creating a new subscription group. With no success.
Do I need to publish the subscriptions without the features first? Upon attempting to write the supporting code that will enable these features within the app, I cannot get Xcode to identify that I have these subscriptions.
I have also tried pushing these to TestFlight, still with no success.
Thank you.
I did an in app purchase in my development app and now I cannot get rid of it. It is a "monthly" subscription that seems to renew every 1 day.
I can see the subscription when I go to settings then tap on Subscriptions.
Then I tap the item and choose "Cancel Subscription", revealing a new modal sheet saying "Confirm Cancellation".
When I "Confirm", I get the popup:
"Your request is temporarily unable to be processed, please try again later".
However, this is anything BUT temporary, has gone on for a couple weeks now.
As such, I am unable to test subscriptions in my development app.
I've tried logging out, restarting, different devices, etc.
The phone is logged in under my primary user account, and I may not have been logged into sandbox email when I did the purchase.
Can someone forcibly remove it for me?
I have been struggling to test the IAP response but it is returning empty. I am now in the very beginning of one app, and I don't want to submit the contacts and banking and tax stuff that early. are these necessary for even testing IAP results locally? I think it does not make sense if I have to.
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 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?
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
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.
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.
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.
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)
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!
Does anyone know why I set the offer code in Apple Store Connect, but when I call SKPaymentQueue.default().presentCodeRedemptionSheet() in the app, the app icon does not appear and I cannot find the offer code?
THX
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?
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.