My app will allow the user upgrade to Pro features via an In-App Purchase. I am validating the receipt data with my own server, and one the confirmation comes back from my server, I call finishTransaction:
What will happen if the validation fails (perhaps not due to piracy attempt) and I dont call finishTransaction: ? Will it stay in the queue indefinitely?
Here's what Apple tells you to do: When you get a notification that an in-app purchase has been made successfully, then there are two possibilities: Either the user paid money to your bank account, or a hacker forged that notification.
So you send the receipt to your server, which checks the receipt. Make one hundred percent sure that it doesn't reject any correct receipts. When it tells your app that the receipt is valid and has been processed, your app calls finishTransaction. If it tells your app that the receipt is invalid, nobody knows exactly what to do, but calling finishTransaction won't hurt. If anything else goes wrong (your server crashed, internet went down etc. ) you do not call finishTransaction, because if you do, the customer loses their money without getting anything and will be quite angry. In that case, you will be told about the transaction again at some later time. Possibly on a different phone, if the user has two or more devices. So be prepared that a transaction could arrive at any time, even if your app hasn't seen any purchases on that device.
That's why it is wrong to store anything in user defaults. The device where the user presses the "buy" button isn't necessarily the one where the purchase ends up being made. (There are people with many iOS devices, even in a simple case a user might switch between their iPhone and their iPad).
if the request to the server failed, in what way will my app get notified again to retry the request to my server?
If you didn't finish a transaction then it stays in SKPaymentQueue. And when your app connects to SKPaymentQueue it receives all transactions connected with it.
So your app will need to finish all unfinished transactions.
I always found that I got strange behavior afterward at some point, if FinishTransaction
wasn't called.
The best option is to set a setting in StandardUserDefaults
, etc. indicating "I bought this but it failed", and call FinishTransaction
. Then when they restart the app (or foreground the app) you could check for this and send it to your server.
Also, if your purchase is not a consumable (i.e not buying coins or money), you can just call FinishTransaction
and tell the user to activate RestoreTransaction
from a button in your settings menu. This button is required by Apple for non-consumable purchases anyway.
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