StoreKit: Re-purchasing a refunded non-consumable

How should an app validate the purchase of a non-consumable product that was previously refunded? Assume validation is done only by local analysis of the IAP receipt (for maximum security).

StoreKit tests (using Xcode 12.4 with a 14.4 device simulator) suggest the IAP receipt remains in its refunded state and shows no trace of the latest purchase date. So the app blocks content.

Is this normal? Does this happen in the production environment also?

Receipt state after re-purchasing:
• 1703 (transaction ID): Shows the ID of the first purchase
• 1704 (purchase date): Shows the date of the first purchase
• 1712 (cancellation date field): Shows the refund date

Thanks!

I'm having the exact same issue. It would be good to know if you figured this out.

Is this purely an Xcode issue with how the test environment creates the test receipts?

I've written my code to check for multiple IAP receipts for the same product (in the case of a purchase-refund-purchase cycle) but judging by the fields present it seems like maybe the receipt for the non-consumable IAP gets updated with the latest purchase ID and dates. This would suggest the right thing to do would be to check the cancellation date against the purchase date.

Have you tried this in a production environment?
@Gops90 : No, the IAP code has not been tested in the production environment. 

The validation logic for each IAP receipt is as follows: if the cancellation date (1712) is newer than its purchase date (1704), then the content is blocked.

For the purchase-refund-purchase scenario (in the Xcode test environment), there is no second IAP receipt. I would expect the original IAP receipt to be updated to something like:
• 1703 (transaction ID): Shows the ID of the second purchase
• 1704 (purchase date): Shows the date of the second purchase
• 1712 (cancellation date field): Shows the refund date

This may well be an Xcode test issue. I also found that Ask-to-Buy can trigger multiple IAP receipts (and customer charges?) for the same non-consumable.

StoreKit: Re-purchasing a refunded non-consumable
 
 
Q