Hi everyone,
I’m encountering an issue with the in-app purchase functionality in my app during the Apple app review process, and I could use some assistance.
Problem Description:
I’ve implemented an in-app purchase feature for the first time in my app, offering lifetime access for 300 euros. The product is created as a non-consumable type in the Apple App Store. The purchase flow works perfectly in various environments: simulator, real device, TestFlight, and sandbox accounts.
However, when the Apple app review team tests the app, they encounter an error retrieving the product ID for the in-app purchase. This issue specifically occurred on an iPhone 13 Mini running iOS 17.5.
Steps to Reproduce:
Implemented the in-app purchase feature.
Created a non-consumable product in App Store Connect.
Tested the purchase flow on:
Simulator
Real device
TestFlight
Sandbox accounts
Submitted the app for review.
Environment:
Xcode version: 14.0
iOS version: 17.5
macOS version: Ventura 13.3
Device: iPhone 13 Mini (used by review team)
What I've Tried:
Verified product ID and its status in App Store Connect.
I'd like to assure you that the in-app purchase feature is correctly configured in the app and App Store Connect.
Tested on different devices and environments:
Sandbox account
TestFlight account
Real devices
Checked all provisioning profiles and certificates.
Additional Information:
Despite successfully testing in all other environments, the issue persists during the Apple app review. I've submitted the binary 3 to 4 times, but the problem remains unresolved. Apple’s provided steps for configuring in-app purchases have been followed meticulously.
Has anyone else faced a similar issue, or does anyone have insights on what might be causing this discrepancy during the review process? Any suggestions or advice would be greatly appreciated!
Thank you in advance for your help!
StoreKit Test
RSS for tagCreate and automate tests in Xcode for your app's submission and in-app purchase transactions.
Posts under StoreKit Test tag
69 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello,
when developing an app on Xcode I add the local .storekit file to the run options as seen in the attachment.
Should this option be reverted back to "None" before we submit the app to the App Store?
Because this option is only under the "Run" scheme, not "Archive", I thought it shouldn't have any impact to the App Store build.
Backstory:
I had rejections from the app review team saying that they can't access the in-app purchases. In another build I removed this option and the app got accepted. But I don't know if this was the reason or it was because in-app purchases were waiting for review.
When searching the web I've seen some people suggesting that the option should be "None".
StoreKitConfigurationFileReference
Hi,
I'm using the App Store Server API for in-app purchase receipt validation. However I received 401 error status code.
My app is ready for submit in App Store Connect, but not yet published the first version.
The receipt is generated using StoreKit test configuration and follow the Sandbox testing instruction. It is generated on a real device using Sandbox Apple account registered in the App Sandbox tester section.
If I go back to use the deprecated verifyReceipt API sandbox endpoint, I get {'status': 21002} error instead.
Is it expected for an App that has not yet published in App Store?
If not, is there any way to test the in-app purchase server-side validation before the App is release?
I implemented a store kit in my application, which was working fine until the last three months. Recently, we have encountered an issue where the store kit screen automatically dismisses when attempting to purchase an in-app product using the UPI payment method. This issue specifically occurs with consumable products. Our non-renewable products are working fine with the same code base.
Below, I have a button designed to facilitate the purchase of a subscription, which depends on the availability of the subscription in App Store Connect. This button is visible when testing locally using a StoreKit Configuration File synced from App Store Connect, and I have linked my subscription to my app in the information section. Currently, my app is in a "waiting for review" status, and the subscription is marked as "developer action needed - rejected." However, this issue of the button not appearing persisted even when the subscription was previously in the "waiting for review" status, indicating that the problem may not be related to the subscription status.
I'm encountering an issue where the 'request products' function returns no results in the TestFlight environment, even when using a sandbox Apple ID. This problem has led to repeated rejections of my app, as testers are unable to verify its functionality. What could be causing these issues?
VStack {
if storeVM.subscriptions.isEmpty {
if storeVM.isLoading {
ProgressView("Loading subscriptions...")
.progressViewStyle(.circular)
.scaleEffect(2.0)
.padding()
} else if let errorMessage = storeVM.errorMessage {
Text("Error: \(errorMessage)")
.foregroundColor(.red)
.padding()
} else {
Text("No subscriptions available")
.padding()
}
} else {
ForEach(storeVM.subscriptions, id: \.id) { product in
Button(action: {
Task {
await buy(product: product)
}
}) {
HStack {
Spacer()
Text("Unlock 3-day free trial. \nThen $23.99 per year. Cancel anytime.")
.font(.custom("Lora-VariableFont_wght", size: 20))
.foregroundColor(.white)
.lineSpacing(5)
Spacer()
}
}
.padding()
.background(Color.black.opacity(0.6))
.cornerRadius(10)
.padding(.horizontal, 10)
}
}
.onAppear {
Task {
await storeVM.requestProducts()
}
}
func requestProducts() async {
isLoading = true
errorMessage = nil
do {
subscriptions = try await Product.products(for: productIds)
isLoading = false
} catch {
print("Failed product request from App Store server: \(error)")
isLoading = false
errorMessage = "Failed to load products"
}
}
I entered Setting > App store section. But ı cannot see anything about sandbox account. What should ı do?
Hello, does anybody know how Apple anonymizes and aggregates the analytics provided to us devs?
I'm interested in understanding the extent of their privacy safeguards. Do they employ federated analytics, or do they use a less effective method?
This app was built with the iOS 16.2 SDK. Starting April 29, 2024, all iOS and iPadOS apps must be built with the iOS 17 SDK or later, included in Xcode 15 or later, in order to be uploaded to App Store Connect or submitted for distribution
How to sort this? Please help
I have testd with TestFlight but after I changed some code and info.plist, suddenly it says "Invalid Binary". Here are my info.plist changed which I got from my github repo.
Diff
code-block
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -2,22 +2,14 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
- <key>LSApplicationQueriesSchemes</key>
- <array>
- <string>https</string>
- </array>
- <key>NSPhotoLibraryUsageDescription</key>
- <string>Enlingo needs access to your photo library to save your profile picture.</string>
- <key>NSCameraUsageDescription</key>
- <string>Enlingo needs access to your camera to take a profile picture.</string>
- <key>NSMicrophoneUsageDescription</key>
- <string>Enlingo needs access to your microphone to record your voice.</string>
+ <key>ITSAppUsesNonExemptEncryption</key>
+ <false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
- <string>Enlingo</string>
+ <string>EnLingo</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@@ -27,7 +19,18 @@
<key>CFBundleLocalizations</key>
<array>
<string>en</string>
+ <string>ja</string>
<string>ko</string>
+ <string>hi</string>
+ <string>es</string>
+ <string>fr</string>
+ <string>de</string>
+ <string>pt</string>
+ <string>en</string>
+ <string>vi</string>
+ <string>zh_CN</string>
+ <string>zh_TW</string>
+ <string>zh</string>
</array>
<key>CFBundleName</key>
<string>enlingo</string>
@@ -54,8 +57,18 @@
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FLTEnableImpeller</key>
<false/>
+ <key>LSApplicationQueriesSchemes</key>
+ <array>
+ <string>https</string>
+ </array>
<key>LSRequiresIPhoneOS</key>
<true/>
+ <key>NSCameraUsageDescription</key>
+ <string>Enlingo needs access to your camera to take a profile picture.</string>
+ <key>NSMicrophoneUsageDescription</key>
+ <string>Enlingo needs access to your microphone to record your voice.</string>
+ <key>NSPhotoLibraryUsageDescription</key>
+ <string>Enlingo needs access to your photo library to save your profile picture.</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>Enlingo needs access to your microphone to record your voice.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
@@ -69,15 +82,10 @@
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
- <string>UIInterfaceOrientationLandscapeLeft</string>
- <string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
- <string>UIInterfaceOrientationPortraitUpsideDown</string>
- <string>UIInterfaceOrientationLandscapeLeft</string>
- <string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>
any suggestion or help would be appreciated...
and one more question...
I tested with storekit in XCode with copy-scheme.
Is it relevant to "Invalid Binary" that I have storekit cert and configuration?
I know it sounds ridiculous - catch a straw....
I use StoreKit's StoreView to buy in-app purchases. The purchase is working in the simulator, but how can I restore purchases? I did not find a restore handler, there is only a onInAppPurchaseCompletion but I'm missing a onRestorePurchaseCompletion or similar.
This is how it looks
This is my code:
StoreView(ids: ["my.product.id"])
.storeButton(.visible, for: .restorePurchases)
.storeButton(.hidden, for: .cancellation)
.onInAppPurchaseCompletion { product, result in
if case .success(.success(let transaction)) = result {
print("Purchased successfully: \(transaction.signedDate)")
isPremium = true
} else {
print("Something went wrong")
}
}
I want to test the in-app purchase in visionOS Simulator. I logged in to the Sandbox account in Simulator and was prompted to send the verification code to the phone number I wrote in the previous step. I entered the verification code accurately, but I couldn't log in normally. It was wet many times.
Hi,
I am following https://developer.apple.com/documentation/storekit/transaction/testing_refund_requests and trying to test refund requests.
I am able to trigger refund requests from my app (in sandbox) using https://developer.apple.com/documentation/swiftui/view/refundrequestsheet(for:ispresented:ondismiss:)
I do see that the notification URL receives a NotificationTypeV2.CONSUMPTION_REQUEST but it's not receiving NotificationTypeV2.REFUND
The product for which the refund is triggered is a consumable type
Is this expected behavior? How can I test REFUND without this?
Thanks
Hi Folks,
We have an app using StoreKit 1 (migrating soon). Sandbox testing worked well until recently. Now, the Restore API throws an error (ASDServerErrorDomain Code=5002: "An unknown error occurred"). We're using the latest Xcode/iOS on real devices. Purchase works fine, but Restore fails in Dev only (Prod is okay). Any idea what might have changed?
Thank you,
Kam
Hello,
I'm encountering an issue where my released app fails to launch only on iOS 17.4. The version of the app released through TestFlight works fine without any issues.
Specifically, when the app installed from the App Store is launched on iOS 17.4, it immediately crashes. However, I've noticed the following:
If I turn off the network connection, such as putting the device in Airplane Mode, the app launches successfully.
Once the app is launched, I can re-enable the network connection, and the app continues to run without crashing.
My app uses StoreKit2 for handling transactions and connections with the App Store. It initiates a connection to the App Store via StoreKit2 at launch. The primary difference between the TestFlight version and the production version is the App Store endpoint they connect to. This leads me to suspect that there might be an issue with the connection to the App Store.
(Another possibility is that the app communicates with Firebase or Google Admob, so there could be an issue with these SDKs as well.)
This issue only occurs in the production version, making it difficult to investigate. Are there any suggestions on what I can do to further diagnose this issue?
You can download my app from here:
https://apps.apple.com/us/app/repeatable-player-cut-loop/id616310281
I can provide the TestFlight URL if needed.
Any help or guidance would be greatly appreciated.
Hey all,
Tl;dr:
In debug-build using a .storekit file, all is good. When uploading a release build to testflight, purchasing follow the expected flow, but it does not seem the subscription status is reflected.
Full description
I've implemented auto-renewable subscriptions in my app. In debug, I've setup a scheme to use products.storekit. When I run this scheme on my device, I can subscrbe, cancel etc, and it all works as expected.
When I upload my release scheme to testflight, purchasing can be done, but changes do not seem to be reflected inside the app (i.e.e no features get unlocked).
Same thing when I run this scheme on my device. This scheme has None set for Storekit configuration.
When I set 'Storekit configuration' to the Products.storekit, file I can't make a purches at all: SubscriptionStoreView shows
Subscription unavailable. The subscription is unavailable in the current storefront'.
I've watched a number of WWDC sessions on the topic, read most (all?) of the documentation, and I just can't seem to find out what it is that needs to be done.
Unfortunately, debugging has been rather cumbersome and sometimes impossible lately, especially when trying to debug a release build.
Anyone can tell me what it is I am overlooking, or what piece of information or link I missed?
Here is the relevant code (which works OK in debug)
private func listenForTransactions() -> Task<Void, Error>
{
return Task.detached
{
for await anUpdate in Transaction.updates
{
do
{
let transaction = try self.checkVerified(anUpdate)
await self.checkSubscriptionStatus()
await transaction.finish()
}
}
}
}
And here's checkSubscriptionStatus():
@MainActor
private func checkSubscriptionStatus() async
{
var hasActiveSubscription = false
do
{
for aStatus in try await Product.SubscriptionInfo.status(for: "718A7488")
{
let state = aStatus.state
hasActiveSubscription = (state == .inGracePeriod) || (state == .subscribed)
}
}
catch
{
print(error)
}
self.hasActiveSubscription = hasActiveSubscription
}
In my Xcode 15 beta 8 setup, I'm encountering an issue with the iOS 17 simulator where StoreKit.Product.purchase() consistently throws StoreKit Error.Unknown while running XCTest.
Inside XCTest, I have declared SKTestSession(configuration: "").
I'm using try await StoreKit.Product.purchase(options: []).
However, it always throws StoreKit Error.Unknown. There's no such problem with the iOS 16.4 simulator, where I can retrieve the result and handle it appropriately. This issue is only present in the iOS 17 simulator.
Is there any necessary workaround or fix for this?
I've also included the console log output for your reference:
デフォルト 10:06:45.981812+0900 storekitd AMSURLRequest: [597e_SK2] Failed to fetch client ID domains from bag. Defaulting to not including analytics cookies. error = { Error domain=AMSErrorDomain, code=204 | URL = http://localhost:XXXXX/inApps/history?REDACTED
I have uploaded one of my app to give some paid service. But when the user tries to make an in-app purchase, it opens one screen like the title is "Apple ID, Almost there Payment request will be created for xyzdemo@ybl" After I press the continue button this window(Screen) closes automatically. But UPI requests are sent on the particular app. So why is this happening on my app? Why does this window (Screen) dismiss automatically?
I have also attached the screen.
This screen automatically dismissed.
I have a problem with submitting my app to the AppStore. I have an app in the AppStore with currently OneTime Purchase. Now I want to add an InApp purchase to this app.
I have tested the app with a local StoreKit file (with synchronised AppStore In App Products) and everything works fine. But when I submitted this file to the store, it was not accepted. So I found out that I need to remove the local StoreKit file so that it uses the real AppStore data.
But my problem is, once I remove the StoreKit file, my purchase process gets stuck in the transaction process. So when I click on the in-app purchase button, I get the payment overlay and everything about the in-app purchase is displayed there. Name, price, details. Also a sandbox title says I am not in production.
As soon as I click on the "Buy" button, I have to log in with my sandbox user account that I have previously created in AppStore connect and also verify the email address by clicking on the link in the e-mail. Then the confirmation tone sounds, but after 4-5 seconds the overlay appears again (and again and again). The transaction remains in "in progress" status.
My question now, since everything worked fine with StoreKit? What could be the problem. I need to submit a new appVersion (which I am working on) with my first new in-app purchase. Could it be that the payment process is not working because the IAP is still in "under review" or "submitted for review"? Where could be a difference that StoreKit IAP works just fine, but sandbox does not work.
Thanks in advance for your help.
I'm working on an application that will include auto-renewable subscription functionality. I'm trying to restrict a few products within a group by using the availability option, for example, only for the US.
However, for a sandbox account with the Germany region, these restricted products are also available to fetch and purchase using StoreKit after providing their IDs through SKProductsRequest.
I tried another scenario where I fetched only products from this group that are available for the sandbox account region in my app. However, after purchasing one of them, in iOS settings on the sandbox account management page, I see a subscription group with all subscriptions, including restricted ones. This means the user is able to purchase them from this page.
Could you please advise on an efficient way to restrict my subscriptions per region? Or maybe this is only a sandbox issue because, according to the documentation, these subscriptions should not be available for restricted regions. Thanks in advance!
I have apple web payment integrated on website, and it work fine when i test it using real cards. I wanted to test it using apple TEST cards, so i invited SANDBOX test user from here https://appstoreconnect.apple.com/access/users/sandbox and logged in to test device using this test id. but it fails to start a merchant session.
System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a send. ---> System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.TlsStream.EndWrite(IAsyncResult asyncResult)
at System.Net.ConnectStream.WriteHeadersCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, TransportContext& context)
at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Net.Http.HttpClient.d__58.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
at Gateway.MobileWallet.Domain.ApplePay.Clients.RequestPaymentSession.ApplePayPaymentSessionClient.d__3.MoveNext() in