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.
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’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
I have several subscription plans in the App Store that I no longer wish to offer to new users.
In my app, these old subscriptions are hidden, but they remain active so existing subscribers can continue their plans and be charged as usual.
However, some new users are still able to switch to these old subscription plans through the App Store.
What is the best solution for this situation? I want to continue serving existing subscribers while preventing new users from subscribing to these legacy plans. Thank you.
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
StoreKit
App Store Connect
I am developing and testing Apple Promotional Offers and encountered issues during implementation.
Purchase Failure
When using the following API, the promotional purchase sheet is displayed, but after attempting payment, the transaction fails.
API:
public static func promotionalOffer(
offerID: String,
keyID: String,
nonce: UUID,
signature: Data,
timestamp: Int
) -> Product.PurchaseOption
Observed behavior:
Alert shows:
Unable to Purchase [Environment: Xcode]
Not Eligible for Offer
Console logs:
AMSErrorDomain Code=305
ASDErrorDomain Code=3903
Discount Not Applied
When calling this API, there are no errors, but the promotional price is not applied, and the user still sees the original price.
API:
public static func promotionalOffer(
_ offerID: String,
compactJWS: String
) -> [Product.PurchaseOption]
Questions
Does Promotional Offers support testing with .storekit files in Xcode?
Can Promotional Offers be tested with sandbox accounts using real offers configured in App Store Connect?
How should I troubleshoot and resolve the above issues?
• Could it be related to the subscription history of the sandbox account?
• Do I need to use TestFlight instead of Xcode to test certain scenarios?
• Could this be caused by signature parameters or StoreKit configuration?
One of our apps has 85% stuck in Billing Retry -- We are so confused. All the users are from the US, and have a one-week free trial.
We had 1,000 subscriptions expire from this issue.
So any help would be so appreciated.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit
App Store Connect
App Store Server API
Hello everyone,
I'm having trouble testing custom offer codes for my auto-renewable subscription in the Sandbox environment.
I am using the modern StoreKit 2 API to display the redemption sheet:
try await StoreKit.AppStore.presentOfferCodeRedeemSheet(in: windowScene)
When I enter a valid custom code that I created in App Store Connect, the system sheet immediately returns the following error:
"Cannot Redeem Code. The code entered is not valid. [environment: sandbox]"
To be clear, I am manually typing the custom code string itself into the redemption sheet's text field, not using a one-time code link or URL.
I believe my configuration is correct, and I've already spent a significant amount of time troubleshooting. Here is a list of everything I have checked and tried so far:
App Store Connect Configuration:
The Offer Code is marked as "Active".
The parent subscription product is approved and its status is "Ready for Sale".
The offer's eligibility is set correctly
The start and end dates for the offer are valid.
Despite all these steps, the error persists. At this point, I suspect this might be a temporary issue with the Sandbox environment itself, but I want to make sure I haven't missed any crucial configuration steps.
Has anyone else encountered this issue recently? Is there anything else I should be checking?
Any help would be greatly appreciated.
Thank you.
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.
Withouth authorization Bearer token:
public static JWKSet getApplePublicKeys(String token) throws Exception {
URL url = new URL("https://api.storekit.itunes.apple.com/inApps/v1/jwsPublicKeys");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
int status = conn.getResponseCode();
InputStream stream = (status >= 200 && status < 300)
? conn.getInputStream()
: conn.getErrorStream();
String body = new BufferedReader(new InputStreamReader(stream))
.lines()
.reduce("", (acc, line) -> acc + line);
System.out.println("HTTP " + status + ": " + body);
// load JWKSet from JSON string
try (InputStream in = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8))) {
return JWKSet.load(in);
}
}
With authorization Bearer token:
public static JWKSet getApplePublicKeys(String token) throws Exception {
URL url = new URL("https://api.storekit.itunes.apple.com/inApps/v1/jwsPublicKeys");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("Authorization", "Bearer ");
int status = conn.getResponseCode();
InputStream stream = (status >= 200 && status < 300)
? conn.getInputStream()
: conn.getErrorStream();
String body = new BufferedReader(new InputStreamReader(stream))
.lines()
.reduce("", (acc, line) -> acc + line);
System.out.println("HTTP " + status + ": " + body);
// load JWKSet from JSON string
try (InputStream in = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8))) {
return JWKSet.load(in);
}
}
Below is the my production and sandbox URls:
Sandbox: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/jwsPublicKeys
Production: https://api.storekit.itunes.apple.com/inApps/v1/jwsPublicKeys
Kindly help me with this. If I am doing anything wrong, please let me know. I tried using the token in the URL, and it gives me a 404. If I hit the endpoint without the token, it returns a 401. Please assist me.
Topic:
App Store Distribution & Marketing
SubTopic:
General
Tags:
StoreKit Test
StoreKit
App Store Server Notifications
Over the past two days, we've observed an unusual spike in requests from some iOS users to our server endpoint responsible for verifying App Store purchase receipts.
After sampling and analyzing the data, we found that the cause is related to the behavior of StoreKit2.Transaction.updates. Specifically, when listening for transaction updates, the system returns a large number of historical transactions — some dating back as far as one year. These callbacks are interpreted as "new" transactions, which in turn trigger repeated calls to Apple’s receipt verification servers, leading to an abnormal surge in traffic and putting pressure on our backend services.
This behavior is ongoing and is something we've never encountered in our previous experience. It appears to be outside of expected behavior, and we suspect it may be due to some kind of abnormality or unintended usage scenario.
We would appreciate guidance on the following:
Is this a known behavior or issue with StoreKit2?
Are there specific device states or conditions that could cause the system to emit historical transactions in bulk?
Are there any recommended practices for mitigating or filtering such transaction floods?
We have attached logs for reference. Any help identifying the root cause or suggestions for investigation would be greatly appreciated.
2025-07-24 12:39:58.594 +0400 listenForTransactions :{
"appTransactionId" : "704289572311513293",
"environment" : "Production",
"inAppOwnershipType" : "PURCHASED",
"originalPurchaseDate" : 1713445834000,
"originalTransactionId" : "430001791317037",
"purchaseDate" : 1713445834000,
"quantity" : 1,
"signedDate" : 1753346396278,
"storefrontId" : "143481",
}
2025-07-24 12:39:58.594 +0400 listenForTransactions :{
"appTransactionId" : "704289572311513293",
"deviceVerificationNonce" : "c4f79de2-a027-4b34-b777-6851f83f7e64",
"environment" : "Production",
"inAppOwnershipType" : "PURCHASED",
"originalPurchaseDate" : 1713445849000,
"originalTransactionId" : "430001791317270",
"purchaseDate" : 1713445849000,
"quantity" : 1,
"signedDate" : 1753346396278,
"storefrontId" : "143481",
"transactionId" : "430001791317270",
}
2025-07-24 12:39:58.594 +0400 listenForTransactions :{
"appTransactionId" : "704289572311513293",
"deviceVerificationNonce" : "02f305d7-0b2d-4d55-b427-192e61b99024",
"environment" : "Production",
"inAppOwnershipType" : "PURCHASED",
"originalPurchaseDate" : 1713511999000,
"originalTransactionId" : "430001792218708",
"purchaseDate" : 1713511999000,
"quantity" : 1,
"signedDate" : 1753346396278,
"storefrontId" : "143481",
"transactionId" : "430001792218708",
}
2025-07-24 12:39:58.598 +0400 [INFO] [MKPaymentService:23]: [XLPay] listenForTransactions :{
"appTransactionId" : "704289572311513293",
"deviceVerificationNonce" : "5ca85907-1ab6-4160-828e-8ab6d3574d6f",
"environment" : "Production",
"inAppOwnershipType" : "PURCHASED",
"originalPurchaseDate" : 1713512034000,
"originalTransactionId" : "430001792219189",
"purchaseDate" : 1713512034000,
"quantity" : 1,
"signedDate" : 1753346396278,
"storefrontId" : "143481",
"transactionId" : "430001792219189",
}
2025-07-24 12:39:58.599 +0400 listenForTransactions :{
"appTransactionId" : "704289572311513293",
"deviceVerificationNonce" : "04869b50-b181-4b69-b4ff-025175e9cf14",
"environment" : "Production",
"inAppOwnershipType" : "PURCHASED",
"originalPurchaseDate" : 1713512049000,
"originalTransactionId" : "430001792219440",
"purchaseDate" : 1713512049000,
"quantity" : 1,
"signedDate" : 1753346396278,
"storefrontId" : "143481",
"transactionId" : "430001792219440",
}
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
I had everything working with Revenue Cat. Then my app got rejected for not loading subscriptions, which was odd because a previous built was rejected for wording on that same paywall.
I checked, and realised I suddenly can't fetch products in testFlight either. I can only see products in Xcode using the store kit configuration file.
I've found many issues like this online and everybody point to the same solutions (that seem to work for most), but here's what I tried so far:
Checked that all my agreements in App Store Connect are active
Checked that ids match between Xcode / revenue cat / App Store connect
Store kit config file is syncing with App Store Connect correctly
I removed revenue cat and used the store kit api directly to fetch products. The array of products is empty in all environments that don't have access to store kit config file.
Checked status of all subscriptions (all waiting for review -- as they were when the paywall worked)
Nothing seems to work...
Any suggestions?
Many thanks
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
App Store
StoreKit
App Store Connect
TestFlight
We are experiencing a critical issue where StoreKit 2 is returning empty products when using Product.products(for:), specifically on devices running iOS 18.4.
This issue does not occur on iOS 18.3 or earlier.
Steps:
Created a subscription product (e.g. "upm1") in App Store Connect
Confirmed the product is active, localised, and part of a valid subscription group
Call the following Swift code using StoreKit 2:
Task {
do {
let products = try await Product.products(for: ["upm1"])
print(products)
} catch {
print("Error: (error)")
}
}
4. Result: products is an empty list.
This regression is blocking subscription testing on iOS 18.4.
Kindly someone please advise on a potential fix or workaround.
Use the following method to fetch:
let appProducts = try await Product.products(for: productIdentifiers)
The following checks have been carried out
✅ Must-check points
App ID capabilities
Subscription product status (ready to submit)
Why The result is an empty array?
Hello.
I have setup a StoreKit testing in the app that was and still is perfectly working on iOS 18.
Unfortunately when run on iOS 26 the following error gets printed in the console after calling Transaction.currentEntitlement(for:) method:
Failed to verify certificate chain due to client recoverable failure:
Error Domain=NSOSStatusErrorDomain Code=-67843 "“StoreKit Testing in Xcode” certificate is not trusted" UserInfo={NSLocalizedDescription=“StoreKit Testing in Xcode” certificate is not trusted, NSUnderlyingError=0x109de7e10 {Error Domain=NSOSStatusErrorDomain Code=-67843 "Certificate 0 “StoreKit Testing in Xcode” has errors: Root is not trusted;" UserInfo={NSLocalizedDescription=Certificate 0 “StoreKit Testing in Xcode” has errors: Root is not trusted;}}}
I'm not seeting any StoreKit Testing certificates in phone's certificate trust settings.
This test was performed on iOS 26.0 (23A341) with app built in Xcode 16.4.
FB20339145
I have three questions about verify receipt
I use this api (https://buy.itunes.apple.com/verifyReceipt)to verify receipt is success or not. But since last month, this interface has started to return an error(21002). I see this document (https://developer.apple.com/documentation/appstorereceipts/verifyreceipt) say its Deprecated. My question is, is the error suddenly returned recently because the interface has been deprecated or for some other reason? (I haven't modified my code about this recently)
I can not understand this document: (https://developer.apple.com/documentation/appstorereceipts/validating_receipts_on_the_device) Does this mean that in the new version, as long as the app returns a payment success (purchaseDetails.status == PurchaseStatus.purchased), the payment is guaranteed to be successful, and my server does not need to request payment result verification from Apple's server?
I try to use this (https://github.com/apple/app-store-server-library-java) to get TransactionInfo, but I dont konw to get Transaction status to know is success or not.
my java server code :
AppStoreServerAPIClient client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment); TransactionInfoResponse response = client.getTransactionInfo(transactionId);
(bug i can note get transaction status, how do i konw this Transaction is success or not)
I just spent way too many hours trying to figure out why my in-app subscription was stuck in “Missing Metadata” in App Store Connect, even though I had filled out everything. If you're here because you're in the same boat, this is the solution Apple doesn't make obvious.
The Problem
I created an auto-renewable subscription (Kanabloom Premium) and filled in all required fields.
The subscription was still marked "Missing Metadata", preventing me from submitting it.
The “In-App Purchases” section wasn’t showing up in my App Store version submission, which meant I couldn't even attach the subscription to my app version.
I triple-checked the metadata, pricing, tax settings, review screenshot, and even resaved everything, but nothing worked.
What I Tried (Before Finding the Fix)
Checked that pricing was set up correctly for all countries.
Uploaded the required review screenshot for the subscription.
Made sure the subscription group existed and was linked properly.
Refreshed, logged out/in, and tried different browsers.
Read every Stack Overflow, Reddit, and Apple Developer Forum post I could find.
Even tried creating a dummy subscription to see if that would reset the system.
The Solution: Localizing the Subscription Group
Here’s the stupidly hidden requirement that finally fixed it:
✅ Your subscription group itself (not just the subscription) needs a localized display name.
App Store Connect requires each subscription group to have at least one localized display name for it to be valid. If this is missing, all subscriptions inside that group will stay stuck in “Missing Metadata” no matter how complete they are.
How to Fix It:
Go to App Store Connect > Subscriptions > Subscription Group
Click on your subscription group (not the individual subscription).
Check if there's a localization added under "Group Reference Name."
If missing, add a localization (e.g., English) and save.
Refresh the page and boom – the subscription will finally be "Ready to Submit."
Conclusion
Apple really needs to make this requirement clearer. Now that I’ve finally figured it out, hopefully, this post helps someone else avoid losing hours of their life to the same issue.
If you're still stuck, double-check that:
You’ve set pricing and enabled "Cleared for Sale."
You’ve uploaded a review screenshot for the subscription.
You’ve signed all App Store agreements and banking/tax documents.
Your app's In-App Purchase capability is enabled in Xcode.
Let me know if this helped you! I wish I had found a post like this sooner. 😂
This should make for a useful and searchable post in case other devs run into the same headache. Let me know if you want any tweaks before posting! 🚀
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
App Store Connect
App Review
StoreKit
i'm integrating In-App Purchases in our Flutter app using the official in_app_purchase plugin. We are currently testing consumable purchases and facing issues with the way events are delivered from StoreKit to the app.
Implementation details
I initiate the purchase with:
await InAppPurchase.instance.buyConsumable(purchaseParam: purchaseParam);
I listen for purchase updates with:
final Stream<List> purchaseUpdated = inAppPurchase.purchaseStream;
_subscription = purchaseUpdated.listen((purchaseDetailsList) {
_handlePurchaseUpdates(purchaseDetailsList);
}, onError: (Object error) {
updateApplePaymentStatus(isSuccess: false, response: jsonEncode(error.toString()));
}, onDone: () {
_subscription.cancel();
});
Issues Observed
Control on purchase button event
As soon as the user taps the purchase button, the App Store purchase sheet is shown.
Question: Is there a way to intercept control at this point (before showing the sheet) to perform additional checks or logging?
Cancelled payment after UPI intent
In our testing with UPI payment flows (UPI intent triggered from Apple Pay/linked payment method), if the user cancels the payment from the external flow, we don’t see a clear event in purchaseStream.
Question: How can we reliably capture this cancellation status on the app side?
Event timing after successful purchase
Currently, the purchaseStream event is only triggered after the StoreKit purchase confirmation popup has been dismissed by the user.
Question: Is there a way to capture the event earlier (i.e., right after StoreKit confirms payment success), so we can update our backend and UI without waiting for popup dismissal?
Request
We would appreciate guidance on:
Best practices for intercepting purchase initiation before the StoreKit sheet.
Recommended way to detect and handle cancelled payments (especially in UPI flows) managed on frondend side.
Whether it is possible to receive successful purchase events without waiting for the user to dismiss the confirmation dialog.
Thank you for your support.
Hello!
We are implementing consumable IAP for iOS using StoreKit 2 together with our own server backend.
Our happy path looks like this:
1. Call /prepare on our server
• We only allow one purchase at a time, so this fails if a pending transaction already exists.
2. Call /purchase via StoreKit
3. If successful, call /complete on our server
4. Call .finish() on the Transaction
⸻
The Problem
Some users report being charged by Apple but not receiving coins.
I suspect this happens in rare cases where the purchase flow throws an exception:
• Every time we throw, we immediately cancel the transaction on our server.
• However, some errors may actually be temporary. StoreKit seems to recover by later sending an update through Transactions.updates.
• When that happens, since the transaction was already canceled on our server, we cannot match it. As a result, we just call .finish() without granting consumables.
⸻
Additional Observations
From user logs, the issue tends to appear when the following errors are reported:
• リクエストを完了できません。
• Triggered by: StoreKit.notEntitled
• Triggered by: StoreKit.unknown
• ヘルパーアプリケーションと通信できませんでした。
I was not able to reproduce the last one, even when testing all possible StoreKit configuration errors. Some sources suggest this may be a rare case where the app cannot communicate with the App Store itself.
Additionally, affected users often seem to be using non-standard payment methods (PayPay, gift cards, carrier billing, etc.) rather than credit cards.
⸻
My Question
What is the best practice for handling StoreKitError and PurchaseError?
Specifically:
• Should some of these errors be treated as temporary instead of final?
• How should we ensure users always receive their consumables in such cases?
⸻
Code
do {
let result = try await wrapper.product.purchase()
switch result {
case .success(let result):
let transaction = try StoreKitVerifier.checkVerified(result)
let iOSPurchase = IOSPurchase(transaction: transaction, jws: result.jwsRepresentation)
return .Success(purchase: iOSPurchase)
case .userCancelled:
return .Canceled()
case .pending:
return .Pending()
@unknown default:
return .Error(
message: "Purchase result doesn't match with anything. This must not be executed")
}
} catch {
return .Error(message: error.localizedDescription)
}
Hello Developer support, In one of our live application we have seen that users are purchasing weekly subscription and automatically they shifted to yearly product. Due to this we have received high revenue and also refunds afterwards. To prevent this we removed our yearly product from the sale. In App Store Connect we have seen activations for weekly product and convert to standard prices are yearly products. Also we have seen weird behavior of user getting trial for same product for three times. For developer support people I am sharing my app id - 1320373866 , and here is the video of our issue - https://drive.google.com/file/d/1DBHw8ivgql4eNoo8NC3xo5v4wgr8Oh7x/view?usp=sharing , Also attaching trial behavior screenshot.
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?