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?

Accepted Reply

The documents have been updated!!!!!!

Wonder of wonders, miracles of miracles - it's official - latest_receipt_info for iOS 7 receipts. And more, much more.


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


and notifications....

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html#//apple_ref/doc/uid/TP40008267-CH7-SW16

Replies

Which part of

>Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.

am I not understanding? These are receipts from [[NSBundle mainBundle] appStoreReceiptURL]. appStoreReceiptURL is an iOS7 method. If you are running iOS6 you cannot get these receipts. If these are "iOS 6 style transaction receipts" than what receipt is not "iOS 6 style transaction receipts"?

@Rich


You said "the Verifying Receipt PG does document that these fields are present in the 'Parse the Response' section".


The documenation in the "Parse the Response" section says:


latest_receipt

Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions. The base-64 encoded transaction receipt for the most recent renewal.


latest_receipt_info

Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions. The JSON representation of the receipt for the most recent renewal.


I thought:

iOS 6 style transaction receipt means transaction.transactionReceipt

iOS 7 style receipts means [[NSBundle mainBundle] appStoreReceiptURL]


Is this incorrect? If so, what do "iOS 6/7 style receipts" mean?

I apologize for the delayed response - I've been swamped with DTS incidents regarding StoreKit issues.


With regards to the documentation in the Receipt Validation PG - first let me apologize for previous statements which I have made indicating that the "latest_receipt" and the "latest_receipt_info" fields are deprecated. The iTunes Store Server engineers tell me that these fields are supported. The documentation in the Receip Validation PG is current, HOWEVER, there is a misunderstanding as to the terms iOS 6 style transaction receipt. This term applies only in the case that it contains information about an auto-renewing subscription. It indicates that when the "latest_receipt" field is revalidated, it will be processed much like the deprecated transactionReceipt field is/was. If you validate a saved transactionReceipt (it still works as far as know under iOS 10.x) if the auto-renewing subscription has renewed since the transactionReceipt was saved, the validation process will include the renewal information of the auto-renewing subscription item. This isn’t the case for the in_app array of the applicationReceipt (the iOS 7 style receipt). However since the latest_receipt and latest_receipt_info fields are a part of the applicationReceipt, if there is an auto-renewing subscription item in the in_app array, there will be a latest_receipt as well as a latest_receipt_info fields which will contain the latest renewal information for the auto-renewing subscription item.


This issue needs to be clarified in the Receipt Validation PG


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Rich,


You have just confirmed that:

>This (the validation process will include the renewal information of the auto-renewing subscription item) isn’t the case for the in_app array of the applicationReceipt (the iOS 7 style receipt)

But then you went on to write:

>However since the latest_receipt and latest_receipt_info fields are a part of the applicationReceipt,

1) Where is that written in the documents?

2) If it is not in the written documents, can we rely on that?

3) Note that the "latest_receipt" and the "latest_receipt_info" will have no newer information than is in that concurrent applicationReceipt. The question is - can the content of the "latest_receipt" field in an ApplicatinReceipt be sent to the Apple servers to be updated?

PBK,


You asked

>However since the latest_receipt and latest_receipt_info fields are a part of the applicationReceipt,

1) Where is that written in the documents?

Response - In the section "Parse the Response"

The response’s payload is a JSON object that contains the following keys and values:

And of course the description is misleading.

You then asked - can the content of the "latest_receipt" field in an ApplicatinReceipt be sent to the Apple servers to be updated?

Response - yes


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Rich,


Thanks for your help here.


Please correctly if I am wrong - what you are writing is that this wording is "misleading":

"latest_receipt Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions."

It should state:

"latest_receipt Only rReturned for as an iOS 6 style transaction receipts butonly for auto-renewable subscriptions."

OMG, this thread is hurting my brain. 😟


PBK, clearly the wording of the footnotes for latest_receipt and latest_receipt_info is missleading. It seems they are solely responsible for the major confusion about these fields on every post on the internet for this subject.


However, they are still being reported for iOS 7+ (applicationReceipt) style receipts with regards to auto-renewable subscription purchases. They are in the sandbox and they are in the real world (our app uses auto-renewable subscriptions and we receive these fields from the Apple verification server).


As you have said many times, these two footnotes make it sound like they should not be there. Rich seems to indicate otherwise however as does the contents of the actual receipts.


I _think_ the wording should really say "Only returned for iOS 6 style transaction receipts with for auto-renewable subscriptions." However, like you have reiterated many times, I'm still worried they may not exist at some point.


Case in point, we receintly received a receit from a user that when sent to the Apple verification server did not come back with a 'lastest_receipt_info' field in it. This caused our code to crash since we were expecting it and unfortunately the receipt data was lost so I can't replay it.


My question then for Rich is, did this receipt not contain a 'latest_receipt_info' field because the receipt didn't actually contain an auto-renwable subscription and was potentially the user trying to decieve us or was this some case where the Apple servers randomly didn't return this field? We are very worried now about losing subscription data due to this issue.

Lusta,


You asked - did this receipt not contain a 'latest_receipt_info' field because the receipt didn't actually contain an auto-renwable subscription.

Response - if there is no auto-renewing subscription item in the applicationReceipt, in the in_app array, then when the applicationReceipt is validated, there won't be either a latest_receipt field nor a latest_receipt_info field.


You asked - was potentially the user trying to decieve us or was this some case where the Apple servers randomly didn't return this field?

Response - if the verifyReceipt server processed the receipt, the contents of the receipt have been verified by the iTunes Store. There is now the question as to the JSON contents of the receipt. My statement above stands. If there is an auto-renewing subscription item in the in_app array, but there is neither a latest_receipt field nor a latest_receipt_info field, this would be a bug report. I would save the base64 encoded applicationReceipt to include with the bug report.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

Rich,


Hi, thanks for the quick reply. I appreciate it.


For your first reponse regarding: "did this receipt not contain a 'latest_receipt_info' field because the receipt didn't actually contain an auto-renwable subscription":

Unfortunately we do not have access to the receipt sent to us by the client (applicationReceipt) nor the contents of the in_app array from the validated response. When our server didn't find the 'latest_receipt_info' field it caused an error and none of the original receipt information was saved (we have since fixed that). We also were not checking for the in_app area since we assumed latest_receipt_info was sufficient. So unfortunately I can't answer your question. Am I correct though that for the case of auto-renewable subscriptions we should be using 'latest_receipt_info' and not 'in_app' to get the most current renewal / expiration information? Or will those two contain the same data?


For your second response regarding: "was potentially the user trying to decieve us or was this some case where the Apple servers randomly didn't return this field?"

I can say that no status error was returned from the Apple receipt validation as that part of code did pass so this was a valid receipt. But unfortunately it crashed right after that while trying to access the 'latest_receipt_info' field so I don't even know if the bundle id matched. What it sounds like from what you are saying though is that if an auto-renewalable subscription was in the receipt then there there should have been a 'latest_receipt_info' and 'latest_receipt' field. This seems to also answer PBK's original question, that these fields are indeed not depricated.


That would mean that one of three things happend:

  1. Fake receipt
  2. Bug on Apple's side
  3. The receipt we sent from the client hadn't yet had the purchase information added to it.


For #3 we grab the applicationReceipt after we receive a .Purchased tranasction from the SKPaymentQueue so I don't see why the receipt wouldn't include the purchase.


I'm leaning towards #1 as our backend is reporting the same number of subscriptions as Apple Analytics and if we dropped the ball I would assume Apple would report 1 more. Is there someone we can contact though to see what receipt we sent to the verification servers at this timestamp or see if a purcahse was made at this timestamp? I could used that to check the 'in_app' array. Or is there a way to download a list of all of our current active subscriptions? That would be helpful regardless.


Thanks,

Iusta

Rich wrote:

>My statement above stands. If there is an auto-renewing subscription item in the in_app array (added by PBK for clarity - in an iOS7 style receipt, not a transaction.transactionReceipt), but there is neither a latest_receipt field nor a latest_receipt_info field, this would be a bug report.


This is absolutely consistent and equally untrue. It is not a bug - it is expected behavior based on the documentation. If the field is present then that is an undocumented feature. Or shall I say, undocumented with the exception of Rich's posts on this forum - which, with all due respect, is not the same as "documented". The random absence of an undocumented feature is not a bug.


Why, oh why, doesn't Apple update its documents if this feature is reliable????? That is the bug here.


I am sorry that this thread is so long and hurts your head - but that's reality. Your 3 choices leaves out the possibility that Apple Engineers may sometimes not agree with Rich's assertion that an iOS7 Style receipt must contain these fields.

PBK, man, I think you are getting a little too worked over the semantics of this whole thing. The documents are just wrong or somebody thinks that wording is correct, which is even worse.

I have worked at companies the size of Apple and often the actual engineers writing code are not the ones writing the docs and may not even have any idea what the docs say. It sounds like Rich has reached out to someone connected with the docs so maybe they will get changed. If we all file bug reports regarding the wording of the docs that could help as well.

At this point I'm just going to assume the docs are either wrong or poorly worded and assume that these fields will always be there for auto-renewal subscription purchases. If I find another case of them missing I'm going to save the receipt so I can analyze it better. If the subscription is in the in_app array but these fields are not there I'm going to report it as a bug to apple. If it's not in the in_app array then I'm going to report it to apple as fraud.

Thanks for starting this thread, it has been helpful.

I recommend that you not rely on the persistence of this feature until it is documented correctly. You are welcome to ignore the documents in favor of Rich's interpretation (actually it is not an interpretation - it is an assertion that they are wrong) and I hope, for the sake of your users, that you and Rich are correct. However, the documents are very clear - this feature is documented as gone in iOS7 style receipts. That it persists for a few iOS versions is what always happens when a feature is removed. Good luck!

Hi Rich,

I appreciate the bravery of even posting here with the "Apple Staff" avatar and we all appreciate the help you've given us on this thread. In the same way that the map isn't the territory, the documentation isn't the intended contract.

My question is regarding the nature of the (intended contract for) receipt validation responses using the iOS7 receipt (applicationReceipt) for an auto-renewing subscription.

We've encountered some receipts whose application receipts return empty "latest_receipt_info" and "latest_receipt" fields. If the application receipt is not nil, we do not refresh the applicationReceipt after they make a purchase and only upload the receipt to our server (to verify with Apple) when the transaction has entered the purchased state. I have a few receipts handy that simply don't have the "latest_receipt" and "latest_receipt_info" fields when we get the validation response back. Does this mean that those users have, with 100% certainty, *not* purchased an auto-renewing subscription? Does that mean that the transaction entered the purchased state and, for one reason or another, the purchase didn't go through? Or, does that mean that we would need to explicitly refresh the application receipt on the client and re-upload that to our server to double check?

Essentially my question is this: "If a user has successfully purchased an auto-renewing subscription does that imply that the "latest_receipt" and "latest_receipt_info" fields will always be populated in the receipt validation response?"

I'm wondering if the absense of those fields suggests we need to force the client to perform an application receipt refresh request and then re-upload the receipt.

Best,

Stephen

A better approach is to follow the documentation. If you:


>only upload the receipt to our server (to verify with Apple) when the transaction has entered the purchased state.


then you can ignore the undocumented latest_receipt_info and latest_receipt fields and look at the well documented in_app field (an array of receipts) for a receipt with an expires_date in the future. The problem is that you can't reuse that same receipt each month to check to see if the auto-renewable subscription renewed. You must get a new receipt from the device, again: "when the transaction has enetered the purchased state."

You indicated that you've encountered the situation where the JSPN results of a validated applicationReceipt show an empty "latest_receipt" and "latest_receipt_info" fields. In this case, what was in the in_app array. I suspect that the in_app array was empty OR did not include an auto-renewing subscription item. Before an applicationReceipt is processed, there are no “latest_receipt” or “latest_receipt_info” fields. They are added by the iTunes Store verifyReceipt server, when it detects that there is an auto-renewing subscription item in the in_app array.

You asked - “. I have a few receipts handy that simply don't have the "latest_receipt" and "latest_receipt_info" fields when we get the validation response back. Does this mean that those users have, with 100% certainty, *not* purchased an auto-renewing subscription? Does that mean that the transaction entered the purchased state and, for one reason or another, the purchase didn't go through? Or, does that mean that we would need to explicitly refresh the application receipt on the client and re-upload that to our server to double check”

An empty in_app array indicates that you are working with a receipt where the iTunes Store has not recorded a purchase. The recommendation as per Tech Note 2413 “iAP FAQ”

<https:/

Indicate to the user that the receipt appears to need refreshing. If the user agrees, then the app issues the SKReceiptRefreshRequest and processes the refreshed receipt.

You also asked “Essentially my question is this: "If a user has successfully purchased an auto-renewing subscription does that imply that the "latest_receipt" and "latest_receipt_info" fields will always be populated in the receipt validation response?"

Yes - unless there is a problem with the verifyReceipt server.

I’ve had developer reports of the in_app array remaining empty after this refresh procedure. Assuming that this resulted after a valid purchase of an auto-renewing subscription in-app purchase, this becomes a bug report issue to be submitted to the iTunes Production Support team for investigation.

Also, if the in_app array does contain an auto-renewing subscription item, but there are neither “latest_receipt” nor “latest_receipt_info” fields, this is again a bug report issue. However, in this case, the iTunes Store server does indicate processing the in-app purchases referenced in the in-app array.

In the cases where the application is called to process a successful transaction, but is unable to validate that the purchase was actually made, the app should not call finishTransaction. This will leave the transaction as incomplete - to be processed another time when the transactionObserver detects it. In this case, when the user contacts Apple Care, AC can verify that the purchase is incomplete which lends credence to the fact that the user was charged but did not receive the contents.

To file a bug report - go the the Apple Developer Bug Report - <http:/

Make sure to include the application ID, as well as the base64 encoded applicationReceipt and the shared secret - so that the receipt can be manually validated.

Also add the statement “please check with Rich Kubota for bug report routing” - without this statement your bug report could be incorrectly assigned.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI