Reputation: 1284
I am trying to verifying that an auto-renewable In App purchase has not expired server side (not on a device).
I am using Apple's Grand Unified Receipt (iOS 7 style transactions). The response returned by Apple contains in_app
and latest_receipt_info
elements with an array of receipts. The in_app
JSON element contains LESS receipts than latest_receipt_info
. I was expecting both elements to contain the same number or receipts.
Also, I was expecting that the in_app
element would contain ALL the receipts. However, it appears that latest_receipt_info
actually contains all the receipts. Apple documentation seems to suggest to use in_app
for finding a latest receipt.
I am surprised to see the latest_receipt_info
because Apple's Documentation state that this element is
"Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions." (not iOS 7+).
Which JSON element should I iterate to find the latest receipt for auto-renewable iOS 7 style transactions: in_app
or latest_receipt_info
?
Upvotes: 73
Views: 20041
Reputation: 48366
I want to link the latest docs App Store Receipts
latest_receipt_info
An array that contains all in-app purchase transactions. This excludes transactions for consumable products that your app marks as finished. This only returns for receipts that contain auto-renewable subscriptions.
in_app
located in Receipt.In_appAn array that contains the in-app purchase receipt fields for all in-app purchase transactions.
Since in_app
contains all receipts, I prefer to iterate it and find the latest receipt of auto-renewable subscriptions.
Upvotes: 0
Reputation: 171
Just wanted to make clear that only the latest_receipt_info
field is returning the latest renewed receipt. This is based on what we're actually getting back from Apple.
The relevant documentation is here on page 21.
Although it states that latest_receipt
and latest_receipt_info
fields are "Only returned for iOS 6 style transaction receipts for auto-renewable
subscriptions", we've found that they are being returned in our iOS 7 receipts. The in_app
field within the receipt
object is also returned with almost identical data, but doesn't contain the latest receipt info, which is the one you care about in the case of an auto-renewal.
Upvotes: 17
Reputation: 31
Babken Vardanyan mentioned in multiple answer threads that latest_receipt_info is sometimes missing. One interesting thing I've seen in receipts in this thread https://forums.developer.apple.com/thread/92200 was the difference in latest_receipt_info vs in_app. When doing a diff I noticed the the first receipt in the chain was missing (containing is_trial_period=true). It didn't generate an in-app receipt equivalent.
As linked in the documentation: https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW4 says to use latest_receipt_info as "for iOS 7 style app receipts, the value of this key is an array containing all in-app purchase transactions."
In regards to subscriptions, you should not use in_app and only use latest_receipt_info.
https://www.revenuecat.com/2018/09/24/apple-subscription-notifications-are-almost-useless covers the edge cases like cancellation_date where it is a customer service provided cancellation like seen in this apple developer forum thread: https://forums.developer.apple.com/thread/96670
Upvotes: 3
Reputation: 2368
To verify that an auto-renewable subscription has not expired check the latest_receipt_info
element.
This is what's currently (2017-08-09) officially documented on the in_app
and latest_receipt_info
elements:
in_app
In the JSON file, the value of this key is an array containing all in-app purchase receipts based on the in-app purchase transactions present in the input base-64 receipt-data. For receipts containing auto-renewable subscriptions, check the value of the latest_receipt_info key to get the status of the most recent renewal.
(source)
latest_receipt_info
Only returned for receipts containing auto-renewable subscriptions. For iOS 6 style transaction receipts, this is the JSON representation of the receipt for the most recent renewal. For iOS 7 style app receipts, the value of this key is an array containing all in-app purchase transactions. This excludes transactions for a consumable product that have been marked as finished by your app.
(source)
Upvotes: 17
Reputation: 685
The documentation above makes it pretty clear to use in_app
.
Please note the line "Keys not documented below are reserved for use by Apple and must be ignored by your app" in the documentation.
So even though the decoded receipt has latest_receipt_info
, we should ignore that.
But I agree, the documentation is very lacking and that makes me nervous. Let me know how was your experience using iOS 7 style receipt verification in production.
Upvotes: -1