Validation of approach for in-app recurring subscriptions

Hi there,

We are retro-fitting recurring subscriptions into our system and would like some validation of our approach. We've done a bit of sleuthing around the docs and forums and have not found a solution close to ours.

Overview

Initial purchase

Since we need to associate an in-app product with a specific user, we have chosen to send the receipt to our server for verification. This way, we will be able to extract the user information through the authenticated call it makes. Once we have this, we will verify the receipt and if successful, grant the user access to the subscription they purchased. We will also store the TransactionId retrieved from the receipt.

Subscription End

We are relying on the App Store Server notification to send us a webhook call at the exact moment a subscription is no longer valid (notificationtype == CANCEL??). Using the autorenewproductid and originaltransactionid contained within the notification payload, we will find and disassociate the subscription from the user.

There are some questions that have arisen regarding this approach, primarily due to the inability to find the appropriate documentation.

Questions

1. We have a Staging and Production environment and would like to verify that the App Store Notifications are being processed correctly before reaching Production. How do we configure the App Store Notifications to send notifications to the correct environment depending on whether the subscription was purchased using a TestFlight build of the app vs a Release version of the app?

2. We would like verification that the App Server Notification with a notificationtype == CANCEL or REFUND is sent at the exact moment a subscription is no longer being paid for versus having to poll Apple on a regular basis to verify whether a subscription is still valid.

3. Is there a way to send an internal transaction identifier to Apple at the time a subscription is purchased and have this same identifier quoted back to us at the time of CANCEL or INITIAL
BUY?

4. Within the receipt verification step, is there an attribute that is returned that will identify that the subscription is no longer valid? Is this attribute called "expiration_intent"?

5. If we verify the receipt in this way, what is preventing the receipt data from being replayed by a different user by the same user after the initial subscription has lapsed? Will the verification endpoint return the current state of the subscription?

I realize these are a lot of questions and I apologize if there is documentation out there which addresses them which I have not been able to find.

Any help would be greatly appreciated.

Replies

In response to your questions

Q1. How do we configure the App Store Notifications to send notifications to the correct environment depending on whether the subscription was purchased using a TestFlight build of the app vs a Release version of the app?
A. The same server will be sent App Store notifications for both the production and sandbox environments. When a notification is received, there is an "environment" field which will indicate "Sandbox" or "Production". The instructions for setting up the server are documented at <https://developer.apple.com/documentation/storekit/in-app_purchase/subscriptions_and_offers/enabling_server-to-server_notifications>

Q2. We would like verification that the App Server Notification with a notificationtype == CANCEL or REFUND is sent at the exact moment a subscription is no longer being paid for versus having to poll Apple on a regular basis to verify whether a subscription is still valid.
A. I'm aware that the app will be sent the CANCEL and/or REFUND notification, but I'm not aware as to the timing of these events. A CANCEL notification is issued in the case that a subscription upgrade occurs ( this will be followed by the INTERACTIVERENEWAL notification). Not sure whether this is a good test, but it is a way to trigger the CANCEL notification. For a REFUND notification, I suggest an API enhancement request submission.

Q3. Is there a way to send an internal transaction identifier to Apple at the time a subscription is purchased and have this same identifier quoted back to us at the time of CANCEL or INITIALBUY?
A. This is not supported - here again, this would be an API enhancement request.

Q4. Within the receipt verification step, is there an attribute that is returned that will identify that the subscription is no longer valid? Is this attribute called "expiration
intent"?
A. The "expirationintent" is present in the "pendingrenewalinfo" receipt section when the associated productid has expired.

Q5. If we verify the receipt in this way, what is preventing the receipt data from being replayed by a different user by the same user after the initial subscription has lapsed? Will the verification endpoint return the current state of the subscription?
A. I'm unclear what you are asking in the first sentence. An appStoreReceipt is signed by Apple and can only be decrypted by the verification endpoint. Associated in the appStoreReceipt is information which Apple can match to a user account. For auto-renewing subscriptions, once the receipt is validated, the verification endpoint will detect whether there is an auto-renewing subscription item, and return the latest information regarding the subscription item for the user account.

rich kubota - rkubota@apple.com
developer technical support CoreOS/Hardware/MFI