Hello all,
I am new to implementing payments in an app, and thus completely at sea here.
I have created a small app that I have set a one-time (non-consumable) payment for a premium version.
In the Xcode simulator (on all platforms) and on any physical test devices I have tried, the payment works as expected. I have a sandbox account and various test accounts, both dummy and actual real accounts (friends and family). Everywhere everything works perfectly fine.
Yet, when I submit for review I get a rejection with this contents:
We found that your in-app purchase products exhibited one or more bugs which create a poor user experience. Specifically, the app still failed to load the in-app purchase. Please review the details and resources below and complete the next steps.
Review device details:
Device type: iPad Air (5th generation)
OS version: iPadOS 18.6
Next Steps
When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code "Sandbox receipt used in production," you should validate against the test environment instead.
Additionally, note that the Account Holder must accept the Paid Apps Agreement in the Business section of App Store Connect before paid in-app purchases will function.
Resources
Learn how to set up and test in-app purchase products in >the sandbox environment.
Learn more about validating receipts with the App Store.
Steps I have done:
I have signed all agreements and all bank account details are in order. Everything in the In-app-purchases section of the AppStoreConnect in an Active state.
I have triple checked that the configuration of the in-app purchases is correct (product IDs, amounts, etc.)
I have created test accounts and tested in sandbox
What I don't understand from the reviewer's response is what receipts validation are they talking about? I have no payment servers (the whole concept of using Apple's in-app-purchases service is to not have to deal with my own payment implementation). The StoreKit documentation specifically reads:
For each transaction that represents a current purchase, your app delivers the purchased products. To validate purchases, you can verify transactions on your server, or rely on StoreKit’s verification.
So now I am confused. The reviewer's response is so vague, and so completely deprived of details that I have no idea what to do...
Does the problem concern the product purchase trigger and the that in production environment it does not trigger?
Is it that I haven't implemented a receipt validation? Do I need to? Although the documentation mentions that it can be done by StoreKit, I couldn't find anything concerning how to do it :(
Can someone give me a hand please?
Cheers,
Alex
StoreKit
RSS for tagSupport in-app purchases and interactions with the App Store using StoreKit.
Posts under StoreKit tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi, I just having an issue with Revenue Cat paywall and react native purchases library when app is downloaded from TestFlight.
All my subscriptions are in ready for submit state and most likely should be available in sandbox TestFlight but in fact revenue cat sends error about no products are available in App Store Connect
(Revenue Cat configured properly, and i event imported froducts from App Store)
Also, locally, with StoreKit product sync everything working properly
Tried different accounts like sandbox and live - still the same error
Can anyone help with this?
Topic:
App Store Distribution & Marketing
SubTopic:
TestFlight
Tags:
Subscriptions
StoreKit
App Store Connect
Hello, is it allowed to include the action=write-review URL parameter in customer support emails to direct users to the App Store review page?
Example: https://apps.apple.com/app/id[APP_ID]?action=write-review
I want to make it easy for customers to leave feedback after positive support interactions, but only if it's compliant.
I have added an in-app purchase function into my app, and have enabled in-app purchase profile in developer portal(it's on by default and is marked gray in developer portal, I don't know if that's how it supposed to look like). I have issued the agreements and tried signing the app both manually and automatically, but neither of that worked. App can be built successfully in simulator but does not show the simulation window, but cannot build on real device or archive.
Errors: Missing com.apple.developer.in-app-purchase,
com.apple.developer.in-app-purchase.non-consumable, and com.apple.developer.in-app-purchase.subscription entitlements.
Automatic signing failed
Xcode failed to provision this target.
Topic:
Code Signing
SubTopic:
Certificates, Identifiers & Profiles
Tags:
StoreKit
Entitlements
Provisioning Profiles
Signing Certificates
revenuecat is asking for the in app subscriptions to be approved first in order for the pay wall to display and function properly, but apple support keeps flagging them as "developer action needed" and complaining that they can't access in app subscriptions. what do I do?
I have added an in-app purchase function into my app, and have enabled in-app purchase profile in developer portal(it's on by default and is marked gray in developer portal, I don't know if that's how it supposed to look like). I have issued the agreements and tried signing the app both manually and automatically, but neither of that worked. App can be built successfully in simulator but does not show the simulation window, but cannot build on real device or archive.
Errors: Missing com.apple.developer.in-app-purchase,
com.apple.developer.in-app-purchase.non-consumable, and com.apple.developer.in-app-purchase.subscription entitlements.
Automatic signing failed
Xcode failed to provision this target.
Topic:
Developer Tools & Services
SubTopic:
Xcode
Tags:
StoreKit
App Store Connect
Provisioning Profiles
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!
In SwiftUI I am using the manageSubscriptionsSheet modifier to open the iOS subscription screen. When this is presented it immediately flashes a white view and then animated the subscription screen up from the bottom, it looks pretty bad.
The view I am calling manageSubscriptionsSheet on is presented in a sheet, so maybe trying to present the subscriptions view as well is causing the visual glitch. Any way to not have this white flashing view when opening the subscription screen?
Starting around October 12, 2025 at 19:51 UTC, we're seeing intermittent failures when verifying StoreKit transaction JWTs. The issue appears to be related to certificate expiration in the x5c chain in the JWT tokens provided by Apple.
What We're Seeing
Some JWTs are being signed with different certificates. Some work, some fail certificate validation.
Old Certificate (Expired - causing failures):
Subject: Prod ECC Mac App Store and iTunes Store Receipt Signing
Issuer: Apple Worldwide Developer Relations Certification Authority (G6)
Serial: 166451396673336810269824643773700992094
Valid From: 2023-09-12 19:51:53 UTC
Valid To: 2025-10-11 19:51:52 UTC ❌ EXPIRED
New Certificate (Valid - working):
Subject: Prod ECC Mac App Store and iTunes Store Receipt Signing
Issuer: Apple Worldwide Developer Relations Certification Authority (G6)
Serial: 95385247725814954943813376527885434295
Valid From: 2025-09-19 19:44:51 UTC
Valid To: 2027-10-13 17:47:23 UTC ✓ VALID
Current Status
Most JWTs use the new valid certificate. Some JWTs still use the expired certificate. This appears inconsistent/random. I don't know if it's an issue with some of Apple's servers, or an issue with StoreKit on-device cache, but seems to me like a bug on Apple's side either way.
Are we missing something? Is this a known issue?
Any guidance or timeline from Apple would be greatly appreciated, as this is blocking legitimate paying users.
After creating a new weekly subscription option, I get inconsistent results for subscriptionPeriod. In local testing with a synced or a un-synced StoreKit file I am getting unit == .week (as expected) whereas in TestFlight I am getting unit == .day. This makes unit.localizedDescriptionsomewhat unusable in the paywall.
Am I missing something? Or is this bug or a limitation of StoreKit and/or TestFlight and/or newly created subscription options?
Affected code (in a custom SubscriptionStoreControlStyle):
private func priceDisplay(for pickerOption: Configuration.PickerOption) -> String {
var result = ""
if pickerOption.introductoryOffer != nil {
result += NSLocalizedString("then", comment: "") + " "
}
result += pickerOption.displayPrice
if let unit = pickerOption.subscriptionPeriod?.unit {
result += " / " + unit.localizedDescription
}
return result
}
private func percentageSaved(for pickerOption: Configuration.PickerOption, allOptions: [Product]) -> Int? {
guard let subscriptionPeriod = pickerOption.subscriptionPeriod, subscriptionPeriod != .weekly else {
return nil
}
let weeklyOption = allOptions.first { otherOption in
otherOption.subscription?.subscriptionPeriod == .weekly
}
guard let weeklyOption, weeklyOption.price > 0 else {
return nil
}
let percentageSaved = 100 - (pickerOption.price / (weeklyOption.price * 52)) * 100
return Int((percentageSaved as NSNumber).doubleValue)
}
In-App Subscriptions Not Fetching in Sandbox or Production (expo-iap / React Native / Bare Workflow)
Hi everyone,
I’m encountering an issue with my in-app subscriptions setup.
When I test using the StoreKit configuration file in Xcode, everything works correctly — the subscriptions are fetched and I can simulate purchases without any issues.
However, when I switch to the Sandbox or Production environment, my app fails to fetch the available products from Apple’s servers. The call to fetchProducts (from the expo-iap library) returns an empty array.
Here’s some context about my setup:
Framework: React Native (Expo Bare Workflow)
Library: expo-iap
Products: Auto-renewable subscriptions
StoreKit Configuration: Synced with App Store Connect
Status: Subscription Plans are approved in App Store Connect
I’ve verified the following:
The product identifiers in code match exactly with those in App Store Connect.
The app is signed with the correct bundle ID.
I’m testing with a Sandbox account (logged in via Settings -> Developer -> Sandbox Tester Account).
Despite this, the response from Apple’s servers still contains an empty array.
Has anyone experienced something similar with expo-iap or in general when moving from StoreKit configuration to Sandbox/Production? Any suggestions on what else I could check or common pitfalls I might be missing?
Thanks in advance!
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit
App Store Connect
In-App Purchase
Problem Description:
1、I have two sandbox accounts from different countries. Account A is from Mainland China (CHN), and Account B is from the United States (USA). When I switch the sandbox account from Account A (CHN) to Account B (USA) in the system settings and restart the app, the value of SKPaymentQueue.defaultQueue.storefront.countryCode always returns "CHN" instead of the expected "USA".
2、This issue only occurs on iOS 18.2 and above.
3、On the same device running iOS 17.5.1, the behavior is correct. However, after upgrading the system to iOS 18.3.2, the error occurs.
4、In the sandbox environment, although SKStorefront.countryCode returns the wrong value, the currency type for Apple's in-app purchase is correct when initiating the payment.
5、The issue only exists in the sandbox environment and does not occur in the App Store-downloaded package.
Demo Code:
- (IBAction)clickButton:(id)sender
{
NSString *appStoreCountryCode3 = SKPaymentQueue.defaultQueue.storefront.countryCode;
NSLog(@"%@",appStoreCountryCode3);
}
Demo Testing Steps and Results:
1、Sandbox Account A (China) will print "CHN".
2、Go to Settings - Developer - (at the bottom) SANDBOX APPLE ACCOUNT, and switch to another sandbox account B (USA).
3、Restart the Demo App.
4、Print results:
iOS 17.5.1: "USA" ✅ → Upgrade the system of the same device to iOS 18.3.2 → "CHN" ❌
iOS 18.2.1: "CHN" ❌
iOS 18.3.1: "CHN" ❌
iOS 18.3.2: "CHN" ❌
Possible Clues:
Starting with iOS 18.2, Apple changed the entry point for setting up sandbox accounts, which introduced this bug. It seems that when users switch sandbox accounts on iOS 18.2, Apple engineers forgot to notify the SKStorefront class to update the countryCode value.
Before iOS 18.2: Settings - App Store - Sandbox Account
iOS 18.2 and later: Settings - Developer - (at the bottom) Sandbox Account
Although it doesn't affect the App Store package, it does impact our development and testing process. We hope this issue can be fixed in future versions. Thank you!
Both the legacy StoreKit API and the new StoreKit 2 API return the incorrect storefront countryCode. My actual Apple ID region is Germany, and my Sandbox test user is set to France, yet the SDK consistently returns USA.
Expected Results:
The returned storefront countryCode should reflect the correct region - sandbox user region if signed in and real user region if not signed in with sandbox).
Actual Results:
Returned country code is USA with both
SKPaymentQueue.default().storefront?.countryCode
and
await Storefront.current?.countryCode.
Signing out/in, device reboot and even reset do not help, I'm stuck with USA storefront.
I am currently developing a feature to support global privacy compliance, which relies on accurately obtaining the user’s App Store country/region. Based on this country/region information, out App dynamically display privacy policies that comply with local regulations.
To retrieve this information, I use the relevant StoreKit APIs.
API usage examples:
Objective-C:
NSString *countryCode = [SKPaymentQueue defaultQueue].storefront.countryCode;
Swift
let storefront = await Storefront.current
let code = storefront?.countryCode
However, during sandbox account testing on iOS 18.0 and above, I noticed that the returned country code does not match the actual country/region configured in the sandbox Apple ID.
This issue does not occur on systems below iOS 18.0, where the country code returned by the API matches the account setting.
Since this discrepancy can directly affect the accuracy of our compliance logic, I would appreciate your clarification on the following points:
Is this a known change in behavior for iOS 18?
In production environments, does the country code returned by the above APIs accurately reflect the App Store region of the user’s signed-in Apple ID?
Is there a recommended approach to reliably obtain the user’s App Store account country/region?
I've been struggling to work with the Storekit framework and specifically to find the current Storefront used by the user of the app.
Context : My app needs to behave differently depending on the country of the user.
For me relying on Locale.current.region?.identifier does not seem very reliable, the user can change it really easily.
I'm trying to use the Storekit framework like so :
if let storefront = await StoreKit.Storefront.current{
return storefront.countryCode
}
As per Apple's Storekit documentation :
Use current to determine a customer's current storefront region and offer in-app products suitable for that region. You maintain your own list of product identifiers and the storefronts in which you make them available.
But I just can't find out what I need to change in my current configuration to get another country. The code keeps returning my original storefront (which is France)
I've tried login in with a sandbox user defined on another country. Changed all settings on my device to another country. Changed my Apple's account region as described here. Also tried to logout from everything.
The only thing that works is setting a local .storekit file as described here and changing the default storefront.
Is Xcode overriding the default storefront when building on debug or TestFlight? does anyone know how can I test different storefronts with sandbox users without the local storekit file ?
Thank you in advance.
Our application is currently under review, and we are still facing issues because we receive a 401 Unauthorized response from the App Store Connect API when using the production environment.
Our app integrates with Chargebee for subscription management, and in production, Chargebee is unable to authenticate with the App Store Server API. This results in a 401 Unauthorized error, preventing the user’s subscription from being synced correctly into our system. Interestingly, the same configuration works in the sandbox environment, but fails in production.
We’ve tried authenticating using JWTs generated from multiple keys (including App Store Connect API / Team Keys with both Admin and App Manager access, and also In-App Purchase keys), all with the same result — sandbox access works, production does not.
Here is our example code for testing with JWT token:
const jwt = require('jsonwebtoken');
const fs = require('fs');
const https = require('https');
const config = {
keyId: '<key_id>',
issuerId: 'issuer_id',
bundleId: 'bundle_id',
privateKey: fs.readFileSync('path_to_key')
};
const { keyId, issuerId, bundleId, privateKey } = config;
const now = Math.floor(Date.now() / 1000);
const jwtToken = jwt.sign(
{
iss: issuerId,
iat: now,
exp: now + 60 * 10, // 10 minutes is fine for test
aud: 'appstoreconnect-v1',
bid: bundleId
},
privateKey,
{
algorithm: 'ES256',
header: {
alg: 'ES256',
kid: keyId,
typ: 'JWT'
}
}
);
console.log('Generated JWT:\n', jwtToken);
// prod
const originalTransactionId = '<prod_transaction_id>';
const hostname = 'api.storekit.itunes.apple.com';
// sandbox
// const originalTransactionId = '<sandbox_transaction_id>';
// const hostname = 'api.storekit-sandbox.itunes.apple.com'
const options = {
hostname,
port: 443,
path: `/inApps/v1/history/${originalTransactionId}`,
method: 'GET',
headers: {
Authorization: `Bearer ${jwtToken}`,
'Content-Type': 'application/json',
},
};
const callAppStoreConnectApi = async () => {
const req = https.request(options, (res) => {
console.log(`\nStatus Code: ${res.statusCode}`);
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Response Body:\n', data || '[Empty]');
});
});
req.on('error', (e) => {
console.error('Request Error:', e);
});
req.end();
};
callAppStoreConnectApi();
With this code, we were able to authenticate successfully in the sandbox environment, but not in production.
I read in this discussion: https://developer.apple.com/forums/thread/711801 that the issue was resolved once the app was published to the App Store, but I haven’t found any official documentation confirming this.
Does anyone know what the issue could be?
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
StoreKit
App Store Connect
App Store Connect API
The use case that I want to implement is as follows: user A has the app, user B doesn't have the app yet. User A wants to referral user B to get points. User B scans the QR code present in user A's app. User B gets redirected to the App Store and when downloads the app, the code will be automatically present in the sign up request (so the referral code will be cashed during first launch of the app).
In Android it was implemented using Google Play Install Referrer. Based on my research, in Apple apparently there isn't an alternative, can you please confirm me this.
Topic:
App Store Distribution & Marketing
SubTopic:
General
Tags:
Developer Tools
App Store
StoreKit
I'm designing an app, and the purchase function was initially broken because the Distribute Certificate expired. After reinstalling it, the app worked again, but on iPhone 15 Pro (iOS ver:18.6), it still couldn't read the purchased items in the App Store.
I test the same app on iPhone 6S Plus( iOS ver: 15.8.4) , the purchase function work fine.
Looking to update one of my apps that uses SKStoreReviewController +requestReview (deprecated) to
AppStore.requestReview(in:)
umm...I have a few of questions...
Why is an NSViewController parameter required? It's really not so uncommon for an AppKit app to just use NSWindowController with a window that does not use NSViewController...
It should be possible to present the review request in a standalone alert (attached to a window is preferred IMO but it still should be possible to ask in separate window).
3)...why Swift..(err nevermind)
Ideally:
AppStore requestReview should take a NSWindow parameter but that parameter should be optional. If nil the request should be presented in a standalone window (like an alert). If non nil..present as a sheet on the window.
Why a view controller? Maybe I'm missing something.
Hi, I’m running into a persistent error while implementing StoreKit 2 renewable subscriptions in my SwiftUI app.
Context
I have a two-screen flow:
Screen 1: user selects a subscription plan (monthly / yearly).
Screen 2: user fills out personal information and taps Subscribe that triggers the purchase function.
On first launch or the first couple of purchases (on both Storekit's local and Sandbox testing), everything works fine. The App Store popup appears, the purchase goes through, and I get the transaction result.
But after a few runs (3rd or 4th purchase attempt onward), my app crashes the moment the App Store purchase popup appears.
Error Logs
When the crash happens, the console shows:
`unable to close due to unfinalized statements or unfinished backups
BUG IN CLIENT OF libsqlite3.dylib: database integrity compromised by API violation: vnode unlinked while in use: /private/var/mobile/Containers/Data/Application/D8D97A11-DF06-4EF2-AC55-138C4739A167/Library/d6d2e85a60f0480c4c17834eeb827a14_MPDB.sqlite
invalidated open fd: 21 (0x11)
BUG IN CLIENT OF libsqlite3.dylib: database integrity compromised by API violation: vnode unlinked while in use: ...`
Observations
The error only shows after some time maybe due to multiple transactions and switching between plans for the same user, not on the very first purchases.
If I land on the purchase screen immediately after app launch, the purchase works. But if I wait a while before navigating to the purchase screen, the popup causes the app to crash.
I’m not using Core Data or my own SQLite database at all - so I assume this DB (MPDB.sqlite) is StoreKit’s internal persistence.
Things I’ve tried so far
Cleaning StoreKit caches:
rm -rf ~/Library/Developer/CoreSimulator/Devices/*/data/Container s/Data/Application/*/Library/Caches/storekit
Rebuilding from scratch, cleaning build folder.
Switching between sandbox accounts, signing out/in again.
Added await transaction.finish() after verified purchases.
Added cleanup for unfinished transactions at app launch:
for await result in Transaction.unfinished {
if case .verified(let transaction) = result {
await transaction.finish()
}
}
Tried both StoreKit Configuration file and sandbox environment but issue persists in both.
Questions
Is this error StoreKit-specific (internal SQLite DB corruption) or something wrong in my implementation?
Why would it only appear after a few runs / with a delay before navigating to the purchase screen?
Am I missing something else in handling StoreKit 2 transactions?
Screenshots of the errors are attached for context.
Any insights would be really appreciated...I’m stuck because I can’t tell if this is an Apple bug with StoreKit 2 or something I’ve overlooked in my code.
Specs:
Xcode 16.4
Build version 16F6
iOS version: 18.6.2
Topic:
App & System Services
SubTopic:
Tap to Pay on iPhone
Tags:
Subscriptions
StoreKit
Xcode
In-App Purchase