latest_receipt and latest_receipt_info fields - deprecated or not?

You used to be able to check the current status of an autorenewable subscription by sending any old coded receipt from the app to the Apple servers and they would respond with the decoded receipt and two new fields - latest_receipt and latest_receipt_info. But the documents


https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1


say this is returned "only for iOS6 style transaction receipts" which are deprecated. Rumor (i.e. your recent post) suggests that the fields will be returned for post iOS6 style receipts (i.e. the receipt in [[NSBundle mainBundle] appStoreReceiptURL]). If so, GREAT!!!!! But is this true? Can we rely on it? When will it be documented?

Up vote post of PBK Down vote post of PBK
Post marked as solved 17k views

45 Replies

Scott,


I would test with a new test user account - as for the downgrade in a group, I just did a quick test with a sample I have, I could go from one subscription item in the group to another and the app receipt was updated with the new info. If the application is where the user makes the change, then the application will know when it gets the successful transaction indication. However, if the user makes the change in the iTunes subscription area, this will result in the creation of an incompleteTransaction when the charge occurs by the iTunes Store. Tkhe app will know when the transactionObserver is called and detects the incompleteTransaction. Things get considerably more complicated if the app is not required to run.


You issue may be better discussed via a DTS incident.

rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Your logic makes perfect sense 🙂. It could be nice to know a customer's intent to (a) forecast revenue or (b) understand why they want to downgrade.


It would be nice to have modern documentation and a fully functional TestFlight environment to cover all the scenarios clearly since there's been many changes in this area recently...sigh.

Using just logic, not experience, to answer:

When a user choses to downgrade they are only signaling an intent to the App Store. They may cancel before the renewal, they may change their mind and go back to the original level. So nothing has happened. And therefore nothing should be reflected in the receipt. Same thing as when a user cancels the autorenewing function - it's only an intention.

Rich,


A TechNote from an Apple representative with a modern date/time would be very helpful.


As for downgrades in the TestFlight environment, my App fails in the SKPaymentTransactionObserver with the localized error "Cannot connect to iTunes Store" everytime I try to downgrade a subscription. So, I'm not able to test what the receipt would contain and when for the downgraded subscription.


Would the receipt show anything in the result from /verifyReceipt before the current subscription ends? If so, what would the JSON look like for the current subscription and upcoming change?


Or, does the downgraded subscription arrive in the receipt after the current subscription period expires? If so, how do we identify that the customer intends to downgrade so we can forecast our revenue?


Thanks,

Scott

PBK, Do you know if this means that the receipt (in_app and latest_receipt_info) through /verifyReceipt will not show the downgraded purchase until the next renewal cycle occurs? Is there any indication that the customer intends to downgrade in the receipt?

>When does a downgrade show in the receipt?

It was my experience that all changes occurred immediatelty. ....As I recall, there is an alert to indicate that the change is effective immediatelty.


I recall that a downgrade occurs at the next renewal cycle and that the user is not refunded anything for their current (not downgraded) subscription period. If this is true, a downgrade, unlike an upgrade, is handled in the normal course of subscription renewals.

(in response to H2OSkier)

Is there any way to test cancellation and subscription downgrades?

For cancellations, there is no good means to do so. The cancellation_date field is only set when Apple Care refunds a non-consumable or auto-renewing subscriptiuon purchase. There's no simulation for this in the sandbox environment. Id submit an enhancement request for iTunesConnect to have the iTunes Store server in the sandbox have a means to simulate this in the applicationREceipt


For subscription change, run two copies of the app. In one, make the purchase to different items in the subscription group. after the change, if the change becomes active, then launch the app on a second device and have it refresh the applicationReceipt and validate the receipt. The subscription change should be present.


The use of the second app will detect renewals made in the iTunes user subscription area as well. However one cannot use this method in the sandbox - another enhancement request.


When does a downgrade show in the receipt?

It was my experience that all changes occurred immediatelty. If your app offers all grouped auto-renewing subscriptions, try purchasing each one before the subscription expires. As I recall, there is an alert to indicate that the change is effective immediatelty.


One other thing, if the applicationReceipt contains an auto-renewing subscription item in the in_app array, then you can manually validate that one applicationReceipt after the purchase of a different subscription in the group - and the JSON results should show the change. This receipt update process only applies to auto-renewing subacriptions. If the first app is later used to make a non-consumable purchase, validating the original application_receipt will not show the non-consumable purchase.


>Oh, and any timeline for the documentation to be revised ;-)?

This would be for a Developer Publications writer to respond to. I work in DTS. I guess I could write a Tech Note - hmm.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Thank you Rich! Based on these clarifications, I've planned to:


a) separate in_app and latest_receipt_info by subscription versus others (like non-consumable/consumable)

b) sort the in_app and latest_receipt_info by descending purchase date order

c) look for cancellation_date in in_app and latest_receipt_info for current/active subscription

d) look for subscription upgrades and downgrades to adjust expiration dates of n-1 subscription life


Is there any way to test cancellation and subscription downgrades? It makes me nervous to push into the App Store without confirming the logic. When does a downgrade show in the receipt? After the current subscription ends?


Oh, and any timeline for the documentation to be revised ;-)?


Thanks!

With regards to the ordering of the items in the in_app array, I would make no assumption that the items are in chronological order. I would say the same holds true for the contents of the latest_receipt_info section. A developer made this assumption, and early last year encountered the situation that the second to the last item in the in_app array was the most current auto-renewing subscription item.


In addition, if the user contacts Apple Care, requests a refund, and the request is approved, the cancellation_date field appears in the corresponding in-app purchase item which was refunded. This will normally be for a non-consumable item or for the auto-renewing subscription item for the period which was refunded. This will appear in both the in_app array item, and in the latest_receipt_info item.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

1) "the items in either section are always chronological" - this is not my experience. I do not recommend relying on the order being preserved.

2) the limit of 6 renewals for an autorenewable is well documented.

Btw, not sure if you noticed the radar (http://openradar.appspot.com/28864177) attached to the topic on this thread: https://forums.developer.apple.com/message/142334#142334 . Apparently, Olaf indicates that Apple had contacted him... the "latest_receipt" is valid for /verifyReceipt and documentation is wrong.

Apple, let's get the documentation fixed asap...this is wasting a lot of developer's time on such a simple little edit. As it deals with money, we are naturally concerned that what our designs are bonified so we and you get paid for services rendered. Thank you!

Thank you PBK! I see here and amongst many other threads you've been very active in this topic. The threads have been informative. Appreciate it!


A. Perfect. My further testing validates this as well. In the case where there is a difference in items between "in_app" and "last_receipt_info", it seems that server-side should update the archived receipt with the "last_receipt". Furthermore, it also would appear the items in either section are always chronological where the last item with an "expires_date" in "last_receipt_info" would be the active (or final) subscription.


B. When a user demands money back, my understanding is that the "last_receipt" would contain "cancellation_date" instead of a receipt. Is this your understanding too? Is there anyway to test this?


As I'm testing, I'm getting expected results from /verifyReceipt for the first 6 auto-subscriptions in the sandbox and old receipt produces "last_receipt_info" with renewed subscriptions. However, after 6 subscriptions, the sandbox acts like each purchase is a consumable and no longer automatically renews.


Italso seems that downgrades and upgrades are not entirely working in the sandbox. In my UI, I provide subscription options for customers to buy, upgrade, and downgrade.


For upgrades, it's successful. The upgrade is taking immediate effect although the prior subscription being overriden's expiration date is unaltered.


For downgrades, it fails in the SKPaymentTransactionObserver with the localized error "Cannot connect to iTunes Store" everytime.


I added this information to an old thread in Sept 2016 on this topic that had no response (https://forums.developer.apple.com/message/177893)

A. The receipt you send is old and the information returned for that receipt will never change - except for the latest_receipt_info and latest_receipt fields. You need to do #7.


B. #7 I believe. Note that when a user stops a subscription that does not generate a cancellation_date. A cancellation_date is generated only when the user demands money back from their subscription. Stopping a subscription stops new entroies with new expires_date(s).

A lot going on in this thread. The documentation is dated and a bit confusing. The question originally raised by PBK is currently being satisfied by NetFlix. My Netflix subscription is through iTunes Auto-Renewal. I am able to access NetFlix from any device, Apple and non-Apple, and browsers. This would suggest that server-side validation to iTunes of a receipt should be capable of informing the server of renewed, expired, and cancelled receipts without an Apple device being required to renew a receipt. From Rich's last post, I'm reading that the following would be proper validation of an auto renewing receipt:


1. Customer purchases an auto-renewing subscription

2. Apple device receives confirmation and receipt

3. App sends receipt to App's server backend for storage and continuing validation

4. App server sends receipt for validation to iTunes

5. iTunes confirms validity of the receipt, return JSON response

6. JSON response contains in_app array with purchased products. Empty array indicates no purchased products.

7. If purchased product is an auto-renewing subscription, then check the "latest_receipt" and "latest_receipt_info" fields for valid renewal


Questions:


A. Will the iTunes validation response update the in_app "expires_date" for auto-renew subscriptions? Or, do we need to verify renewal as in step #7?


B. Will the iTune validation response update the cancellation_date? If not, then how does NetFlix ensure valid subscriptions when a user may have not accessed NetFlix services from the Apple product but from a browser or other non-Apple device?