0
votes

I'm implementing a monthly and yearly auto-renewing subscription alongside several non-consumable IAPs. After quite a lot of documentation and SO reading, I've landed on the following conclusions:

  1. The app receipt at Bundle.main.appStoreReceiptURL only needs to be refreshed if missing or invalid. It does not need to be refreshed if there is a file present at Bundle.main.appStoreReceiptURL. (Source: "Use [SKReceiptRefreshRequest] to request a new receipt if the receipt is invalid or missing")

  2. The initial purchase of a non-consumable or auto-renewing subscription product can be detected using paymentQueue(updatedTransactions:) only. No need to verify (i.e., decode) the receipt at this time, as I'm not worried about significant fraud.

  3. Receipt verification on each launch of the app is sufficient to detect expired or auto-renewed subscriptions via the latest_receipt_info->expires_date_ms and receipt->request_date_ms fields. (This information is used to a) revoke the user's subscription privileges if their subscription has expired, and b) to update the "Subscription renews on [date]" text in the app.)

  4. Receipt verification on each launch of the app is sufficient to detect cancelled subscriptions. This will be detected via the pending_renewal_info->auto_renew_status fields. (This information is used to display "Subscription expires on [date]" text in app).

  5. Restore purchases (SKPaymentQueue.default().restoreCompletedTransactions()) can be used to restore non-consumable purchases, but isn't sufficient to restore subscriptions (no expiry date information). Receipt verification on launch is enough to ensure subscriptions are restored. (That said, though redundant, a "restore purchases" button press by the user can also trigger a receipt verification pass.)

  6. The "active subscription" is found via pending_renewal_info->auto_renew_product_id, and represents their most recent subscription selection. This is used to display the price/duration of the next subscription period to the user.

The implicit assumption in 3 and 4 is that the call to verifyReceipt will retrieve any new information about the subscription. In other words, if a) a monthly subscription starts today, and b) no receipt refresh is manually performed at any point afterwards, then c) verifying the receipt in just over a month will still give me an updated latest_receipt_info->expires_date_ms value.

Are there any conceptual or practical oversights here?