I am writing an in-app purchase capability for ma iOS app. I'm selling some simple consumables (no downloads). I based my code on this tutorial/topic How do you add an in-app purchase to an iOS application? However I noticed it conflicts with official apple docs.
In this code when a Transaction fails for whatever reason, this code [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; is called. However on apple pages https://developer.apple.com/library/ios/documentation/StoreKit/Reference/SKPaymentQueue_Class/Reference/Reference.html#//apple_ref/occ/instm/SKPaymentQueue/finishTransaction: it is written: "Your application should call finishTransaction: only after it has successfully processed the transaction and unlocked the functionality purchased by the user."
So which approach is correct? Should I call finish on failed transactions?
According to the Apple's In-App Purchase Programming Guide
Your app needs to finish every transaction, regardles of whether the transaction succeeded or failed.
So regardless of the transaction result, you always finish the transaction to remove it from the payment queue and then handle the state (successful or failed) in your code in order to provide the user with the appropriate information
This is an old thread, but I find the answer incomplete, which can be misleading, and Apple docs are a bit vague on the subject. The problem is how we define a 'failed' transaction.
We can identify many states:
You get notified Apple noticed something went wrong (i.e. user cancelled, credit card declined, the kid is not authorized by its father to make the purchase, etc) and informs you of the event.
You must call finishTransaction
We can split this one in multiples ones:
If you don't perform validation nor have server-side inventory, none of this really matters to you, since there are not many points of failure.
Without validation nor server-side inventory, after receiving SKPaymentTransactionStatePurchased you update your database on the phone's storage with the additional/unlocked content, and after that you just call finishTransactions.
Same flow as SKPaymentTransactionStatePurchased.
You must not call finishTransaction
You must not call finishTransaction
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With