youknowone / itunes-iap

Apple iTunes In-app purchase verification tool
http://itunes-iap.readthedocs.io
Other
136 stars 50 forks source link

receipt.last_in_app is not the latest purchase #29

Closed jeffjvick closed 7 years ago

jeffjvick commented 8 years ago

I'm not sure if this issue is an Apple problem or my my incorrect interpretation of how the receipt validation process works or a shortcoming of itunes-iap.

If I send a receipt to get validated and get back a response and then do a response.receipt.last_in_app I get the last purchase in the in_app array contained in the receipt. The problem is that this is not the latest purchase if the receipt hasn't been refreshed on the device. Since I'm handling subscriptions I will be periodically checking the receipt from the server and do not have the ability to refresh the receipt (at least I don't think I can).

The latest purchase information is however contained in 'latest_receiptinfo' of the receipt and Pablo Rivera pointed out how to obtain this in his wiki post https://github.com/youknowone/itunes-iap/wiki/Getting-the-receipt-with-the-latest-expiration-date by doing `response..get('latest_receipt_info')` you can get access to this information. However this is just the raw dictionary of the data and then I need to parse it manually which is all nicely done for the in_app part by itunes-iap.

So my question is, when validating a receipt, is there a way to always get the last purchase history in the in_app part or if not, could itunes-iap be changed in a way to more natively access 'last_receipt_info'? I've already worked around this but I'd like to know if I'm doing something wrong or there is an easier way to do this.

jeffjvick commented 8 years ago

Note: I just tested and found if I resend the receipt found in response.latest_receipt to get validated then the result that comes back will have all of the latest purchases in the in_app array. This seems like an unnecessary second step though.

If this isn't required then having itunes-iap have native access to 'last_receipt_info' would be helpful.

alej0varas commented 7 years ago

I"m having the same issue. My work-around is to sort in_app using original_purchase_date_ms like this.

sorted(response.receipt.in_app, key=lambda x: x['original_purchase_date_ms'])[-1]

youknowone commented 7 years ago

Thanks @alej0varas. I will regard it for backward compatibility. For now, by apple's reference, it seems processing only last receipt has potential risk to leak unprocessed receipts when they purchases multiple times in a row. I recommend to process all of the receipts everytime when you got it.

aehlke commented 6 years ago

@youknowone your quickstart guide uses the >>> print response.receipt.last_in_app.product_id pattern - maybe document the actual recommended approach there?