Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SKPaymentQueue: What happens if I never call finishTransaction:?

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?

like image 856
Dermot Avatar asked Sep 11 '12 10:09

Dermot


3 Answers

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).

like image 20
gnasher729 Avatar answered Oct 06 '22 00:10

gnasher729


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.

like image 32
Mike Avatar answered Oct 06 '22 00:10

Mike


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.

like image 60
jonathanpeppers Avatar answered Oct 06 '22 00:10

jonathanpeppers