The sample code provided in https://developer.apple.com/wwdc21/10114 doesn't appear to call finish()
on unverified transactions, and I haven't been able to find any documentation regarding what to do with unfinished transactions. However, Apple has always emphasized the importance of finishing transactions, and since a transaction object is provided even with the unverified state, I'd love some guidance!
StoreKit 2 - Is it necessary to finish unverified transactions?
Any guidance here? If you download https://developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api and look at its implementation of Store.purchase()
, you'll see that if the transaction is .unverified
, checkVerified()
will throw StoreError.failedVerification
, and transaction.finish()
will not be called.
I also encountered the same confusion, the same transactionid, every time when the restoreTransaction, there will be unverified failure of the order, and I feel very strange
Here is my non expert take on this.
Deciding what to do with an unverified transaction is a business decision. You can ignore verification and unlock the content, although I have no idea why would someone decide to do this. In StoreKit 1, the equivalent of verifying a transaction required sending a receipt to your server. App developers who did not want to maintain a server and were willing to take the risk of hacking, simply handled all transactions.
You should call finish()
only after you unlocked the content. If you do not plan unlocking the content for unverified transactions, do not call finished()
. Apple's example you provided is supporting this theory.
I would cautiously speculate that the app should almost never encounter an unverified transaction unless the user is trying to do something funny with the device or a bug on Apple's side.
Also notice that in a rare case transaction can change from unverified to verified. See this: https://developer.apple.com/documentation/storekit/verificationresult/verificationerror/revokedcertificate