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.
StoreKit
RSS for tagSupport in-app purchases and interactions with the App Store using StoreKit.
Posts under StoreKit tag
200 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I am the Lead iOS Developer for The Incc, an upcoming social networking application. The platform offers subscriptions that grant users access to premium content, primarily digital magazines showcasing diverse cultures, alongside standard social media features and additional unique functionalities.
I am exploring two specific use cases for our subscription model.
Promo Codes with Split Payments:
We plan to collaborate with the our influencers (referred to as Mover Shakers) by providing them with promo codes for users to purchase subscriptions. For such purchases, we aim to implement a revenue split model, allocating 10% to the influencer and the remainder to us after Apple’s fees.
Gifting Subscriptions:
We also wish to enable users to gift subscriptions to others within the app.
I understand that the Apple Subscription Service does not natively support these features.
What other options do we have to achieve this that are also not against the Apple's guidelines.
Hello, Apple App Store Server API Team!
I have one questions about the identifiers provided by Apple App Store Server API. Could you please answer?
We are running an iOS App. In our app, the transactionId we get from Apple App Store Server API is called T1. (Example)
Q1. Is it correct that other iOS apps cannot get T1 for transactionId from Apple App Store Server API? (I'm wondering if the transactionId is globally unique across apps.)
Thank you!
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.
I'm using Transaction.environment to determine server behavior.
https://developer.apple.com/documentation/storekit/apptransaction/environment
https://developer.apple.com/documentation/storekit/appstore/environment
I gather this information on the app using StoreKit and then send it to the server:
originalTransactionId = transaction.originalID
originalTransactionEnvironment = transaction.environment
When testing within Xcode, on a simulator, the value sent to the server for originalTransactionEnvironment is Xcode - as expected.
When testing on a device using a TestFlight build, the value sent to the server for originalTransactionEnvironment is undefined/nil. I expected it to be Sandbox - and later in production it should be Production.
Most importantly, the value sent to the server for originalTransactionId in the TestFlight version is not undefined/nil - it is the value I expected it would be. The transaction was originally for a subscription purchase, if that makes a difference.
So the transaction is available, and information like originalID is also available. Why is transaction.environment not available? What is the behavior in production?
So, we've implemented IAP with StoreKit2 e2e for both the client and backend and it's working mostly perfectly, however we have an issue which we can't seem to understand Apple's behavior.
So, imagine a purchase that occurred on the 10th of December in the sandbox environment through an install from TestFlight, and this same purchase keeps getting queued in the Transaction.unfinished list for some reason (today, the 17th of December, a whole week after the initial purchase!).
Here's the flow:
We iterate the list on app launch
Send the unfinishedTransaction's transactionId to our servers
The server says "hey, we could verify it with Apple but it's not longer active (expired). We can't really work with it so just finish it on your side and don't send it to me again"
The client finishes!! the transaction
On the very next app launch it keeps reappearing in the Transaction.unfinished queue
Are we doing something wrong, why doesn't it get cleaned? Is this an expected behavior?
Note, this is generally the server's logic for new purchases:
If we weren't able to contact Apple - we tell the client to not finish the transaction so that we'll be able to re-iterate it on the next app launch or retry
If the transaction is not expired and valid - we update our records and tell the client to finish the transaction
If we couldn't update our records - we tell the client to not finish the transaction so that we'll be able to re-iterate it on the next app launch or retry
If the transaction is not valid for some reason - we tell the user to finish the transaction
The server might see it as a valid transaction if we'll send the originalTransactionId instead of the 'transactionId(using it to callgetTransactionInfoinAppStoreServerLibrary`), but is this something we want to do?
This will obviously not fix the problem because the server tells the client to finish the transaction anyways, but it simply doesn't work.
Please, any advice or changes to make to either Client/Server would be greatly appreciated
Best Regards, Ofek
So I've run a promo for my which offerred a free purchase for a while.
Some people - and it looks like mostly in Germany - ran into an issue that the purchase would fail with SKError.Code.unknown.
One user noted that if you cover FaceID and use your password when making the purchase it would succeed.
That was then my guidance and it seemed to have worked for everyone.
Is there a way from my side to prevent that error?
So I ran a promo for my app that got me 30k downloads or so. The app was free for a day and so it got lots of "purchases". There were two errors from StoreKit2 that I can't explain (I'll detail the other one in another post)
This one:
StoreKit.StoreKitError.systemError(Error Domain=NSCocoaErrorDomain Code=4097 "connection to service with pid 19497 named com.apple.storekitd" UserInfo={NSDebugDescription=connection to service with pid 19497 named com.apple.storekitd}
There are various theories online that the display name of the purchase could be an issue.
Another was that this indicates that this indicates that a helper process has crashed.
Generally my guidance was to restart the device and that seemed to resolve it for most if not everyone. But not everyone reached out and it rained bad reviews and I was accused of a bait and switch and so on.
Is there any way to mitigate this? Any way to address it? It doesn't happen for everyone but it happens very frequently still.
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 *** purchase."."***" is purchase product id.
Why does this error occur, and how can I fix it?
Guideline 3.1.1 - Business - Payments - In-App Purchase
We found in our review that your app or its metadata provides access to mechanisms other than in-app purchase for purchases or subscriptions to be used in the app, which does not comply with the App Review Guidelines. Specifically:
Your app's Thanks window includes the following call-to-action and/or URL that directs users to external mechanisms for purchases or subscriptions to be used in the app:
After generating icons, a "Buy me a coffee" button is presented that goes to a website to make a purchase.
I literally just want my app to be able to take "tips" without going through apple in app purchases, because the cut they take is INSANE
Hi everyone,
I'm encountering an issue with StoreKit 2 and subscriptions that I hope someone can help clarify.
Here's the scenario:
A user purchases a subscription.
The user cancels the subscription in their Apple ID settings (it remains active until the end of the billing period).
While the subscription is still active, the user reopens the app and tries to repurchase the same subscription.
The problem:
The purchase() method start well a new billing flow, but once confirmed throws a StoreKitError.unknown.
Despite this error, the subscription gets re-enabled and appears active again in the currentEntitlements.
So my question is why the purchase method throw an error and how to deal with this case ?
I precise I'm currently only working in sandbox, maybe the behavior is different in production (but even in that case there is still a bug in Sandbox that should not happen).
Also in that case the Apple Server Notification API send the webhook with type DID_CHANGE_RENEWAL_STATUS (and subtype AUTO_RENEW_ENABLED), which is expected.
Thanks for help,
Gregoire.
Hello, I've been trying to get the sandbox environment working for in-app purchases, but so far, no luck. I can use a storekit config file to simulate purchases just fine. The item is a single consumable product.
I've checked that my product ID matches, followed the advice tendered to other forum users, created a sandbox user, all to no avail.
I've signed into the app store using my sandbox account on one phone - I can't get the "Sandbox User" option to appear on the second after attempting to make a purchase (per https://developer.apple.com/documentation/storekit/testing-in-app-purchases-with-sandbox ).
What I'm wondering is, do I need to get the in-app-purchase approved/released through App Review before I can even perform testing or something? I've signed all agreements, set up our banking information, everything seems to be in order, but I just cannot get the StoreKIt products call to return anything. ( let products = try await Product.products(for: productId) )
Is there anything else I can check? I've also checked everything here: https://forums.developer.apple.com/forums/thread/652077
Thanks!
My submission was rejected because (among other reasons) of this:
"Guideline 2.1 - Performance - App Completeness
We found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, your app did not load its content and the activity indicator spun indefinitely in subscription page. Please review the details and resources below and complete the next steps."
The issue here is that I use SubscriptionStoreView. The screenshot that the review team attached shows a loading spinner with a text "Loading subscription" - that view is already part of SubscriptionStoreView.
The problem here is how to prevent rejections like this. By using SubscriptionStoreView we get convenience because a lot of things are handled automatically, but there is no way to force reload and there are no callbacks in case loading of products breaks.
What is the recommended solution, except for not using SubscriptionStoreView and making a custom view?
It feels kind of stupid to have your app rejected because one of the Apple provided views malfunctions.
I am having a very strange problem with await ExternalLinkAccount.canOpen
On some apps using the same project and code (different targets) it reports false, but works in the simulator.
Some apps work both in the simulator and a device and, but some apps only work in the simulator. They are all sharing the same code.
What could be wrong? They all have SKExternalLinkAccount and the correct url in plist and they also have the com.apple.developer.storekit.external-link.account entitlement
I'm developing StoreKitV2 and my app provides in-app management of subscription. so I use AppStore.showManageSubscriptions method.
@MainActor
static func showManageSubscriptions(in scene: UIWindowScene, subscriptionGroupID: String) async throws
the document(https://developer.apple.com/documentation/storekit/appstore/showmanagesubscriptions(in:subscriptiongroupid:)) says
"Presents the App Store sheet for managing subscriptions for a subscription group." but actually It shows the list of subscription groups.
I wanna show the list of subscription options(products) of certain subscription group directly.
how can I??
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?
In one of My Apps I want have a "tip" option for users, so they can support the developer if they like the App. As a small tank you, "tipping" will unlock a small bonus feature (nothing essential, but nevertheless nice to have). According to the Guidelines this is perfectly fine and explicitly allowed.
So a created a few IAP options with different prices as non-consumable one-time purchases and the same number of consumable one-time-purchases with the same prices (so no subscriptions at all).
The idea is: users should be able to tip multiple times if they want to (actually many users of the old App version have asked for this)
Non-consumable IAP items can only be purchased once, but these can be restored (for example when switching to a new device).
Consumable IAP items can not be restored, but these can be purchased multiple times.
The idea is to combine both, so it is possible to tip multiple times (via consumable IAPs) and to allow the restore of previous purchases (to unlock the bonus feature). To do this, the App would at first only offer the non-consumable IAP items in its "tipping" screen. Only after these were purchased, the App would then only offer the consumable IAP items. Users tipping only once would always purchase the non-consumable item that can be restored. Users who have tipped multiple times would also have purchased the non-consumable IAP once and in addition the consumable item, so they all can restore and unlock the bonus feature. And no one is confused about any internal differences (consumable vs non-consumable), because the users will always see only one tipping option.
I've created these IAP items and send them to Apple for review together with this explanation. All the non-consumable items got approved, all the consumable items got rejected with the following bizarre and unhelpful note from the review board:
3.1.1 - new IAP type
New type: Consumable
Previous type: Non-Consumable
Recommend: Download
The binary of the app is new (more than 14 days).
What exactly does this mean? I've read section 3.1.1 of the guidelines and nothing indicates anything which would allow any rejection here. And what does "the binary of the app is new" mean? Sure the App is new (currently the new version is tested via TestFlight), but what does this have to do with the IAP?
With normal "Appstore rejections" there was always a link provided which allowed to contact the review team. But there's absolutely nothing available here. Just this bizarre note which doesn't give any clue what's wrong.
Does anyone have an idea what's wrong, or what I need to do to get this approved? How can I contact the review team that is responsible for this IAP review?
BTW: I've tried to get this approved again after changing the description/names of the localization a bit (because these are the only things which are marked in red), but the same strange note came back.
And the localization title and description can not have a long text, so there're not that many possible variations available which describe the IAP correctly.
Hi,
I have 6 subscriptions in a subscription group. Each subscription has 2 active promotional offers configured. One is with a 25% offer for a month and another one is a 50% offer for a month.
My doubt is, can users access both promotional offers in a single subscription? Not at a time
First 25% offer and then 50% offer
Hello everyone,
I want to set up subscriptions but I'm having problems testing them.
Indeed, when I use the storekit file to view the subscriptions it works, I see the subscriptions and I can subscribe in XCODE mode.
However, I'd like to go further and test with server notifications. So I removed the storekit file from the scheme, but I can't retrieve the products.
The application doesn't retrieve any products.. I've been stuck on it for 2 weeks... I checked the contracts and put in all the information last Friday and everything is validated.
I tested it in testflight mode, and it doesn't recognize any products!
Just so you know, I use the original API for maximum compatibility.
If a user applies for and is approved for a subscription refund by Apple, we understand that the developer can receive a server notification of "REFUND."
However, this notification doesn't include the refund amount.
Therefore, we thought about linking the refund amount information output in the financial report "All Countries or Regions (Detailed)" with individual end-user transaction information.
However, it seems that this report doesn't have a transaction ID, and the records appear to be aggregated daily.
Is there any way we can find out how much was refunded to which user for individual refunds?
If a user applies for a subscription refund from Apple, are there cases where only a part of the plan, rather than the full amount, is refunded?