question

ara avatar image
ara asked

iOS 7+ style iTunes Receipt Failing RestoreiOSPurchases (ReceiptAlreadyUsed)

Hi, so I had been discussing this in the Slack chat, but our game has been facing an issue where any attempts to restore our iOS purchases (through Playfab validation) are failing. After trying a variety of things (both depending on Unity's saved receipt and manually reaching out to iOS for a receipt), I noticed that using the deprecated SKPaymentReceipt's "transactionReceipt" (base64) would validate successfully if plugged into the Playfab web API , but if I used the newly preferred way (using NSBundle's appStoreReceiptURL, which provides base64 of an ASN1 style receipt, and is also what Unity provided), the receipt would always come back with ReceiptAlreadyUsed.

Considering what is effectively the same receipt gets two separate results (and I have tried verifying the ASN1 version and failed, then used the older style and had that succeed), I am worried something that either something Playfab's end is erroneously rejecting our attempts to validate, or something on Apple's new receipt style does not refresh everything that is expected. I can provide receipts in both styles as needed. Thanks for your help!

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
brendan avatar image
brendan answered

The problem with that appStoreReceiptURL receipt is that it's the previous receipt - it's what Apple refers to as a "refresh receipt", which they suggest you use to compare it to what you've already given the player and give them any missing items. The reason you should never use a refresh receipt to restore items is because it provides an exploit in your game, as that refresh receipt could then be passed from player to player and re-used. That's why we record the key information on the receipt and mark it in our database as "used" - so that players can't cheat your game with receipts that aren't theirs (a common tactic).

Instead, you need a "restore receipt", which you get from the SKPaymentQueue's restoreCompletedTransactions (which is not deprecated): https://developer.apple.com/reference/storekit/skpaymentqueue/1506123-restorecompletedtransactions. On a successful call to that API, your paymentQueueRestoreCompletedTransactionsFinished will be called, to let you know that the restore receipt is available - that's the one to pass to us.

7 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

ara avatar image ara commented ·

So when I call RestoreCompletedTransactions, the delegate passes back the SKPaymentQueue which was used to restore the transactions. How should I grab the "restore receipt" from there? Inside the queue, there is an NSArray of SKPaymentTransactions, but the transactionReceipt field is the only receipt field I see there, and that field is the deprecated one I mentioned. Also, and I could work around this, but that "transactionReceipt" is not a field I have been able to access via Unity's IAP libraries, which would make integrating this service for anyone using Unity pretty tricky (unless I missed an access point).

Is there a different way you recommend I receive the payload to pass to PlayFab for these "restored" receipts using an iOS bridge, that does not use this deprecated "transactionReceipt" field?

0 Likes 0 ·
brendan avatar image brendan ara commented ·

As far as I can tell from reviewing their documentation and forums, Apple has yet to provide equivalent functionality. This has been called out to them in their forums a few times. Ex:

https://forums.developer.apple.com/thread/42247

https://forums.developer.apple.com/thread/8659

In all the cases I've managed to find, there isn't a response from Apple stating how to use appStoreReceiptURL to get a Restore receipt instead of a Refresh receipt. Developers appear to largely be falling back to using the transactionReceipt, despite it having been deprecated (and because Apple have called it out as the fall-back to use).

We'll reach out to Apple to see if they can provide any update, and I would encourage developers to do the same. If they provide clarification on how to obtain a refresh receipt - one that can safely be used to restore purchases without exposing your games to exploits - without using transactionReceipt, we'll happily update the docs to reflect that info.

0 Likes 0 ·
countinglampposts avatar image countinglampposts brendan commented ·

Is this still a problem? Ive been combing forums and docs trying to find a restore receipt and haven't made any progress.

0 Likes 0 ·
Show more comments
ara avatar image ara commented ·

Got it. Thanks for the explanation Brendan.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.