Hi everyone,
I'm encountering an issue while testing a subscription purchase with a promotional offer using StoreKit in the Xcode debug environment. I’ve created a subscription in the StoreKit configuration file and added a promotional offer. However, when I attempt to make a purchase with the promotional offer, the process fails, and I receive an alert with the message:
"Unable to purchase"
"Contact the developer for more information."
Here’s the error that is printed in the Xcode logs:
Purchase did not return a transaction: Error Domain=ASDErrorDomain Code=3903 "Received failure in response from Xcode" UserInfo={NSDebugDescription=Received failure in response from Xcode, NSUnderlyingError=0x303346b50 {Error Domain=AMSErrorDomain Code=305 "Server Error" UserInfo={NSLocalizedDescription=Server Error, AMSServerErrorCode=3903, AMSServerPayload={
"cancel-purchase-batch" = 1;
dialog = {
defaultButton = ok;
explanation = "Contact the developer for more information.\n\n[Environment: Xcode]";
initialCheckboxValue = 1;
"m-allowed" = 0;
message = "Unable to Purchase";
okButtonString = OK;
};
dsid = 17322632127;
failureType = 3903;
jingleAction = inAppBuy;
jingleDocType = inAppSuccess;
pings = (
);
}, AMSURL=http://localhost:49300/WebObjects/MZBuy.woa/wa/inAppBuy, AMSStatusCode=200, NSLocalizedFailureReason=The server encountered an error}}}
Has anyone encountered a similar issue, or does anyone have insights into what might be causing this? I’m using StoreKit 2 methods for handling subscriptions, and this error only occurs when attempting to apply the promotional offer. Any help or suggestions would be greatly appreciated!
Thanks in advance!
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
72 Posts
Sort by:
Post
Replies
Boosts
Views
Activity
Hello everyone,
I am trying to implementing the In-App Purchase in one of my iOS App and I am getting the following error when I test it into iPhone, but when I test the same app into the iPad I didn't get any error and it works properly.
Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x282da9860 {Error Domain=ASDErrorDomain Code=500 "(null)" UserInfo={NSUnderlyingError=0x282d02940 {Error Domain=AMSErrorDomain Code=203 "Bag Load Failed" UserInfo={NSLocalizedFailureReason=Unable to retrieve p2-product-offers-batch-limit because we failed to load the bag., NSLocalizedDescription=Bag Load Failed, NSUnderlyingError=0x282d02af0 {Error Domain=AMSErrorDomain Code=203 "Bag Load Failed" UserInfo=0x2836ca380 (not displayed)}}}}}}
When verifying the receipt to 'https://sandbox.itunes.apple.com/verifyReceipt', the status code 21199 is always returned. Even if the verification is performed again after an interval, the status code 21199 is still returned. How can this problem be solved?
I'm developing an iOS app that supports in-app purchases and I'm using StoreKit2 for handling transactions. While purchase, promotion, and restore purchase functionalities are working fine, I'm facing an issue with offer code redemption.
When I present the offer code redemption sheet using:
``SKPaymentQueue.default().presentCodeRedemptionSheet()``
I am able to redeem the offer code in App Store sheet. It's showing success. But after offer code redeem SKPaymentTransactionObserver does not seem to receive any updates or notifications. Specifically, the paymentQueue(_:updatedTransactions:) method is not being called.
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])
import StoreKit
`class YourClass: NSObject, SKPaymentTransactionObserver {
override init() {
super.init()
SKPaymentQueue.default().add(self)
}
deinit {
SKPaymentQueue.default().remove(self)
}
public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchased:
print("Transaction Purchased")
SKPaymentQueue.default().finishTransaction(transaction)
case .failed:
print("Transaction Failed")
SKPaymentQueue.default().finishTransaction(transaction)
case .restored:
print("Transaction Restored")
SKPaymentQueue.default().finishTransaction(transaction)
case .deferred:
print("Transaction Deferred")
case .purchasing:
print("Transaction Purchasing")
@unknown default:
print("Unknown Transaction State")
}
}
}
}
`
So I am not able to update the UI and also not able to send the details to server.
Steps I’ve Taken:
Verified that the observer is added to the SKPaymentQueue in the initializer and removed in deinit.
Tested on a real device, not just the simulator.
Checked that the offer code is valid and properly set up in App Store Connect.
Verified that the latest version of Xcode is being used.
Questions:
Is there a known issue with offer code redemption in StoreKit2 that might cause the observer not to receive notifications?
Are there additional steps or configurations required to ensure that the transaction observer is notified about offer code redemptions?
Are there any common pitfalls or troubleshooting tips for dealing with this issue?
Any assistance or insights would be greatly appreciated!
Hi! I am creating a plugin that implements the In App Purchases and Subscriptions. I have done everything already and the only error I am debugging right now is with the validation of receipts.
I always get status 21002 even the format is base64 already. I prefer to use the verifyReceipt as it is intended for my plugin.
I have tried everything but still the response I get is status 21002 which is I know the data in receipt-data is malformed or missing. What can I do about this? Thank you so much in advance!
This is my code too: (Objective-C)
NSString *receiptString = [receiptData base64EncodedStringWithOptions:2];
if (!receiptString) {
[self post_receipt_validation_result:@{@"status": @"error", @"message": @"Failed to encode receipt data"}];
return;
}
NSLog(@"Requesting to Sandbox: %@", receiptString);
NSURL *storeURL = [NSURL URLWithString:@"https://api.storekit-sandbox.itunes.apple.com/verifyReceipt"];
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
NSDictionary *requestContents = @{@"receipt-data": receiptString};
NSError *jsonError;
NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:&jsonError];
if (jsonError) {
[self post_receipt_validation_result:@{@"status": @"error", @"message": jsonError.localizedDescription}];
return;
}
NSLog(@"Request Data: %@", requestData);
[storeRequest setHTTPBody:requestData];
NSLog(@"Store Request: %@", storeRequest);
I'm developing a multi-platform e-learning app in React Native where teachers create courses by uploading various types of content, such as videos, PDFs, Zoom meeting links, or simply by chatting with students. Students can purchase these courses via the app. However, our app has been repeatedly rejected by the App Store because digital content for mobile must be purchased through the App Store.
This presents a challenge since the content our teachers upload is dynamic and varied, making it impractical to predefine all possible subscription packages. From my understanding, subscriptions or products need to be created in our App Store account first, and only then can they be fetched in our app.
Is there a way for Apple to support dynamic subscription packages that can be uploaded through the app, Any guidance on how to manage this within the App Store guidelines would be greatly appreciated.
This error no solution is available.
I was trying to write unit test of ask to buy for SKDemo app.
Even if I set SKTestSession.askToBuyEnabled = true, I got transaction state as .purchased after I call SKTestSession.buyProduct(identifier:).
import StoreKitTest
import XCTest
final class SKDemoTests: XCTestCase {
private var session: SKTestSession!
override func setUp() async throws {
session = try .init(SKTestSession(configurationFileNamed: "Products"))
session.disableDialogs = true
session.resetToDefaultState()
session.clearTransactions()
}
func test() async throws {
session.askToBuyEnabled = true
try await session.buyProduct(identifier: "consumable.fuel.octane89")
XCTAssertEqual(session.allTransactions().first!.state, .deferred) // Gets error here. The actual state I get is .purchased
}
}
I was using Xcode 15.0.1 (15A507), Simulator iPhone 15 Pro iOS 17.0.1 (21A342)
I couldn't find the problem so I'm happy to hear any solutions.
Plenty of info on test IAPs in xCode. I need to test whether the user has previously purchased the product in order to adjust my business model from a paid app to an in-app-purchased subscription.
I have implemented the code from "What's New in StoreKit" found at https://developer.apple.com/wwdc22/10007?time=527 and this works. but I don't know how to create a mock purchase that I can use to validate a previous purchase. This means I have no way of testing if the code actually works with a previous purchase in place.
My question is specifically: How do I create a mock/test "purchased product" that I can use in testing this functionality?
For clarity, I have successfully test IAP IAW: https://developer.apple.com/documentation/xcode/setting-up-storekit-testing-in-xcode/
Thanks
This is a copy of a reply to this post.
https://developer.apple.com/forums/thread/722222?page=1
I'm posting as new in the hope someone might have more up-to-date information, as I'm pulling out what little hair I have left.
I'm using Storekit 2, testing in Xcode with a local Storekit config file. I have created a very minimal system to investigate this issue. I have a SwiftUI-based window using SubscriptionStoreView, and my app set up with the usual listener. I have four types of auto renewing subscription, configured in the local Storekit config file.
With my app running, I subscribe to the lowest-level subscription I offer, via the SubscriptionStoreView. Notification of the inital purchase arrives, but subsequent auto-renewals do not trigger any action in my listener for Transaction.updates. They arrive as expected in the Transaction Manager. Radio silence in my listener.
If I upgrade one subscription (via my SubscriptionStoreView) I see this reflected in the UI immediately, and also in the Transaction Manager, but the update that arrives in Transaction.updates refers to the old subscription, and has the isUpgraded flag set to false.
Also, can anyone remind me what the grey warning triangle next to entries in the Transaction Manager means. I'm assuming it means unfinished, as that's what the sidebar indicates.
Can the testing system really be this broken, or am I wildly off the mark? Unless I'm doing something fundamentally wrong this all seems extremely flakey, but happy to be proved wrong.
I find this all rather unsettling if I can't test reliably, and am concerned that I my app may end up in this situation if I use storekit 2:
https://stackoverflow.com/questions/73530849/storekit-renewal-transactions-missing-in-transaction-all-or-transaction-updates
Not Found In-App Purchase?????
I'm experiencing an issue where in-app purchases work correctly in both profile and debug modes. However, when I upload the app to TestFlight, the in-app purchases are not functioning as expected. How can I resolve this issue?
How to determine if a user is eligible for an introductory offer or promotional offer or neither when they just view the subscription page in APP without submitting a subscription? We are using apple server notifications V2.
My goal is to display different offer pages to different users on the subscription page according to their eligibility.
But currently, we can only recognize the user's eligibility after they have submitted a subscription order.
Hey everyone!
I’m currently working on a new app called Kept – a simple and elegant journaling app designed to help you capture your thoughts and ideas effortlessly.
However, I’ve hit a bit of a snag with the TestFlight distribution of the app. When I test the in-app purchases locally, everything works perfectly. But once the app is pushed to TestFlight, users only see "Loading products..." indefinitely and are unable to make purchases.
Here are the details:
The app works locally with sandbox accounts.
Product identifiers and configurations have been double-checked.
All in-app purchases are correctly set up and approved in App Store Connect.
Using correct sandbox account settings on the device.
I'm offering a free trial period for each of four auto-renewable subscriptions.
Does anyone know the best way to detect whether a customer is still in the trial period, and to calculate the remaining trial days?
I'm using Storekit 2.
I've seen vague answers about using the Transaction purchaseDate and expiry date, but the documentation is incredibly vage as to what those values actually represent when it comes to a free trial period. What does purchase Date actually mean when you're in a free trial?
Any help greatly appreciated.
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!
Trying to manage my Sandbox Account. Using the web AppStoreConnect interface, I keep getting and error message "Something went wrong try again later". I have tried during multiple days without success.
Any solution to this as it is impossible to do some app testing?
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
I am running a very simple UI test on Xcode 14 beta 6 that sets up a StoreKit testing session and then attempts to bring up a purchase dialog. Unfortunately, PassbookUIService is crashing and thereby causing the purchase to be canceled. Here is the crash report:
PassbookUIService-2022-08-30-094331.ips.txt
For context, the UI test is very simple:
func testExample() throws {
_ = self.expectation(description: "Never fulfilled")
let session = try SKTestSession(configurationFileNamed: "CatsAndLlamas.storekit")
session.clearTransactions()
session.resetToDefaultState()
session.disableDialogs = false
let app = XCUIApplication()
app.launch()
let tablesQuery = app.tables
tablesQuery.staticTexts["Buy Product"].tap()
tablesQuery.cells.containing(.staticText, identifier:"Silver Llama").staticTexts["Subscribe"].tap()
waitForExpectations(timeout: 30)
}
On an iOS 15.5 simulator device, the UI test works as expected.
However, on an iOS 16 simulator device, the UI test behaves as if the purchase request were canceled before the dialog is even displayed.
This is when PassbookUIService crashes. I believe this crash is causing StoreKit (or StoreKitTest) to consider the purchase canceled.
(I have screenshots of the behavior but I’ve not been able to successfully include them in this post for some reason.)
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?