AppStore.sync() not restoring purchases

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.

Hello! Did you manage to solve this?

Same issue here.

Classic StoreKit 1 to 2 migration pitfall. A few things worth checking:

  1. The sandbox account matters more than you'd expect. When you reinstall, make sure you're signed into the same sandbox Apple ID that actually made the SK1 purchase. If it's a fresh sandbox user or a different one, there's literally no transaction to restore. Settings > Developer > Sandbox Apple Account shows who's currently active.

  2. For a non-consumable originally purchased via SK1, after AppStore.sync() completes, the transaction shows up in Transaction.currentEntitlements with its original productID, but the id or originalID might be a legacy numeric identifier rather than a UUID. If you're filtering entitlements by anything other than productID, that could be why you don't see it.

  3. AppStore.sync() triggers an Apple ID password prompt. If the user cancels that prompt, it returns without throwing but also without actually syncing. Wrap it in try/catch and log so you can distinguish canceled vs successful vs failed.

  4. If this is a TestFlight build rather than a sandbox-signed build, TestFlight uses the production App Store Commerce backend. You won't be able to restore SK1 sandbox purchases across, only production purchases the TF user actually made.

One more thing: check Transaction.all (not just currentEntitlements) after sync. If the old SK1 transactions show up there but not in currentEntitlements, it's a filtering issue on your side. If they don't appear in Transaction.all at all, the sync isn't reaching them, which usually points back to point 1.

AppStore.sync() not restoring purchases
 
 
Q