Hello!
My application written with CPP and using StoreKit2 functionality based on bridging CPP-ObjectiveCPP-Swift. The question is in correct project properties for adding this library to application.
Configuring library by attaching project.entitlement file (within in-app purchase key) to the library project. Question is how to add library to the application correctly:
Is there requirements to write another one entitlement for Application and switch on 'in-app purchase' in application too or it's enough to add it only to the library?
Is there any examples of using StoreKit2 in libraries and attaching it to the projects?
Is there any requirements for configuring library within StoreKit2 if it's going to be reused in different applications?
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
109 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
I have a few issues. Support consultants responded to my review file by saying they wanted the image. 1- I logged in with the sandbox account I used for testing and took a screenshot of the Paywall screen. However, they said this screenshot wasn't accepted. The documentation explains how to log in to Testflight with a sandbox account and test it, but even though I tried testing on two different devices, I couldn't log in to Testflight or get the image they requested. 2- I closed my privacy policy and terms of use, and there's no problem. What else should I do? I'm stuck on the Testflight and sandbox sections. Can you help ?
Hi,I am facing the 21002 issue.Have you went through it? If you have resolved it, please dive me a hand.
Below is my code,and I Have tested in sand box environment.
NSURL receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
if (![[NSFileManager defaultManager] fileExistsAtPath:[receiptURL path]]) {
SKReceiptRefreshRequest receiptRefreshRequest = [[SKReceiptRefreshRequest alloc] initWithReceiptProperties:nil];
receiptRefreshRequest.delegate = self;
[receiptRefreshRequest start];
return;
}
NSData data = [NSData dataWithContentsOfURL:receiptURL];
/ receipt_data/
NSString *receipt_data = [data base64EncodedStringWithOptions:0];
After I test the purchase procedure, use the above receipt-data to verify on the server https://sandbox.itunes.apple.com/verifyReceipt,which always response 21002.I have no idea to deal with it.Thanks.
Hello everyone,
I’m currently working on an iOS app built with Capacitor(5.0.6) with Cordova and vanilla JS. At the moment, my app uses Stripe to handle payments — on iOS I open a Safari View Controller so users can pay with Apple Pay or their credit card.
However, I need to migrate to Apple’s In-App Purchase system to comply with App Store policies. I would really appreciate some guidance or a step-by-step outline on the following:
The exact process to enable and configure In-App Purchases in Xcode and App Store Connect for a Capacitor-based app.
How to properly set up local testing with StoreKit (or any other recommended approach) before submitting to review.
Best practices for integrating In-App Purchases when using RevenueCat, since I’m considering it to simplify the implementation.
Any pitfalls or gotchas that I should be aware of during the first submission (for example, the requirement to include the first IAP with a new app version).
My goal is to fully comply with Apple’s policies and provide a smooth user experience for iOS users. I’m open to suggestions on frameworks, workflows, or tools that could make this easier.
Thank you in advance for any help or examples you can share!
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
StoreKit Test
App Store Connect
In-App Purchase
Hello!
We are tryign to test refund notifications and we've implemented a debug button trigger the refund of a purchase done with a sandbox account. The problem is that the refund view displays a Cannot Connect message and nothing happens. No error messages appear in the console. Anything we are doing wrong?
<SKPaymentQueue: 0x283da58d0>: Payment completed with error: Error Domain=ASDErrorDomain Code=500 "(null)" UserInfo={client-environment-type=Sandbox, storefront-country-code=IND, NSUnderlyingError=0x28310f6c0 {Error Domain=AMSErrorDomain Code=305 "Purchase Failed" UserInfo={NSLocalizedDescription=Purchase Failed, AMSURL=https://sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy?guid=f7d7d15046ee6db6d61ef721b924773fa7d9347d, AMSStatusCode=200, AMSServerPayload={
"cancel-purchase-batch" = 1;
customerMessage = "Unable to process your request.";
dialog = {
defaultButton = ok;
explanation = "Please try again later.";
initialCheckboxValue = 1;
isFree = 1;
"m-allowed" = 0;
message = "Unable to process your request.";
okButtonString = OK;
};
failureType = "";
"m-allowed" = 0;
metrics = {
actionUrl = "sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy";
asnState = 0;
dialogId = "MZCommerce.SystemError";
I am getting this error code who all are added via beta test link and internal tester who all are added after the beta link has been created
but IAP working one who all are before in internal testers as beofre the link has been created
Hey everyone,
I'm currently preparing an older iOS app for App Store release that includes a non-consumable In‑App Purchase using StoreKit 2. Everything works perfectly in the StoreKitTest environment inside Xcode – the product loads, the purchase flow runs, the transaction verifies.
However, when I run the same app through TestFlight, I always get the error:
❌ Product not available - mapped to
Here’s what I’ve already checked:
✅ The product ID is correct and matches what’s in App Store Connect (case-sensitive).
✅ The IAP is created in App Store Connect and includes:
Title
Product ID
Price Tier
Screenshot for review
✅ The App Store "Paid Applications" agreement is active.
✅ The app is using the correct bundle ID.
✅ I'm using Product.products(for: [productID]) from StoreKit 2.
✅ I’ve implemented fallback and retry logic (e.g. reload after delay).
✅ All IAP logic is wrapped in @MainActor and async-safe.
As the App got Rejected on Review, the IAP is also now in the Rejected Status.
Now the IAP shows status:
🟠 "Developer Action Required"
And App Review rejected the IAP with the message:
"Your first In‑App Purchase must be submitted together with a new app version."
But if I add the App to the Test again and therefore the IAP, then the app will get Rejected again for App Completeness, IAP does not work...
What am I doing wrong here? :)
Thanks a lot in advance
Cheers,
Niklas
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
StoreKit Test
App Review
StoreKit
In-App Purchase
Hi,
I am trying to do some purchase on sandbox envirnment and facing this error from last 2 days. Any idea what is wrmong here
<SKPaymentQueue: 0x158ac1030>: Payment completed with error: Error Domain=ASDErrorDomain Code=500 "(null)" UserInfo={client-environment-type=Sandbox, storefront-country-code=IND, NSUnderlyingError=0x15ae9c0c0 {Error Domain=AMSErrorDomain Code=305 "Purchase Failed Server canceled the purchase" UserInfo={AMSFailureReason=Server canceled the purchase, AMSURL=https://sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy?guid=00008030-0004388026C2802E, AMSDescription=Purchase Failed, AMSStatusCode=200, AMSServerPayload={
"cancel-purchase-batch" = 1;
customerMessage = "Unable to process your request.";
dialog = {
defaultButton = ok;
explanation = "Please try again later.\n\n[Environment: Sandbox]";
initialCheckboxValue = 1;
isFree = 1;
"m-allowed" = 0;
message = "Unable to process your request.";
okButtonString = OK;
};
failureType = "";
"m-allowed" = 0;
metrics = {
actionUrl = "sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy";
asnState = 0;
dialogId = "MZCommerce.SystemError";
eventType = dialog;
message = "Unable to process your re";
mtEventTime = "2025-08-06 06:56:30 Etc/GMT";
mtTopic = "xp_its_main";
options = (
OK
);
};
pings = (
);
}, NSDebugDescription=Purchase Failed Server canceled the purchase}}}
Optional(Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x15a152280 {Error Domain=ASDErrorDomain Code=500 "(null)" UserInfo={NSUnderlyingError=0x15a1501e0 {Error Domain=AMSErrorDomain Code=305 "(null)"}}}})
Whether using Storefront.current?.countryCode or SKPaymentQueue.default().storefront?.countryCode, both are returning "USA" only.
(It used to return the correct country code before the update.)
In the sandbox environment, the country code is returned correctly,
but in the TestFlight environment, it always returns "USA".
There's no mention of this behavior in the beta release notes, so I'm posting it here for visibility.
Received error that does not have a corresponding StoreKit Error: Error Domain=AMSErrorDomain Code=305 "Purchase Failed Server canceled the purchase
More details:
Error Domain=AMSErrorDomain Code=305 "Purchase Failed Server canceled the purchase" UserInfo={AMSFailureReason=Server canceled the purchase, AMSURL=https://sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy?guid=00008110-000A4DC10E51401E, AMSDescription=Purchase Failed, AMSStatusCode=200, AMSServerPayload={
"cancel-purchase-batch" = 1;
customerMessage = "Unable to process your request.";
dialog = {
defaultButton = ok;
explanation = "Please try again later.\n\n[Environment: Sandbox]";
initialCheckboxValue = 1;
isFree = 1;
"m-allowed" = 0;
message = "Unable to process your request.";
okButtonString = OK;
};
failureType = "";
"m-allowed" = 0;
metrics = {
actionUrl = "sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy";
asnState = 0;
dialogId = "MZCommerce.SystemError";
eventType = dialog;
message = "Unable to process your re";
mtEventTime = "2025-07-28 12:34:22 Etc/GMT";
mtTopic = "xp_its_main";
options = (
OK
);
};
pings = (
);
}, NSDebugDescription=Purchase Failed Server canceled the purchase}
Received error that does not have a corresponding StoreKit Error: Error Domain=ASDErrorDomain Code=500 "(null)" UserInfo={client-environment-type=Sandbox, storefront-country-code=IND, NSUnderlyingError=0x1276116e0 {Error Domain=AMSErrorDomain Code=305 "Purchase Failed Server canceled the purchase" UserInfo={AMSFailureReason=Server canceled the purchase, AMSURL=https://sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy?guid=00008110-000A4DC10E51401E, AMSDescription=Purchase Failed, AMSStatusCode=200, AMSServerPayload={
"cancel-purchase-batch" = 1;
customerMessage = "Unable to process your request.";
dialog = {
defaultButton = ok;
explanation = "Please try again later.\n\n[Environment: Sandbox]";
initialCheckboxValue = 1;
isFree = 1;
"m-allowed" = 0;
message = "Unable to process your request.";
okButtonString = OK;
};
failureType = "";
"m-allowed" = 0;
metrics = {
actionUrl = "sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy";
asnState = 0;
dialogId = "MZCommerce.SystemError";
eventType = dialog;
message = "Unable to process your re";
mtEventTime = "2025-07-28 12:34:22 Etc/GMT";
mtTopic = "xp_its_main";
options = (
OK
);
};
pings = (
);
}, NSDebugDescription=Purchase Failed Server canceled the purchase}}}
Purchase did not return a transaction: Error Domain=ASDErrorDomain Code=500 "(null)" UserInfo={client-environment-type=Sandbox, storefront-country-code=IND, NSUnderlyingError=0x1276116e0 {Error Domain=AMSErrorDomain Code=305 "Purchase Failed Server canceled the purchase" UserInfo={AMSFailureReason=Server canceled the purchase, AMSURL=https://sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy?guid=00008110-000A4DC10E51401E, AMSDescription=Purchase Failed, AMSStatusCode=200, AMSServerPayload={
"cancel-purchase-batch" = 1;
customerMessage = "Unable to process your request.";
dialog = {
defaultButton = ok;
explanation = "Please try again later.\n\n[Environment: Sandbox]";
initialCheckboxValue = 1;
isFree = 1;
"m-allowed" = 0;
message = "Unable to process your request.";
okButtonString = OK;
};
failureType = "";
"m-allowed" = 0;
metrics = {
actionUrl = "sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy";
asnState = 0;
dialogId = "MZCommerce.SystemError";
eventType = dialog;
message = "Unable to process your re";
mtEventTime = "2025-07-28 12:34:22 Etc/GMT";
mtTopic = "xp_its_main";
options = (
OK
);
};
pings = (
);
}, NSDebugDescription=Purchase Failed Server canceled the purchase}}}
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit Test
StoreKit
In-App Purchase
I have created a Python app and built it with pyinstaller and codesigned everything. Now I want to Sandbox test it. In my appstore connect account i have created a subscriptions id. I read that if I am logged out from the AppStore and have codesigned my .app file with a Developer Certificate i should be able to run the app on my local mac and when i click on the "Buy" button it should connect to my app store connect setup. I have implemented StoreKit in my app and use a storekit_bridge to combine the .swift code with my python app.
However when i run the app. I get this: "25-07-24 21:01:12,557 - FEC - WARNING - StoreKit: fetchProducts returned empty result
2025-07-24 21:01:12,557 - FEC - INFO - StoreKit fetch_products returned: {"products": []}
2025-07-24 21:01:12,557 - FEC - ERROR - StoreKit: Failed to parse product info: No products returned from JSON"
And no login screen appears where I should be able to enter my Sandbox email adress and password.
Anyone here who has experience with a Python app combined with In App Purchases? Hope someone can help me out with this.
hello, i am currently trying to add a hardpaywall to my app. When I test in testflight with storekit config set to "none" in scheme. I get an error saying unable to load subscriptions.
The minimum support for the project is iOS 15.2, and the subscription function is implemented using StoreKit2.
Problem: The redemption was successful within the Appstore, but the redemption item cannot be detected through code within the app.(The subscription function has been implemented and tested)
Here is my code, I am not sure if it is due to storeKit2 (as seen elsewhere) or if there is a problem with the testing method. If there is a correct testing method for the promoCode redemption scenario, please let me know.
for await verificationResult in Transaction.currentEntitlements {
switch verificationResult {
case .verified(let transaction):
if transaction.revocationDate != nil {
print("unsubscribe:\(transaction)")
break
}
if transaction.offerType == .code,let code = transaction.offerID {
print("Have promoCode")
print("promoCode: \(code)")
let dateF = DateFormatter()
dateF.dateFormat = "yyyy.MM.dd HH.mm.ss"
if let expireDate = transaction.expirationDate {
print("endTime:\(dateF.string(from: expireDate))")
}
}
//.consumable,.nonConsumable,.autoRenewable,.nonRenewable
if transaction.productType == .autoRenewable {
print("Have subscription:\(transaction)")
let dateF = DateFormatter()
dateF.dateFormat = "yyyy.MM.dd HH.mm.ss"
if let expireDate = transaction.expirationDate {
print("endTime:\(dateF.string(from: expireDate))")
}
}else{
print("\(transaction)")
}
case .unverified(let unverifiedTransaction, let verificationError):
print("checkProduct:error")
}
}
Hello,
I am consistently receiving the error message "In-app purchases are not allowed on this device" whenever I try to make an in-app purchase on my iOS device. Despite following all the recommended solutions I could find online, the issue remains unresolved.
Here is a list of the steps I have already taken:
Checked Screen Time Settings:
I navigated to Settings > Screen Time > Content & Privacy Restrictions > iTunes & App Store Purchases.
I have confirmed that "In-App Purchases" is set to "Allow." I have also tried toggling this setting off and on again.
Signed Out & In of Apple ID:
I signed out of my Apple ID via Settings > [Your Name] > Media & Purchases, restarted the device, and then signed back in.
Restarted the Device:
I have force-restarted my device multiple times.
Updated iOS:
I have ensured my device is running the latest version of iOS (checked via Settings > General > Software Update).
Verified Payment Method:
I have confirmed that my payment method on file is valid and up-to-date.
Created a New Sandbox Account:
I also created a new Sandbox Tester account in App Store Connect and tested with it, but the result was the same.
Device Information:
Device Model: iPhone 15, iPhone 13
iOS Version: iOS 17.5, iOS 18
Even after performing all of these steps, the problem persists. Has anyone else encountered such a stubborn issue, or does anyone have a different solution I could try?
Thank you in advance for your help.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit Test
StoreKit
In-App Purchase
I implemented consumable in-app purchases in an iPhone app using ProductView().
When I tap the payment button in ProductView(), I am taken to the payment screen and once the payment is completed the next code seems to be executed, so there doesn't seem to be a problem, but if I tap the payment button in ProductView() again, the next code is executed without taking me to the payment screen.
This means that a single payment can be made multiple times.
Can someone help?
ProductView(id: "geminiOneMatch")
.productViewStyle(.compact)
.padding()
.onInAppPurchaseCompletion { product, result in
if case .success(.success(_)) = result {
// 課金が成功した場合の処理
gemini.addOneMatch(amount: 20)
popUpVM.geminiOneMatchPopUp = false
dataManageVM.generateRespons(locale: locale)
}
}
It seems that beta 3 broke StoreKit Testing when running against an iOS 26 simulator device. Specifically, when validating product IDs, the debug console displays messages like the following:
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
[492a4cfa_SK1] Could not parse product: missingValue(for: [StoreKit.ProductResponse.Key.price], expected: StoreKit.BackingValue)
In addition, the SKProductsResponse (I am using the original StoreKit API), lists all requested product IDs in invalidProductIdentifiers. The products array is empty.
StoreKit Testing behaves as expected when Xcode 26 beta 3 is run against an iOS 18.4 simulator device.
在沙盒环境下或者TestFlight 测试消费型项目会提示此项目将免费恢复
I've been implementing in app purchases into an existing C++ app. I'm using the latest Swift StoreKit since the old ObjC interface is deprecated . There is a really weird problem where the swift/C++ bridging seems to get into a loop. After the Product structure is retrieved I have the following structure which I use to bridge to C++
public struct storeData
{
public var id : String
public var displayName : String
public var description : String
public var price : String
public var purchased : Bool = false
public var level : Int = 0
}
and this is passed back to the caller as follows
public func getProducts (bridge : StoreBridge) -> [storeData]
{
bridge.products.sort { $0.price > $1.price }
var productList : [storeData] = []
for product in bridge.products
{
let data : storeData = storeData(id: product.id,
displayName: product.displayName,
description: product.description,
price: product.displayPrice,
purchased: bridge.purchasedProductIds.contains(product.id)
)
productList.append(data)
}
return productList
}
the "bridge" variable is a bridging class where the guts of the bridge resides, and contains the "products" array as a publishable variable.
In the C++ code the data is retrieved by
outProd->id = String(inProd.getId());
outProd->displayName = String(inProd.getDisplayName());
outProd->description = String(inProd.getDescription());
outProd->price = String(String(inProd.getPrice()));
outProd->purchased = inProd.getPurchased();
The "String" is actually a JUCE string but that's not part of the problem. Testing this with a local StoreKit config file works fine but when I test with a sandbox AppStore the app hangs. Very specifically it hangs somewhere in the Swift thunk when retrieving the price. When I remove the line to retrieve the price everything works. And - and this is the weird bit - when I pad the price out with some random text, it now starts working (so I have a workaround). This is, however, slightly worrying behaviour. Ideas?
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect API
Tags:
StoreKit Test
Swift
StoreKit
I just boxed up AppTransaction API. In the debug environment it appears to always return a VerificationResult that is .verified
Unlike Storekit1 calling AppTransaction.shared does not seem to cause a sandbox receipt to actually get written on the app bundle in Derived data.
I was trying to purposefully mess with the receipt in order to get AppTransaction to fail so I can test how my app behaves when errors occur but there is no receipt to mess with. I tried using the old exit(173) API and it does cause a receipt to be fetched but that seems to be completely ignored by AppTransaction, it validates even if you trash or tamper with the receipt given by exit(173).
Is there a good way to test receipt validation failure using the high level Storekit2 API?
I’m testing an auto-renewable subscription on TestFlight. Now the user can't re-purchase the same product – Apple just restores the old (expired) one, and no payment sheet appears.
How can I let the same TestFlight user re-subscribe to an expired product?
Do I have to create a new productId for every test cycle?