3

I am working on a client/server application which uses Apples IAP and StoreKit framework to purchase a subscription.

What we would like is for the client (iPhone or iPad) to make the initial subscription purchase with apple through their iTunes account using StoreKit framework and then pass of the receipt to our server, which will validate it and then update the users account status. We'd also like the server to be responsible for managing the status of the subscription (check for auto-renew, cancellation etc..) This is all using iOS 7 style appleReceipts, rather than iOS 6 style transaction receipts which are deprecated currently.

Apple's docs say to POST to the following URL to validate a receipt in the sandbox along with the receipt and the secret code

https://sandbox.itunes.apple.com/verifyReceipt

Up to this point .. everything works as it should.

Where things get confusing to me is in the response. Apple's docs say that the response should have up to 4 fields. If you are validating an iOS 7 style app receipt then you should only expect the first 2. If it's an iOS 6 style subscription transaction receipt then you should expect to see all 4.

1) status (0 for valid, some error code otherwise)

2) receipt (a JSON representation of the receipt that was sent)

3) 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.)

4) latest_receipt_info (same as above in JSON format)

Problem 1: I am seeing all 4 even though I am validating an iOS 7 style app receipt. The docs say that shouldn't be happening.

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

Problem 2: We'd like to have the server handle maintaining the user subscription status by polling this API with the original app receipt that the client passed after its initial purchase. The latest_receipt_info field does seem to contain a continually updated list of transactions, while the receipt field is a copy of the original with no updated transaction information.

My Question: It seems then that the only way the server can get information about updated transaction is by looking at the latest_receipt_info or latest_receipt fields, but those fields are not supposed to be present in the response according to the documentation.

Is this an error in the Apple documentation? Or is the only way to get the latest set of transaction is to have the client send updated AppReceipts when it gets notified by the SKPayementTransactionObserver?

EDIT -- adding steps taken and some code as per comment below.

1) Making a purchase of a autoRenewSubscription product using SKPaymentQueue:

 SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:product];
    payment.applicationUsername = [self hashedValueForAccountName:[UserAccount sharedInstance].subscriberKey];
    [[SKPaymentQueue defaultQueue] addPayment:payment];

2) When the payment is completed I get a call back through my SKPaymentTransactionObserver and send the file at the following URL:

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];

to my remote server.

3) I'm using the following python code to validate the receipt

import itunesiap
import base64

file = "/path/to/receipt/sandboxReceipt"
f = open(file)
encoded = base64.b64encode(f.read())

with itunesiap.env.current().clone(use_sandbox=True):  # additional change for current environment.
    response = itunesiap.verify(encoded,"mysecretkey")

The response contains a dictionary. The dictionary has the following fields

"latest_receipt" = base64 encoded receipt here
"latest_receipt_info" = a JSON representation of the latest receipt
"receipt" = a JSON representation fo the receipt I sent for verification

The Docs say that the first 2 fields are

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

  1. Why are they showing up here, since I was validating an iOS 7 style app receipt?
  2. If these fields aren't supposed to be present, how do I get the latest transaction information?
ljk
  • 488
  • 1
  • 5
  • 11
habs93
  • 105
  • 2
  • 9
  • Please show code of what you're seeing and trying. – sschale Mar 10 '16 at 01:05
  • @sschale I've edited the original post with some example code. Thanks – habs93 Mar 10 '16 at 02:17
  • The wording in Apple's docs is ambiguous. _Only returned for iOS 6 style transaction receipts **for auto-renewable subscriptions**_. This means the field is always present for iOS 7 receipts using `appStoreReceiptURL` but only present for deprecated transaction style receipts that are for an auto-renewing subscription. i.e. they do not show up on iOS 6 transaction receipts if the purchase isn't a subscription. – Marc Greenstock Mar 10 '16 at 04:48
  • @MarcGreenstock thanks for your comment, that's helpful – habs93 Mar 10 '16 at 04:54
  • @MarcGreenstock if you post your comment as an answer I'll mark it as accepted – habs93 Mar 10 '16 at 05:09
  • To be honest, I don't agree with the accepted answer. _Only returned for iOS 6 style transaction receipts..._ to me implies that for iOS 7+ receipts these fields should not be there - and yet there they are. – winna Jul 26 '16 at 13:58

2 Answers2

5

The wording in Apple's docs is ambiguous. Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions. This means the field is always present for iOS 7 receipts using appStoreReceiptURL but only present for deprecated transaction style receipts that are for an auto-renewing subscription. i.e. they do not show up on iOS 6 transaction receipts if the purchase isn't a subscription.

Marc Greenstock
  • 11,278
  • 4
  • 30
  • 54
  • To be honest, I don't agree with this accepted answer. _Only returned for iOS 6 style transaction receipts..._ to me implies that for iOS 7+ receipts these fields should not be there - and yet there they are. There needs to be some real clarity on this issue. Does anyone have some verifiable information regarding how this works? – winna Jul 26 '16 at 14:00
  • @winna This is why I said the docs are ambiguous, i.e. It can be interpreted in two or more ways. The only *official* documentation is the one provided from Apple, I have submitted a bug report in the past to have them provide clarity. Documentation is not always a reliable source of truth, the only truth is what you can observe; the *latest_receipt* and *latest_receipt_info* fields do exist on Grand Unified Receipts, thereby my interpretation is correct. – Marc Greenstock Jul 26 '16 at 14:39
  • I'm stuck with the same issue, I, like @winna, don't think it's the correct interpretation. I think they still send it for BC breaks issues, but it can disappear at any time. One Apple engineer seems to tell the same : "The latest_receipt field [...] is still the iOS 6 style [and] is deprecated as of iOS 7. [...] If there is a desire for offline support of auto-renewing subscriptions, this is an enhancement request for iTunesConnect to implement." (source : https://forums.developer.apple.com/message/156580#156580) – deathpote Sep 15 '16 at 13:38
  • @deathpote I read link you sent and it just clouds the issue even more. In a follow up by Rich he says "The focus of my response was not for the content of the receipt, instead that one should not rely on the validation support provided to this receipt to be similar to that of the iOS 6 transactionReceipt". As far as I can gather from his statement, `transactionReceipt` and `applicationReceipt` validations don't work the same. Which when you go back to the top of the thread `latest_expired_receipt_info` is mentioned, which only is returned when validating an expired `transactionReceipt`. – Marc Greenstock Sep 15 '16 at 16:35
  • 1
    @deathpote I've added a request for clarification https://forums.developer.apple.com/message/179326 – Marc Greenstock Sep 15 '16 at 17:17
  • 1
    @deathpote. I think we all agree the docu sucks :) For that reason, my company got in contact with Apple Support. After 2 weeks of back and forths providing sample requests and an App, the Apple Rep admitted that the documentation is not only ambiguous but also wrong. We also got details saying that despite the iOS 6 data being deprecated, there is no chance of it being removed within at least the next 12 months - this came from the iTunes Engineering Team directly (supposedly). – winna Sep 17 '16 at 13:34
  • Thanks posting and sharing this thread @MarcGreenstock, it's usefull ! could you update your answer with a summary of it ? – deathpote Sep 19 '16 at 07:27
  • @deathpote I have a follow up question to PBK that is currently being moderated (posted on the 16th). I'm still not 100% clear on the situation. PBK has done his best to share his knowledge, but we need an official source to know for certain what the situation is, the most creditable answers will still be speculation unless they can be attributed. – Marc Greenstock Sep 19 '16 at 07:46
  • @winna I re-read my reply to you and I apologise for sounding snarky. I'll continue to push for an answer from Apple so we can all be clear on what the situation is. – Marc Greenstock Sep 19 '16 at 07:56
  • @MarcGreenstock I just got new from Apple on this subject, if you're still interested in the subject : `all receipts containing auto-renewable subscriptions now include real-time information about the status of the customer's subscription.` including `Subscription Auto-Renew Status: Indicates if a customer's subscription will renew at the end of the current subscription period.` (source : https://itunespartner.apple.com/en/apps/news/45333106) PS: I didn't looked in the API, I don't know if it's already available – deathpote Jul 19 '17 at 16:41
  • latest_receipt documentation is updated and is now more understandable : `Only returned for receipts containing auto-renewable subscriptions. For iOS 6 style transaction receipts, this is the base-64 encoded receipt for the most recent renewal. For iOS 7 style app receipts, this is the latest base-64 encoded app receipt.` https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW4 – deathpote Jul 19 '17 at 16:50
  • 1
    @deathpote thank you. I think we can safely say the issue of ambiguity is resolved. `latest_receipt` and `latest_receipt_info` are here to stay. The updates to the API work well, I have tested and implemented in production and am really pleased with the extra detail. The status notification update webhook is awesome. I have purchase information even before the device sends the receipt to my API. – Marc Greenstock Jul 19 '17 at 20:00
0

You need to include "password" key in your JSON along with "receipt-data" when hit to validate the reciept and its value will be "shared secret key" that you can generate from itunes account. Refer third heading in this link for more detail. https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html