iOS Server Side Validation - Receipt Types

iOS Server Side Validation - receipt types

In iOS 6 each IAP (in-app purchase) transaction would have its own receipt (SKPaymentTransaction.transactionReceipt in the StoreKit API). When you send this receipt data over to their validation API, you get the former response.

In iOS 7, Apple has started using something they call the “Grand Unified Receipt”. This means that apps have one receipt that contains information about the purchase of the app itself, as well as IAPs. You use the -[NSBundle appStoreReceiptURL] API to load this receipt data from disk (and possibly SKReceiptRefreshRequest to get it if it doesn't seem to exist). When you send this receipt data over to their validation API, you get the latter response.

The main difference is that the former receipt format represents one IAP transaction, while the latter represents an array of them (as well as the purchase of the application itself).

See more info in the “Using Receipts to Protect Your Digital Sales” WWDC 2013 session.

In App Purchase receipt validation with trusted server. Any ideas why I am not getting the latest receipt from the server?

The purpose of server-side receipt validation is to protect yourself against users injecting a forged receipt. The server simply validates the receipt that you send it. It doesn't use the receipt you send to check if there is a later corresponding receipt available.

The flow you describe, where you need to restore purchases on Device B, is the expected process.

You may be confusing server-side receipt validation with server notifications, where Apple can send your server subscription status updates

Server side receipt validation for non-consumable products in iOS7 and transactionReceipt deprecation

From what I've been able to gather via Apple's documentation.

1) There is one receipt for all purchased products. In order to perform server side validation you send the entire receipt to your server, which forwards it to Apple for verification. See this post on the Apple Developer Forums (starting around comment 13) https://devforums.apple.com/thread/193893?tstart=0

2) Non-consumables will remain in the receipt forever, so yes it will grow and grow. Consumables are removed lazily from the receipt once finished via a call to finishTransaction. See https://devforums.apple.com/message/876265#876265

3) The iOS6 way of looping through updatedTransactions and sending individual receipts to your server for validation seems at odds with the new iOS7 design. This post on the Apple Developer forums suggests you "Send the whole list of transactions to your server with the receipt. When the receipt is verified, deliver all of the products, and finish all of the transactions." https://devforums.apple.com/message/897870#897870

4) That really does seem to be the case.

If you believe the iOS7 documentation is lacking you can raise a bug report with Apple

Understand the serverVerificationData in_app_purchase Flutter

It looks like either your receipt is not correct ( sandbox has issues sometimes ) or your server-side setup is wrong

For the first point, you can try creating a receipt by generating a storeKit config file.
This can't be done in flutter, you have to open iOS module with code and setup storekit config file by going here.

After setting up the storekit file, you can either run the app from xCode directly or just close xCode and run from your preferred flutter IDE

Now, iOS will never hit the production purchase identifiers when you try to fetch/buy products from the app, and instead fetch the products from your storekit config and generate a receipt from those. This receipt is accepted by apple sandbox verification endpoint, you can also test refunds and subscription cancellations from xCode using a storekit config.

For the second point, you have to enable the app specific shared secret in iTunes connect and then use that in the 'password' key in the receipt validation API.
Here is where you find it
AppStoreConnect > Your app > Subscriptions

If it still doesn't solve the issue, I'd be happy to assist further.

App specific shared secret

EDIT: I just tested purchasing an auto renewable subscription purchased in sandbox (not storeki
t) and then validating it using the sandbox URL and it returned the correct receipt data. In your post above, you don't need to base64 encode the purchaseDetails.verificationData.serverVerificationData since its already encoded. Have you tested this on postman? It Works there

EDIT: so the request is malformed because you are not sending data as String so you need to dump the dict :

request_body = json.dumps({"receipt-data": token})


Related Topics



Leave a reply



Submit