swiftin-app-purchasesubscriptionstorekitreceipt-validation

Auto-Renewable Subscription never expires in Sandbox


I have successfully implemented auto-renewable subscriptions (In App Purchase) in my app using StoreKit. I am still in development mode so I am using sandbox user for testing. Once I subscribe to the monthly subscription using the sandbox environment I can have access to the "premium content". I use UserDefaults to indicate that a user has purchased a product. I have not implemented receipt validation.

My problem is that the subscription never expires since I can have access to the premium content anytime I want, way after the expiration of the subscription i.e. max. 30 minutes given that renewals happen at an accelerated rate in testing mode (6 * 5minutes)

My question: are auto renewable subscriptions expiring if we store the product purchased in userDefaults ? should I have to use receipt validation to have the auto renewable subscription expired?

private func productPurchaseCompleted(identifier: ProductID?) {
        guard let identifier = identifier else { return }

        purchasedProductIDs.insert(identifier)
        UserDefaults.standard.set(true, forKey: identifier)
        productPurchaseCompletionHandler?(true, identifier)
        clearHandler()
    }

Solution

  • The only way to determine if the subscription is still active for the user is through receipt validation.

    1. The best way to do this is to store the receipt file on your server and periodically refresh it with Apple's /verifyReceipt endpoint to see if anything has changed. (See iOS Subscriptions Are Hard for more detail).

    2. If you are just looking for something quick and dirty, you can do the validation locally, and store the expiration date of the subscription in User Defaults. On launch check if the device time is before the expiration date. You'd only need to revalidate if the device time is after the expiration date to check if the subscription renewed.

    The second approach is an insecure, non-scalable way to work with subscriptions, but it would "work" for a little side project. The recommended way is through server-side receipt validation and status tracking mentioned in #1.