Hello!
I make use of the new iOS 15.4 SKAdNetwork.updatePostbackConversionValue feature:
SKAdNetwork.updatePostbackConversionValue(0) { error in
if let error = error {
print(error.localizedDescription)
}
}
I am not sure why, but I always see this error message in the console:
SKAdNetwork: Error while updating conversion value: Error Domain=SKANErrorDomain Code=10 "(null)"
The operation couldn’t be completed. (SKANErrorDomain error 10.)
Any idea what’s going on there? What does Error Code 10 mean? Couldn't find anything in the documentation about that so far.
I have the NSAdvertisingAttributionReportEndpoint key with domain (https://api2.branch.io/v1/skadnetwork/advertiser_app) in my .plist.
StoreKit
RSS for tagSupport in-app purchases and interactions with the App Store using StoreKit.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
On an app that was using the old API for In-App Purchases (StoreKit 1). The app is already published on the App Store. The purchase is non-consumable.
While trying to migrate to StoreKit 2, I'm unable to restore purchases.
Specifically displaying and purchasing products works as expected, but when deleting and reinstalling the app, and then trying to restore purchases I can't do it.
I'm trying to restore them using the new APIs but it doesn't seem to be working.
What I have tried so far:
I'm listening for transaction updates during the whole lifetime of the app, with:
Task.detached {
for await result in Transaction.updates {
if case let .verified(safe) = result {
}
}
}
I have a button that calls this method, but other than prompting to log in again with the Apple ID it doesn't seem to have any effect at all:
try? await AppStore.sync()
This doesn't return any item
for await result in Transaction.currentEntitlements {
if case let .verified(transaction) = result {
}
}
This doesn't return any item
for await result in Transaction.all {
if case let .verified(transaction) = result {
}
}
As mentioned before I'm trying this after purchasing the item and deleting the app. So I'm sure it should be able to restore the purchase.
Am trying this both with a Configuration.storekit file on the simulator, and without it on a real device, in the Sandbox Environment.
Has anyone being able to restore purchases using StoreKit 2?
PD: I already filed a feedback report on Feedback Assistant, but so far the only thing that they have replied is:
Because StoreKit Testing in Xcode is a local environment, and the data is tied to the app, when you delete the app you're also deleting all the transaction data for that app in the Xcode environment. The code snippets provided are correct usage of the API.
So yes, using a Configuration.storekit file won't work on restoring purchases, but if I can't restore them on the Sandbox Environment I'm afraid that this won't work once released, leaving my users totally unable to restore what they have already purchased.
https://developer.apple.com/documentation/appstoreserverapi/send_consumption_information
If the customer provided consent, respond by calling this API and sending the consumption data in the ConsumptionRequest to the App Store. If not, respond by calling this API and setting the customerConsented value to false in the ConsumptionRequest; don't send any other information.
Since our server would be receiving CONSUMPTION_REQUEST server notifications and will be the one calling the Consumption API, how do we know if the user has provided consent? That info doesn't seem to be in the server notification or anywhere else.
Please help! I have a subscription IAP failing on tvOS 18.2 at:
func makePurchase(_ product: Product) async throws
{
let result = try await product.purchase() //ERROR OCCURS HERE (See error message below)
...
Xcode Console message: "Could not get confirmation scene ID for [insert my IAP id here]"
The IAP subscription was working fine on 18.1 and earlier, and the same IAP and code is also running fine on iOS 18.2. The tvOS error on 18.2 happens both in production and sandbox.
Are there any changes to StoreKit 2 which might cause this error?
Dear Apple Support Team,
Hello!
I am currently developing the in-app subscription functionality using Apple IAP API and have encountered a serious technical issue while processing subscription data. I would like to report this issue to you.
Issue Description:
When calling the subscription API endpoint, the same OriginalTransactionId returns inconsistent results. Specifically, a particular transaction ID (let's call it TransactionId_A) should belong to the subscription order with OriginalTransactionId_A, but it is currently incorrectly associated with OriginalTransactionId_B. This issue severely affects our ability to accurately manage and process subscription data.
Here are the relevant log details for your reference:
API Endpoint Requested:
https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{TransactionId_A}
(Note: The link is a placeholder for the actual API endpoint.)
Log Information on February 21, 2025, at 09:40:09:
{
"AppAccountToken": "{AppAccountToken}",
"BundleId": "{BundleId}",
"Currency": "CNY",
"Environment": "Production",
"ExpiresDate": {ExpiresDate},
"InAppOwnershipType": "PURCHASED",
"IsUpgraded": false,
"OfferDiscountType": "",
"OfferIdentifier": "",
"OfferType": 0,
"OriginalPurchaseDate": {OriginalPurchaseDate},
"OriginalTransactionId": "{OriginalTransactionId_A}",
"Price": {Price},
"ProductId": "{ProductId}",
"PurchaseDate": {PurchaseDate},
"Quantity": 1,
"RevocationDate": 0,
"RevocationReason": 0,
"SignedDate": {SignedDate},
"Storefront": "CHN",
"StorefrontId": {StorefrontId},
"SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}",
"TransactionId": "{TransactionId_A}",
"TransactionReason": "PURCHASE",
"Type": "Auto-Renewable Subscription",
"WebOrderLineItemId": "{WebOrderLineItemId}"
}
Log Information on March 21, 2025, at 09:38:49:
{
"AppAccountToken": "{AppAccountToken}",
"BundleId": "{BundleId}",
"Currency": "CNY",
"Environment": "Production",
"ExpiresDate": {ExpiresDate},
"InAppOwnershipType": "PURCHASED",
"IsUpgraded": false,
"OfferDiscountType": "",
"OfferIdentifier": "",
"OfferType": 0,
"OriginalPurchaseDate": {OriginalPurchaseDate},
"OriginalTransactionId": "{OriginalTransactionId_B}",
"Price": {Price},
"ProductId": "{ProductId}",
"PurchaseDate": {PurchaseDate},
"Quantity": 1,
"RevocationDate": 0,
"RevocationReason": 0,
"SignedDate": {SignedDate},
"Storefront": "CHN",
"StorefrontId": {StorefrontId},
"SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}",
"TransactionId": "{TransactionId_A}",
"TransactionReason": "PURCHASE",
"Type": "Auto-Renewable Subscription",
"WebOrderLineItemId": "{WebOrderLineItemId}"
}
From the above logs, it is evident that the same transaction (TransactionId_A) returns different OriginalTransactionId values at different times, which is clearly not expected and severely impacts our ability to correctly process and manage subscription data.
I hope you can address and investigate this issue as soon as possible. If you need any further information or assistance, please feel free to contact me. Thank you for your support!
Best regards!
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
In-App Purchase
App Store Server Notifications
App Store Server API
Hi there 👋🏻
We are facing an issue that started on 24 June 2025 where some users that have an active subscription with an offer are not being able to use/restore their subscription since Transaction.currentEntitlements is empty.
We have tried to call the server with this endpoint https://developer.apple.com/documentation/appstoreserverapi/get-transaction-history and it's returning the correct transactions correctly.
Any idea what is happening?
Hello,
I hope to find out more about how AppTransaction works on macOS, specifically about its internet connection requirements: if I use this to validate that the app is a legit purchase from the Mac App Store, I would not want it to have an always-on requirement just to validate.
Does AppTransaction require the user to always be online for AppTransaction.shared ?
When an app is downloaded from the Mac App Store, is the data needed for AppTransaction automatically embedded during that download, or is that data downloaded upon first launch of the app, therefore requiring an internet connection at launch time?
Once the data/receipt has been downloaded by AppTransaction, is it cached until the app's next update, or is it cleared at some time during the version's life and needs to be re-downloaded, therefore requiring an internet connection at launch?
Where is that receipt/data stored?
Also, if you don't mind me sneaking in this non-related but sort of related question, in terms of receipt validation:
Does macOS Sequoia's MAC address rotation feature affect receipt validation in any way when using IOKit?
Thank you kindly,
– Matthias
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
macOS
StoreKit
App Store Receipts
Mac App Store
I'm encountering an issue with the App Store Server API where the appAccountToken is not preserved when users migrate their Apple ID email addresses. I've submitted
Feedback Assistant ticket FB18709241 but wanted to check if anyone else has experienced this and get community input on best practices.
The Issue
When a user migrates their Apple ID from one email to another (e.g., from olduser@example.com to newuser@icloud.com), the App Store creates a new subscription
transaction with a different originalTransactionId, but the appAccountToken is not carried forward from the original transaction.
What I'm Seeing
note: these values are fake
When querying /inApps/v1/subscriptions/{originalTransactionId} with the either post-migration transaction ID or the pre-migration transaction ID, the API returns both transactions:
Pre-migration transaction (status: 2 - inactive):
originalTransactionId: "12345678910111"
Contains: "appAccountToken": "abc123-def456-ghi789"
Post-migration transaction (status: 1 - active):
originalTransactionId: "67891011121314"
Missing: appAccountToken entirely
The Problem
The appAccountToken is our only way to link App Store subscriptions to user accounts. Without it on the new transaction:
Users lose access to premium features despite having valid subscriptions
Server-side renewal notifications can't be matched to user accounts
Manual support intervention is required for each affected user
Questions for the Community
Has anyone else encountered this issue with Apple ID migrations?
What's the recommended approach for handling this scenario?
Is there an alternative mechanism to maintain the subscription-to-user linkage across migrations?
Questions for Apple Engineers
Is this the expected behavior, or should the appAccountToken be preserved?
Are there any planned improvements to handle this migration scenario?
What's the best practice for developers to handle this case?
Interestingly, both the old and new transaction IDs return the same JSON response from the App Store Server API, suggesting Apple maintains internal linkage between
these transactions, but the appAccountToken isn't carried forward to the active transaction.
Any insights or similar experiences would be greatly appreciated!
Thank you!!
Feedback Assistant: FB18709241
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
StoreKit
App Store Server Notifications
App Store Server API
We feel like we're at the end of the long and treacherous process of migrating to StoreKit2. But we've hit a small snag. When testing in the sandbox environment, we've found that if we don't finish a transactions, no subsequent purchase (invoked via call to purchase or the other purchase) will produce the confirmation sheet. Is this the expected behavior? The behavior is observed on iOS26 and 18.
Our app will only attempt to finish the transaction if it successfully uploads the receipt to our API. If it fails to do so for whatever reason, the transaction is left unfinished. Whilst the user is informed about this, users will commonly try again. Our concern is that since the confirmation sheet will not be shown again, users will not know they are actually paying again - most certainly not the UX we want to have. We'd much rather have our users be fully aware when they're paying us money.
The reason we're choosing not to finish the transaction until our backend has received it and confirmed the receipt to be valid is that the only way the user can get their product is if the server side is aware of this and add more time to the users account. When finishing the transaction via finish immediately after the purchase() call, the confirmation sheet is shown every time after subsequent calls to purchase().
Again, is this the expected behavior both in the sandbox and the production environments? Are we doing something wrong or misusing the product API? We are somewhat stumped because technically, we could get the first confirmation for a product purchase, and then finish it only after an arbitrary amount of calls to purchase() have been made - the user will believe they will have paid only once, but we will receive however much money we can drain from their account - most certainly not the kind of app we want to develop.
Please advise and best regards,
Emīls
We were facing the same error yesterday and tried many different solutions, but none of them worked. However, today the issue resolved itself and everything is working properly now.
The issue we were facing was:
#1. not getting any product in didReceive method of storekit.
#2. it was working sometimes (i.e. if we try 3 times then 1 time we were getting the product
Hello,
Since updating to iOS 26 Beta 3, I’ve been experiencing an issue where transactions purchased through the normal in-app purchase flow continue to be reported as updated and unfinished—even after calling the finish() function. Please resolve this promptly.
We have had a small number of users of our mac app complaining that the app suddenly can't detect their subscription or previous purchase history. These users are not new, and have been using the app successfully for some time.
In the app we do this using the following (very standard) code at app startup:
let result: VerificationResult<AppTransaction> = try await AppTransaction.shared
For those users experiencing the failure, the result is coming back as unverified.
So far we've been unable to find the cause or a solution, but it seems to have become worse with the release of macOS 15.4.
We've tried resetting, rebooting and reinstalling the app.
It's worth adding the (probably obvious) that it's impossible to test or fault-find with this, because we can't replicate the issue in a development environment.
Any suggestions gratefully received.
Description
SKTestSession.setSimulatedError() does not throw the configured error when testing StoreKit with the .loadProducts API in iOS 26.2. The simulated error is ignored, and products load successfully instead.
Environment
iOS: 26.2 (Simulator)
Xcode: 26.2 beta 2 (Build 17C5038g)
macOS: 15.6.1
Framework: StoreKitTest
Testing Framework: Swift Testing
base project: https://developer.apple.com/documentation/StoreKit/implementing-a-store-in-your-app-using-the-storekit-api
Expected Behavior
After calling session.setSimulatedError(.generic(.notAvailableInStorefront), forAPI: .loadProducts), the subsequent call to Product.products(for:) should throw StoreKitError.notAvailableInStorefront.
Actual Behavior
The error is not thrown. Products load successfully as if setSimulatedError() was never called.
Steps to Reproduce
Create an SKTestSession with a StoreKit configuration file
Call session.setSimulatedError(.generic(.notAvailableInStorefront), forAPI: .loadProducts)
Call Product.products(for:) with a valid product ID
Observe that no error is thrown and the product loads successfully
Sample Code
import StoreKitTest
import Testing
struct SKDemoTests {
let productID: String = "plus.standard"
@Test
func testSimulatedErrorForLoadProducts() async throws {
let storeKitConfigURL = try Self.getStoreKitConfigurationURL()
let session = try SKTestSession(contentsOf: storeKitConfigURL)
try await session.setSimulatedError(
.generic(.notAvailableInStorefront),
forAPI: .loadProducts
)
try await confirmation("StoreKitError throw") { throwStoreKitError in
do {
_ = try await Self.execute(productID: productID)
} catch let error as StoreKitError {
guard case StoreKitError.notAvailableInStorefront = error else {
throw error
}
throwStoreKitError()
} catch {
Issue.record(
"Expect StoreKitError. Error: \(error.localizedDescription)"
)
}
}
#expect(session.allTransactions().isEmpty)
}
static func execute(productID: String) async throws {
guard
let product = try await Product.products(for: [productID]).first(
where: { $0.id == productID })
else {
throw NSError(
domain: "SKDemoTests",
code: 404,
userInfo: [NSLocalizedDescriptionKey: "Product not found for ID: \(productID)"]
)
}
_ = product
}
static func getStoreKitConfigurationURL() throws -> URL {
guard
let bundle = Bundle(identifier: "your.bundle.identifier"),
let url = bundle.url(forResource: "Products", withExtension: "storekit")
else {
fatalError("StoreKit configuration not found")
}
return url
}
}
Test Result
The test fails because the expected StoreKitError.notAvailableInStorefront is never thrown.
Question
Is this a known issue in iOS 26.2 / Xcode 26.2 beta 2, or is there a different approach required for simulating errors with SKTestSession in this version? Any guidance would be appreciated.
Feedback Assistant report: FB21110809
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?
Hello,
I use Storekit2 to test the purchase of subscription products. After purchasing a subscription product in the sandbox, it will automatically renew 12 times, and then it will no longer automatically renew. When I click to purchase again, calling the
try await product.purchase()
method does not pop up the purchase pop-up window. In fact, it will directly go to the
case let .success(.verified(transaction)):
step, and the
Transaction.currentEntitlements is empty
Dear Apple Support Team,
Hello!
I am currently developing the in-app subscription functionality using Apple IAP API and have encountered a serious technical issue while processing subscription data. I would like to report this issue to you.
Issue Description:
When calling the subscription API endpoint, the same OriginalTransactionId returns inconsistent results. Specifically, a particular transaction ID (let's call it TransactionId_A) should belong to the subscription order with OriginalTransactionId_A, but it is currently incorrectly associated with OriginalTransactionId_B. This issue severely affects our ability to accurately manage and process subscription data.
Here are the relevant log details for your reference:
API Endpoint Requested:
https://api.storekit.itunes.apple.com/inApps/v1/subscriptions/{TransactionId_A}
(Note: The link is a placeholder for the actual API endpoint.)
Log Information on February 21, 2025, at 09:40:09:
{
"AppAccountToken": "{AppAccountToken}",
"BundleId": "{BundleId}",
"Currency": "CNY",
"Environment": "Production",
"ExpiresDate": {ExpiresDate},
"InAppOwnershipType": "PURCHASED",
"IsUpgraded": false,
"OfferDiscountType": "",
"OfferIdentifier": "",
"OfferType": 0,
"OriginalPurchaseDate": {OriginalPurchaseDate},
"OriginalTransactionId": "{OriginalTransactionId_A}",
"Price": {Price},
"ProductId": "{ProductId}",
"PurchaseDate": {PurchaseDate},
"Quantity": 1,
"RevocationDate": 0,
"RevocationReason": 0,
"SignedDate": {SignedDate},
"Storefront": "CHN",
"StorefrontId": {StorefrontId},
"SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}",
"TransactionId": "{TransactionId_A}",
"TransactionReason": "PURCHASE",
"Type": "Auto-Renewable Subscription",
"WebOrderLineItemId": "{WebOrderLineItemId}"
}
Log Information on March 21, 2025, at 09:38:49:
{
"AppAccountToken": "{AppAccountToken}",
"BundleId": "{BundleId}",
"Currency": "CNY",
"Environment": "Production",
"ExpiresDate": {ExpiresDate},
"InAppOwnershipType": "PURCHASED",
"IsUpgraded": false,
"OfferDiscountType": "",
"OfferIdentifier": "",
"OfferType": 0,
"OriginalPurchaseDate": {OriginalPurchaseDate},
"OriginalTransactionId": "{OriginalTransactionId_B}",
"Price": {Price},
"ProductId": "{ProductId}",
"PurchaseDate": {PurchaseDate},
"Quantity": 1,
"RevocationDate": 0,
"RevocationReason": 0,
"SignedDate": {SignedDate},
"Storefront": "CHN",
"StorefrontId": {StorefrontId},
"SubscriptionGroupIdentifier": "{SubscriptionGroupIdentifier}",
"TransactionId": "{TransactionId_A}",
"TransactionReason": "PURCHASE",
"Type": "Auto-Renewable Subscription",
"WebOrderLineItemId": "{WebOrderLineItemId}"
}
From the above logs, it is evident that the same transaction (TransactionId_A) returns different OriginalTransactionId values at different times, which is clearly not expected and severely impacts our ability to correctly process and manage subscription data.
I hope you can address and investigate this issue as soon as possible. If you need any further information or assistance, please feel free to contact me. Thank you for your support!
Best regards!
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
In-App Purchase
App Store Server Notifications
App Store Server API
I has sandbox account with Japanese local. When i build app directly to check, price is displayed in Japanese Currency. But when I install app from the Test Flight, price is always displayed in USD Currency.
the issue is appear in iOS 18.5
How can i fix this issue ?
Hey!
We're implementing In-App Purchase Subscriptions and we were able to receive "App Store Server Notifications" on our "Sandbox Server URL".
But the last event we received 22 hours ago. We are able to verify transactions and finish them, but receive no webhooks.
We changed nothing on our server or its configurations but the notifications stoped to come.
We consulted the API (https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/history) and it says the same as we see - the last event was 22hrs ago.
I checked all the advices from here as well (https://developer.apple.com/forums/thread/805806?answerId=864483022#864483022).
Is there any Status page for the Store Kit Sandbox services? Was there any outage?
Sincerely,
Konstantin
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit
App Store Server Notifications
Some paid users are unable to use the paid features unlocked by purchasing our subscription plan. It seems that this is due to StoreKit 2's Transaction.currentEntitlements not working the way we would expect it to work.
Are you also encountering this issue? Do you have any idea to improve this situation?
At launch, our app checks if the user is subscribed to the plan, using Transaction.currentEntitlements. As a result, the currentEntitlements array was empty.
Our app then fetches the products from StoreKit 2 using Product.products(for:). As a result, the Product.SubscriptionInfo.RenewalState value of the corresponding Product (product.subscription.status.first.state) is subscribed, which confirms that the user has indeed purchased our plan, but seems to contradict the absence of the corresponding transaction in Transaction.currentEntitlements.
Proactive in-app purchase restore and a restore purchase button calling the AppStore.sync() method are implemented, but using the button did not solve the issue.
Background
We sell a suite of iPadOS/macOS apps that share a single auto-renewable subscription using this architecture.
Per “Offering a Subscription Across Multiple Apps” we require users to sign in before purchasing so we can propagate the entitlement and avoid duplicate subscriptions across apps.
To enforce that sign-in step we plan to turn off Streamlined Purchasing in App Store Connect.
Question
We also want to distribute subscription offer codes (for promotion, retention, appeasing dissatisfied customers, etc.).
After Streamlined Purchasing is turned off, will customers still be able to redeem offer codes outside the app (App Store “Redeem Code” UI or redemption URL)?
If outside-app redemption remains possible, it bypasses our sign-in gate and could let the same customer buy the suite twice (once via each app).
Is there an approved method to limit offer-code redemption to the in-app flow only, or otherwise prevent such duplicate subscriptions?
If no such limitation exists, what best-practice workaround does Apple recommend for multi-app suites that must turn off Streamlined Purchasing yet still wish to use offer codes without duplication risk?
Environment
StoreKit 2; server-side receipt validation & cross-app entitlement propagation.
Apps support the in-app presentCodeRedemptionSheet flow.
We expect to use both one-time-use and custom offer codes.