How to detect and verify a renewal for an auto-renewable subscription?
My experience. Let's assume, we always send initial receipt to Apple's server.
In any case, you'll get JSON with at least two fields: status
(no comments) and receipt
(information about receipt that you've send).
Additionally to that:
1) If the subscription is still active, you'll additionally get latest_receipt
(base64-encoded string) and latest_receipt_info
(information about that receipt).
2) If the subscription is already expired, you'll additionally get latest_expired_receipt_info
(information about last renewing receipt). Yes, you get only information about it, no base64-encoded string.
And yes, AFAIK, that's not documented anywhere. Hope that helps.
Nikolay Dyankov
Updated on July 16, 2022Comments
-
Nikolay Dyankov almost 2 years
So I have setup an auto-renewable subscription for my app with a period of 1 month, which equals 5 minutes or so in the sandbox. In the client app I subscribe, send the receipt to my server, it gets verified and I put a record in my database that this user has a subscription.
My question is how do I check if this subscription has been renewed? I have read the docs and can't figure out what should I do.
Here is where I am so far:
- The initial receipt that gets sent to my server is verified with a status
0
, great. I also getlatest_receipt
, which I replace in my database with the oldest receipt. - After 6 minutes when I try to verify the
latest_receipt
, I get status21006
(expired receipt) and this:
{ receipt: { original_purchase_date_pst: '2013-08-06 11:58:04 America/Los_Angeles', unique_identifier: '------------', original_transaction_id: '----------', expires_date: '1376129825000', transaction_id: '------------', quantity: '1', product_id: 'subscription', item_id: '--------', bid: 'com.--------', unique_vendor_identifier: '---------', web_order_line_item_id: '---------', bvrs: '2.0', expires_date_formatted: '2013-08-10 10:17:05 Etc/GMT', purchase_date: '2013-08-10 10:12:05 Etc/GMT', purchase_date_ms: '1376129525000', expires_date_formatted_pst: '2013-08-10 03:17:05 America/Los_Angeles', purchase_date_pst: '2013-08-10 03:12:05 America/Los_Angeles', original_purchase_date: '2013-08-06 18:58:04 Etc/GMT', original_purchase_date_ms: '1375815484000' }, latest_expired_receipt_info: { original_purchase_date_pst: '2013-08-06 11:58:04 America/Los_Angeles', unique_identifier: '-------', original_transaction_id: '-', expires_date: '1376129825000', transaction_id: '-', quantity: '1', product_id: 'subscription', item_id: '-', bid: 'com.-', unique_vendor_identifier: '--', web_order_line_item_id: '-', bvrs: '2.0', expires_date_formatted: '2013-08-10 10:17:05 Etc/GMT', purchase_date: '2013-08-10 10:12:05 Etc/GMT', purchase_date_ms: '1376129525000', expires_date_formatted_pst: '2013-08-10 03:17:05 America/Los_Angeles', purchase_date_pst: '2013-08-10 03:12:05 America/Los_Angeles', original_purchase_date: '2013-08-06 18:58:04 Etc/GMT', original_purchase_date_ms: '1375815484000' }, status: 21006 }
The second element in the array used to be
latest_receipt_info
, but now it'slatest_EXPIRED_receipt_info
. Here is what the docs say:In addition to the receipt_data field, the response may also include two new fields. If the user’s subscription is active and was renewed by a transaction that took place after the receipt your server sent to the App Store, the
latest_receipt
field includes a base-64 encoded receipt for the last renewal for this subscription. The decoded data for this new receipt is also provided in thelatest_expired_receipt_info
field. Your server can use this new receipt to maintain a record of the most recent renewal.So if the sub has been renewed since my server last checked, the decoded receipt for the renewal should be in
latest_expired_receipt_info
. In that object theexpires_date
is the same as the original receipt'sexpires_date
.What the hell? I just want to check if the sub is active. Can anyone explain in simple words how do I do that?
Thank you!
- The initial receipt that gets sent to my server is verified with a status
-
Nikolay Dyankov over 10 yearsAnd the immediate question - why doesn't the sandbox auto-renew the subscription? Or how do I renew it myself? Right now the receipt expires after 5 minutes and that's all. I need to test my code somehow.
-
Alexandr Paliy over 10 yearsIn sandbox, you are working with test accounts. You can't use test account to log in to iTunes and disable auto-renewing of your subscription. To let you test the situation, when your auto-renewable subscription becomes expired and inactive, Apple is doing only 5 renews in sandbox (i.e. you have initial transaction and 5 renews after it -> the total subscriptions queue' length is 6 times your subscription length). This will refresh after 8 hours. Or you can use other test account.
-
Nikolay Dyankov over 10 yearsOk, I figured it out. Here is a simpler explanation: stackoverflow.com/questions/8033673/…
-
Nikolay Dyankov over 10 yearsBasically, I just need to verify the initial receipt. That answers my question.
-
Cmag over 9 yearsSo in Sandbox, how do you get the receipt to expire?
-
uem almost 9 years@Cmag The subscription expires after a couple of automatic renewals, usually after 5 renewals. That way you can test both cases. Also note that the test subscription duration is way shorter than the actual duration: developer.apple.com/library/mac/documentation/…
-
Yohan over 7 years@AlexandrPaliy I have a query what will happen to the main receipt when he cancels and activates the subscription again? Whether new receipt will be generated or what will happen?
-
zirinisp almost 7 yearsUnbelievable how Apple has turned a simple subscription service to rocket science for developers!!
-
Ankur Patel almost 7 years@NikolayDyankov In sandbox test account auto-renewable subscription successfully excuted ( initial transaction and + 5 renews after it ) but after that i can not get latest_expired_receipt_info so how I can validate that auto-renewable subscription is expired In Response I get status,environment,receipt,latest_receipt,latest_receipt_info I did not get latest_expired_receipt_info
-
TomSawyer over 5 years@AnkurPatel This answer is longer valid, since
latest_expired_receipt_info
is only for iOS6. -
Larry Lo over 4 yearschecking
latest_receipt_info
instead ?