I'm thinking of using server-side validation of a receipt and in-app purchase, but I'm not sure how I can prevent a valid receipt from one device from being used illicitly on a different device. Then I started thinking about local validation, and realized I don't understand how it works there either. Yes, there is the "hash" in the receipt that uses the `UIDevice.current.identifierForVendor`, but if a device is jailbroken, can't it just patch a framework somewhere to return a bogus ID there, to match the one in the illicit receipt?
Receipt validation - a real receipt on a jail broken device?
Strictly a cat/mouse game, where you can leverage UIDevice.current.identifierForVendor to detect JB, but if they're determined enough, they can defeat your detect, wash/rinse/repeat. Point is, the win in this example goes the one that gives up the game last.
Use it for what it's worth, then decide how much more effort you're willing to put towards dealing with fraud. While I'm sure you have a right to be proud of your app, unless it ha$ a big following I'm not sure there is that much interest in your particular goods to push that hard.
Your energies may be better put towards attracting and keeping paying users, routinely staying ahead of the fraud that offers outdated content, etc.
I had written a fairly complex response and now it has disappeared! Here goes...again.
1) regarding receipt validation on a jailbroken device: Remember that the identifierForVendor is not in the receipt, only the salted hash. So to hack that, someone would need to retrieve the actual value of the identifierForVendor of the device with the original receipt and then interupt the second device's call to the identifierForVendor API and replace the response with the other device's identifierForVendor. That's pretty hard. On the device validation is pretty secure.
2) regarding the server to server validation - in the old days you could simply use transaction_id as unique to each receipt. Your server would keep a file of all past transaction_id's and if it detected a duplicate it would flag it as a fake. The new receipts have confounded that. When certain IAP's do a restore or a repurchase (for free) or an auto-renew, the transaction_id is repeated. So you must now move over to a selection of other fields such as receipt_request_date. Once you identify a set of markers that could not be repeated in another receipt then use that as a record and flag any duplicate receipts.
Thanks for writing it again after your draft disappeared. The existence of this forum software is one of the mysteries of the universe to me.
Point #2 seems a bit tricky because a user could be legitamately restoring purchases or installing on a second device.
Point #2 seems a bit tricky because a user could be legitamately restoring purchases or installing on a second device.
And that is why you use receipt_creation_date along with transaction_id to assure uniqueness.