Auto-renewing subscription receipt persistence and iTunes user change

I am witnessing the following:

• User A purchases my auto-renewing subscription

• User A logs out of iTunes & App Store

• User B logs in, receipt is still there on next app launch and exactly the same, so he still uses User A’s subscription.

Will the receipt be ever updated to show User B’s subscription state? How do we handle this case? User A could login to multiple devices, restore purchases and then log out.


I have not found any official reference as to when the receipt is actually updated on device. I have found blog posts claiming that:

• A receipt is issued for a specific version of an application and a specific device.

• A receipt is issued each time an app installation or update occurs.

• A receipt is issued each time a transaction occurs.

But no info about what happens when changing Apple ID on same device and how to handle that.


Thanks in advance.

Replies

Seen this from the the docs ?:

Send a copy of the receipt to your server along with some kind of credentials or identifier so you can keep track of which receipts belong to a particular user. For example, let users identify themselves to your server with an email or user name, plus a password.

Tags: WWDC Session #pending ref. IAP 04-0501 Attn:WRB

Similar to KMT answer, but except of use an email or user name, plus a password (because User A can provide User B it), I think you could make compulsory for the user allow using iCloud for your app and use ubiquityIdentityToken to identify the user.


An opaque token that represents the current user’s iCloud identity.


var ubiquityIdentityToken: (NSCoding & NSCopying & NSObjectProtocol)? { get }


You can get it as follow:


if let ubiquityIdentityToken = FileManager.default.ubiquityIdentityToken{

 }

If you are willing to require that the user log into some account, as implied by a the docs quoted by KMT, you can just do a receipt refresh each time the user opens the app. That will require that the user log into 'their' App Store (iTunes) account unless they did that within a reasonable period of time. This will pick up your theives but also burden all your users.


There are two accounts with similar or different Ids - iTunes/App Store Id and the Apple Id. Most iPhones are strongly linked (through Find My iPhone, iCloud data backups, notifications, etc.) to their Apple Id and users will not freely share their Apple Id nor change the Apple Id their device is logged into. It is, unfortunately, straightforward to change (and share) your iTunes/App Store log in.


So, you can use the user's iCloud Account key-value file (tied to their logged-in Apple ID) to write something at the time of first purchase and thereby record the purchase in only one key-value file - hence only one Apple Id can use the IAP. Any attempt to use the purchase could require having access to that key-value file and therefore require being logged into that Apple Id under which the purchase was originally made. Remember, the Apple Id is not the same as the iTunes/App Store Account. You also need to prevent crediting additional Apple Ids with restoreCompletedTransactions and with a second (third, fourth...) purchase of the same IAP (which would be for free). It is easy to separate a restore from a purchase in updatedTranscations and in fact once you have this system in place you can do your own restore and not implement restoreCompletedTransactions. I do not recall how you differentiate a second 'repeat-purchase-for-free' from the original purchase event - but there is some indelible marker that differentiates the two, perhaps it's the original_transaction_id being different from the transaction_id in a repeat purchase. You need to do this to prevent a 'friend' from logging into the iTunes/App Store account, making a second 'repeat-purchase-for-free' and crediting a second key-value file in iCloud.

But this is again a workaround and a restriction I do not want to enforce. The user's purchase is tied to their iTunes & App Store account, they might even not be logged in to iCloud theoretically when purchasing this item. Apple provides restoration of purchases based on the iTunes account. Attempting to restore them using same iCloud but different iTunes account does not work and I would not want to add custom logic for something that Apple claims to provide out of the box.


As I answered to KMT, I want the receipt to be the whole truth for my application. And everything works perfectly if I restore on a new device or reinstall on same device. My only problem is changing iTunes user with the app still installed. How can a different iTunes user access the previous user's receipt? Is this considered normal? Is this only a sandbox issue that I am experiencing?

I will insist on the answers I gave above. These are smart solutions but IMO workarounds. Apple pushes for trusting only the receipt as the total truth in auto-renewing subscriptions. I don't mind if I see a user's iTunes account logged in on 500 devices unlocking my app's subscription. I mind if that user's account then logs out, and my subscription is still active because the receipt stays the same and is not cleared or updated to reflect the new iTunes account. I see this behavior in sandbox and it does not seem normal to me, so all I want is to know all the cases when the receipt is updated and whether logging in/out of iTunes should force an auto-update to the receipt (IMO it should but I don't see that).

> I see this behavior in sandbox and it does not seem normal to me


What url are you use to verify your receipt in that example?


Quick question - is your goal more fraud-centric, or about simple user bifurcation?

Then I will give another answer to your "should" question that is not a simple work around:


Simply do an SKReceiptRefreshRequest each time the user opens the app. That will require, in most cases, that the user log into 'their' App Store account.


Remember though, these are not really lost sales as most users who will do this will not actually pay for the subscription. The solution above burdens all of your users to prevent this theft; it will not result in greater revenue to you.

This would be bad experience, legit users would also see the alert for no reason every time they launch the app, if I am not mistaken. And, exactly as you say, users that want to steal will simply press cancel.


(It will result in lost revenue, if the subscription includes ad-removal 😢)

Hey, Krince I'm facing a similar issue as yours. If a user wants he can unlock the subscription for a number of users using his apple id. This will be a loss in revenue. Refreshing the receipt won't help much in fraud prevention plus it becomes irritating asking to sign in with apple id every time and also scares away new users who are using the app for the first time.
Were you able to figure this out (not just a workaround)?