I'm building an app that allows the purchase of digital items. Since we have many items available, we can't use non-consumables, so we are defining consumables for different price categories (2€ item, 3€ item, etc...).
When a user wants to buy a specific item, I get the consumable product for that specific price category, and start a purchase for that consumable. I then want to send the receipt to my server, validate it, and unlock the item in question.
Here's where I'm unsure on how to implement this. To get the receipt of a transaction, I need to listen to the PaymentQueue, so I get the receipt asynchronously and without context from the actual purchase.
How do I associate the receipt with the item the user purchased?
From what I know, there are two options:
I was just going through the same problem in my app. Here's how I handled it:
- Attach data to my purchase, that I can read out of the receipt. Is that possible? That would be the ideal scenario.
As you've probably found out, this is not possible.
- Store a list of item ids the user started buying, and when I get a receipt (or many receipts) from my queue, I simply look up the item ids, and send them along to my server. When the purchase is finished, I remove the item id from my list. Is this a viable solution? Can there be any problem with multiple devices, where a device gets a receipt although it didn't initiate the payment?
This is pretty similar to what I did. Whenever a user makes a purchase, I create my own purchase object that gets added to an array in User Defaults. My payment object contains the App Store Connect product identifier as well as my app specific product info.
When a receipt comes in on the PaymentQueue I do the following:
I did get some weird behavior when testing in Sandbox where I'd see old receipts appear on the PaymentQueue as well. In this case there isn't a matching object in User Defaults so I finish the transaction anyway.