Search code examples
iosin-app-purchase

How to handle an interrupted in-app purchase with specific data


I want to set up a consumable in-app purchase that buys a virtual ticket for a specific event in my app. When they buy the ticket I will send a message to my server to add their userID for a specific event ID in the database. There will be many events that a user could buy a consumable ticket for.

I am aware of the necessity for a SKPaymentTransactionObserver subclass which handles transactions.

However, if something goes wrong (they background the app, battery dies, loss of internet connection) the SKPaymentTransactionObserver will be sent the transaction until I call -finishTransaction. How can I know what event ID they've purchased the consumable for in this instance? Is there a payload that I can attach to a transaction?


Solution

  • Unfortunately, there is no official way to add a payload to a payment request. If you provide a consumable for each event, you can check for the product id, but I assume it would be overkill to provide and maintain a consumable for each possible event.

    You could try to abuse the applicationUsername field for that. But, corresponding to Apple's documentation (see below) and the fact it isn't guaranteed to be persisted, I wouldn't recommend that.

    The applicationUsername property is not guaranteed to persist between when you add the payment transaction to the queue and when the queue updates the transaction. Do not attempt to use this property for purposes other than providing fraud detection.

    Another way could be to remember each created transaction mapped to its event id in a dictionary and after a transaction succeeded, you look into that dictionary for the corresponding event id. This works as long as the app doesn't restart. You could also remember the mapping between transactions and event ids within the user defaults.