When is the unverified branch of AppTransaction.shared entered?

Hi all,

I am adding the following StoreKit 2 code to my app, and I don't see anything in Apple's documentation that explains the unverified case. When is that case exercised? Is it when someone has tampered with the app receipt? Or is it for more mundane things like poor network connectivity?

    // Apple's docstring on `shared` states:
    // If your app fails to get an AppTransaction by accessing the shared property, see refresh().
    // Source: https://developer.apple.com/documentation/storekit/apptransaction/shared
    var appTransaction: VerificationResult<AppTransaction>?
    do {
        appTransaction = try await AppTransaction.shared
    } catch {
        appTransaction = try? await AppTransaction.refresh()
    }

    guard let appTransaction = appTransaction else {
        AppLogger.error("Couldn't get the app store transaction")
        return false
    }

    switch appTransaction {
    case .unverified(appTransaction, verificationError):
        // For what reasons should I expect this branch to be entered in production?
        return await inspectAppTransaction(appTransaction, verifiedByApple: false)
    case .verified(let appTransaction):
        return await inspectAppTransaction(appTransaction, verifiedByApple: true)
    }

Thank you, Lou

Answered by endecotp in 823471022

Is it when someone has tampered with the app receipt?

Yes, and similar.

I suggest presenting an alert asking the user to contact you for advice. If you already have some kind of analytics, include this. Don't ignore the possibility of false positives, i.e. users who have made a legitimate purchase but are reported as unverified here.

I use this:

	private func handle(transaction: VerificationResult<StoreKit.Transaction>) async {
		guard case .verified(let transaction) = transaction else {
			return
		}
    // Do something with the verified transaction...
    await transaction.finish()

That should ignore any transaction that's not verified.

Is an unverified transaction for a jailbroken phone, that sort of thing?

Accepted Answer

Is it when someone has tampered with the app receipt?

Yes, and similar.

I suggest presenting an alert asking the user to contact you for advice. If you already have some kind of analytics, include this. Don't ignore the possibility of false positives, i.e. users who have made a legitimate purchase but are reported as unverified here.

if the unverified branch is entered + receipt validation fails, I'll feel OK about marking requests from that app as fraudulent.

No, I think that if you get an unverified AppTransaction then you will also fail to verify the receipt on your server. Doing both is probably redundant.

Be very cautious about blocking users based on any of this stuff. Assume that they can still write app store reviews when you block them.

When is the unverified branch of AppTransaction.shared entered?
 
 
Q