apple / app-store-server-library-python

MIT License
147 stars 31 forks source link

Local receipt validation #55

Closed CallumAtCarter closed 7 months ago

CallumAtCarter commented 7 months ago

The App Store developer documentation describes validating receipts with the App Store as deprecated, and recommends performing the validation on the server locally:

To validate receipts on your server, follow the steps in Validating receipts on the device on your server.

- https://developer.apple.com/documentation/storekit/in-app_purchase/original_api_for_in-app_purchase/validating_receipts_with_the_app_store

Validating the receipt locally requires you to develop or use code to read and decode the receipt as a PKCS #7 container, as defined by RFC 2315.

- https://developer.apple.com/documentation/appstorereceipts/validating_receipts_on_the_device

The README describes using ReceiptUtility.extract_transaction_id_from_app_receipt, but this only gets the transaction ID, and does not perform any validation:

Extracts a transaction id from an encoded App Receipt [...] NO validation is performed on the receipt

The example goes on to use AppStoreServerAPIClient.get_transaction_history, which seems to contradict the advice of performing the validation locally, and makes the receipt signing entirely redundant.

Does this library provide any way of performing this validation and extracting the fields of the receipt locally?

Also, given a receipt from a customer device, can I safely call AppStoreServerAPIClient.get_transaction_history when no validation of the receipt has taken place? Could the transaction ID in this case not have been spoofed?

Perhaps there's a different library I need. Any help on this is greatly appreciated.

alexanderjordanbaker commented 7 months ago

Generally we recommend the device to send the signed JWS from StoreKit 2 (https://developer.apple.com/documentation/storekit/verificationresult/3868429-jwsrepresentation), which can be directly validated using this library as part of the SignedDataVerifier. If there are devices that have not yet been upgraded to StoreKit 2, this library allows extracting the transaction id and then calling the history endpoint to support those installs.

CallumAtCarter commented 7 months ago

@alexanderjordanbaker Thanks for the quick support, I appreciate it. This is starting to make a lot of sense. I am using Unity IAP which only supports StoreKit 1. Good to know that when they do upgrade I can continue to use this package.