Auto-renewable subscription - confusion about source of truth

Apple's latest WWDC entitlement engine presentation is quite useful as far as converting receipt into subscription + entitlement data.

I am using it in conjunction with my own server verifyReceipt endpoint and store subscription data on server, along with original transaction id + user id.

First, terminology for below situations:
appuser = user login for my own app
appstore user = user login for iTunes / appstore

However, I am confused on a few things:

What should be the source of truth?

For entitlement engine to work, receipt must be sent to server. If appuser signs in on Device A, purchases product P, then signs in on Device B, no / empty receipt will exist on Device B.

Obviously, this appuser will download subscription data I stored on server during previous verifyReceipt call. Is this OK? How do I know if my server knows the truth about this appuser?

Should this be restoreTransaction flow, or simple REST call? If my server holds latest subscription data based on receipts, what should restoreTransaction do?

Also, if appuser remains the same, but appstore user changes (different itunes id) - what is the way to tackle?

1 - Is Apple OK if I allow access to purchased content via this appUser but different appstore user who never purchased it?

2 - Vice versa, if appuser is altered, but appstore user remains the same, what is correct entitlement?

Does Apple has any say on above 2 scenarios or is it just me who gets to decide?

Probably too many questions, but it is bit confusing in conjunction with storekit callbacks (transaction observers etc) and I am wondering if there is well-established universal approach other developers are following....

Accepted Reply

Hi Vividcode,

Thanks for the feedback! Glad to hear you found the session useful.

 Let's see if I can do my best to answer your questions:

For entitlement engine to work, receipt must be sent to server. If appuser signs in on Device A, purchases product P, then signs in on Device B, no / empty receipt will exist on Device B. 

Storing the receipt on your server is recommended so that you can refresh your backend data or update entitlement info on your backend when changes occur via App Store Server notifications.

But you are correct, you will want to associate this with an appuser (using the terminology you menitoned), so that you can provide login across devices and off-platform.

When an appstore user (user login for iTunes / appstore) downloads the app on a different device, the receipt will also contain their purchases. If it is up-to-date, it should contain the same in-app subscription transactions as the other device. 

Obviously, this appuser will download subscription data I stored on server during previous verifyReceipt call. Is this OK? How do I know if my server knows the truth about this appuser?

You should use the Apple receipt as the as the source of truth for the user so that the user is always able to get the access associated with the receipt they are presenting. 

Should this be restoreTransaction flow, or simple REST call? If my server holds latest subscription data based on receipts, what should restoreTransaction do?

Are you referring to the StoreKit restore or something else? You will need to support restoring transactions with StoreKit so that the user can receive the service reflected by the transactions within the receipt. If your server does not have a receipt or the data is incorrect, you will need to support a flow where the user can restore their purchases on device. After the receipt is refreshed on deviced, you can send that to your server to determine which content should be unlocked.

1 - Is Apple OK if I allow access to purchased content via this appUser but different appstore user who never purchased it? 

Yes, this is allowed. Make sure you aren't accidentally replacing the receipt containing no purchases with the one that does have the active subscription.

2 - Vice versa, if appuser is altered, but appstore user remains the same, what is correct entitlement?

You may choose to have a premium level of service that supports multiple users for one subscription or require that a subscription only be associated with a single account at a time. If you so choose, you can prompt the user to sign in with the App Store account that has the active subscription in order to access the subscription content.

Replies

Also relevant is the ideal state management with respect to promo offers.

Current entitlement engine provides offers as part of receipt verification - in the process it might be bit time consuming call storing subscription + offer data on back end while verifyreceipt endpoint has just returned from apple.

Also a concern would be, how to reset promo offer pending status on the server?
Code Block
promotional_offer_id
I know the above tells about it within the receipt.
This means that all such operations have to be tied up with verifyReceipt?
Hi Vividcode,

Thanks for the feedback! Glad to hear you found the session useful.

 Let's see if I can do my best to answer your questions:

For entitlement engine to work, receipt must be sent to server. If appuser signs in on Device A, purchases product P, then signs in on Device B, no / empty receipt will exist on Device B. 

Storing the receipt on your server is recommended so that you can refresh your backend data or update entitlement info on your backend when changes occur via App Store Server notifications.

But you are correct, you will want to associate this with an appuser (using the terminology you menitoned), so that you can provide login across devices and off-platform.

When an appstore user (user login for iTunes / appstore) downloads the app on a different device, the receipt will also contain their purchases. If it is up-to-date, it should contain the same in-app subscription transactions as the other device. 

Obviously, this appuser will download subscription data I stored on server during previous verifyReceipt call. Is this OK? How do I know if my server knows the truth about this appuser?

You should use the Apple receipt as the as the source of truth for the user so that the user is always able to get the access associated with the receipt they are presenting. 

Should this be restoreTransaction flow, or simple REST call? If my server holds latest subscription data based on receipts, what should restoreTransaction do?

Are you referring to the StoreKit restore or something else? You will need to support restoring transactions with StoreKit so that the user can receive the service reflected by the transactions within the receipt. If your server does not have a receipt or the data is incorrect, you will need to support a flow where the user can restore their purchases on device. After the receipt is refreshed on deviced, you can send that to your server to determine which content should be unlocked.

1 - Is Apple OK if I allow access to purchased content via this appUser but different appstore user who never purchased it? 

Yes, this is allowed. Make sure you aren't accidentally replacing the receipt containing no purchases with the one that does have the active subscription.

2 - Vice versa, if appuser is altered, but appstore user remains the same, what is correct entitlement?

You may choose to have a premium level of service that supports multiple users for one subscription or require that a subscription only be associated with a single account at a time. If you so choose, you can prompt the user to sign in with the App Store account that has the active subscription in order to access the subscription content.
thank you for the answers!

I have small doubt - As for your answer about scenario where 2 app store IDs are associated with single appuser.

Terminology:
App user is U.
App Store User A on device D1 - purchases product P. A's receipt is stored on my back end server.
U signs in on different device D2 with App Store User B (same app user U is logging into the app)

Upon login, U knows that he has purchased product P from back end server. But U has no knowledge which app store user did purchase. So, he is prompted to restore, before unlock on newer device. U gets B's receipt (empty), not A's receipt.

So B's receipt will also be stored on the back end server, associating it with user U.

But since U has paid for the content already(through App store user A), it does not matter to consider B's receipt. It will just lie on the back end for the records.

Unlock on D2 for P will happen because server knows U has purchased P. App store's truth about B will not matter at all. So effectively, restore did nothing on D2.

Is this correct?

(This assumes that every receipt is stored on the back end server as your answer suggests that too)