We want to use auto-renewable subscriptions in our app (iOS/Android). But I don't understand what is the best way to sync these subscriptions between devices and platforms.
We are using user email for authentification but it seems that all subscriptions are linked to user's Apple account.
Does it mean that I can't sell subscription to some user if another user (from the same device) already bought one on this device because this device is already subscribed?
What is the best way to sync subscriptions between platforms? Should I write some server code to check subscription status for the current user? But, again, right now I don't have any information about user except his/her email. Of course, it is possible for me to put subscription status on our server but what to do with this case:
user A bought auto-renewable subscription on iPhone from the app;
user A cancelled this subscription via subscription management (app doesn't know anything about it yet)
user A logged-in on Android device, and he is subscribed because I don't have any information about him/her cancelling his subscription yet.
I understand that I am able to check his/her subscription status from my server, but his/her in this case means I am able to check his/her Apple account status, not his/her account in my app. So, for example, if I have two/three/million users on the same Apple device (first is a paying user, and the second cancelled his subscription) it means that I will always get the good receipt from Apple, right?
It's possible that my understanding of how it works is not very good, or, maybe, I can't see the good working pattern here, but I don't understand how to create convenient subscriptions that would work for iOS/Android both.
At the same time I know it's possible because of Wunderlist and dozen other apps with this functionality. Could someone please describe high-level logic behind that?
If your app offers auto-renewable subscriptions, you can receive server notifications from the App Store about key events by setting up an optional URL that links to your server.
https://help.apple.com/itunes-connect/developer/#/dev0067a330b
Related
My problem:
I am having a hard time figuring out a way to safely manage auto-renewable subscriptions in iOS with Firebase.
Purchase process:
User1 purchases a subscription
Update User1's account on Firebase w/ the subscription identifier
(used to unlock content)
Store original_transaciton_identifier(OTI) w/ uid of User1 to match w/ receipt verification from Apple.
Grant user access
Edge cases causing my brain to implode:
User1 logs out of AppleId used to purchase subscription, but remains logged in to app w/ Firestore credentials.
Therefore, when I go to verify if the subscription has expired it does not return a valid subscription. I want the user to be able to keep their access until it is expired or canceled. Any tips on achieving this?
User2 logs into the same device User1 was previously using.
Therefore, the same AppleId is being used for both users. I can check if the current user has a subscription, and check the OTI to see if it corresponds to User2...which it won't.
We will show the 'purchase iAPs' screen, but what if this user wants to buy a subscription as well under the same AppleId? Is it normal for me to handle this saying, "Apple Id already connected with another account or something"?
Relevant articles I've been able to find:
How to tie auto-renewable subscriptions to in house user, not appled id
I've been struggling with this for sometime and haven't been able to find many resources. All help is appreciated.
For case #1:
When you attempt to access the receipt Apple will trigger a login prompt for the user to enter their iTunes credentials. If a receipt is still unavailable, you won't be able to verify the subscription status. The "right" way to do this is to store the entire receipt on your server, and periodically refresh it with /verifyReceipt. You'll check if the subscription was cancelled, and update the expiration_date so you know when to cut off access for the user.
For case #2:
Is it normal for me to handle this saying, "Apple Id already connected
with another account or something"?
Yes! If you're able to look at how some other large subscription apps handle this (Netflix, Spotify, HBO, etc.) - it's similar to what you describe. Instead of checking the receipt locally every time, if you maintain the subscription status on your server (as mentioned in #1) this would only happen if the user tries to "Restore Purchases".
This is a pretty extreme edge case, since not many people try to make a purchase on their friends phone and would require TouchID/FaceID in most cases - so it's more of a fraud prevention feature. Once you get millions of users you can get fancy and send them an automated email link to signup with Stripe if you detect this.
Alternative:
RevenueCat can handle all the subscription tracking and these edge cases out-of-the-box, and it plays nice with an official Firebase integration. Disclaimer: I work there.
Let's assume we are Netflix. The user created an account on our webpage and then downloaded the iOS app. Within the app he started a payed subscription by purchasing an auto-renewable iOS subscription.
The subscription is added to the user account on our webpage. Thus the user can access the paid content not only within the iOS App but also on our webpage from his SmartTV, etc.
The user can mange his account not only from within the iOS app but also directly on our webpage.
The iOS Subscription is not linked to the iOS app but the users Apple ID account. Deleting just the iOS app does not has any effect on the subscription at all. At the end of the subscription period the subscription would sill be auto-renewed and our server. Our server does not need an installed iOS to recognize the renewal (e.g. using Status Update Notifications or by polling the /verifyReceipt endpoint). Thus the user could still continue to access the payed content even if he does not use/install the iOS App any more. Is this correct?
But what happens if the users decides to delete his user account on our webpage and forgets to cancel the iOS subscription?
In assume the subscription would simple do the same as before and would auto-renew at the end of each subscription period. Since the user account on our server has been deleted the server does not recognize the renewal any more and the user simply pays for nothing. Is this correct?
Or is there any way the server can notify Apple to cancel the subscription?
Question 1: The iOS Subscription is not linked to the iOS app but the users Apple ID account. Deleting just the iOS app does not has any effect on the subscription at all. At the end of the subscription period the subscription would sill be auto-renewed and our server. Our server does not need an installed iOS to recognize the renewal (e.g. using Status Update Notifications or by polling the /verifyReceipt endpoint). Thus the user could still continue to access the payed content even if he does not use/install the iOS App any more. Is this correct?
Ans: Yeah You are right. When you had send receipt to server first time, then receipt will be verify with apple by verifyReceipt, after that your server validate this receipt time to time.
Question 2: But what happens if the users decides to delete his user account on our webpage and forgets to cancel the iOS subscription?
Ans: If user has deleted his user account on webpage then user account will be auto-renew at the end of each subscription period. There is only the way to manage i.e. if a user request for refund after deleting the account, then you can check form server(for deleting his account) and refund his money.
Question 3: In assume the subscription would simple do the same as before and would auto-renew at the end of each subscription period. Since the user account on our server has been deleted the server does not recognise the renewal any more and the user simply pays for nothing. Is this correct?
Ans: No this is not correct. Subscription will only be managed by Apple , not your server. Only your server can hit the request for verify subscription status time to time nothing than else.
Question 4: Or is there any way the server can notify Apple to cancel the subscription?
Ans: No, there is no way. Because of apple security. Server has not any authority to do anything in users account(Apple account). That is the reason apple will never approve your app with auto renew if you will not clearly see the below information to user before his purchasing(Subscription). Please refer attached screenshot.
There is no automatic API for this flow it seems within IAP ecosystem.
Here is what you can do.
Upon (before / after, depending upon how you want it) account deletion from within iOS app, you are obligated to route the user to the following page to remove his / her subscriptions, by visiting the following page:
https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/manageSubscriptions
Opening this URL launches iTunes or iTunes Store and displays the
Manage Subscription page.
If account deletion was initiated from web UI, you should show an instructional page for canceling subscriptions from all possible devices (iOS, Android, TV apps, Web). It is then user's responsibility to ensure he / she cancels it.
Since Apple is the marketplace, this is not different from you buying a grocery product from a supermarket. As it is mentioned on Apple docs pages, it is iOS user's responsibility to get in touch with Apple Customer Care for subscription cancellation.
As a service provider, you are obligated to demonstrate to the user how to do it.
I just run into a problem with in-app auto-renewable subscription. The app contains this kind of subscription and the app can be used by multiple users but the subscription is bind to the apple id is used on the device. So if a different user log in to the app than the system say he has a valid subscription. If I log the subscribed users on my backend server than if a user without subscription log into the app can not make a new subscription according to the Apple's response because the apple id used on the device. An other problem if a keep track of the subscriptions on my backend server if the user unsubscribe on the apple's webpage I can't notify the server about if.
What do I do wrong? What is the right workflow for this case?
I hope do you understand my dilemma.
Thanks!
Your use case is absolutely valid and that's exactly how the subscriptions In-App purchase work with any platform (Apple/Google).
In case of Subscriptions in-app purchase the content delivery is entirely the responsibility of the app provider and not the platform. You have no direct way of identifying if the app user has been switched to a different user as you can't access the current logged in user on iTunes account on the device.
You need to manage this use case on your own by keeping some data locally on the device and maintain user purchase history but still that wouldn't solve the purpose 100%. When user will go for purchase of the subscription it will show the service as already subscribed unless the iTunes user account is also switched on the device.
You can keep track of the unsubscribed state from the backend as when the subscription is successful you will get a receipt from iTunes which you can use to save in your DB. You need to run a backend job on the server side to validate the saved receipt to check the updated receipt which will give you details if the subscription has been expired or not.
We are building a subscriptions based video on demand platform that lets our subscribed users to access films from a variety of devices including iOS, Web etc.
So no matter from where the user has subscribed, they should be able to access the content from any & all devices that we support.
Since I need to maintain user's state at a central system (so that all devices can query & allow/disallow access to paid-content).
I have read through multiple documentation re: iOS In-App Purchases & have determined we are a good fit for auto-renewable subscription category.
I have already integrated subscriptions via Roku & using that as a reference. For users who are subscribing through the Web, I have also integrated payment processors like Amazon Payments, Stripe & PayPal - the transactions for which are triggered by the Subscriptions Billing platform that I have already built.
My server (or an endpoint essentially) needs to be able to receive following bits of information preferably directly from iTunes and not from my app.
Notification when a user subscribes successfully to one of my products
Notification when iTunes sucessfully renews a subscription i.e. if user is subscribed to a monthly product then at start of next month, I need to have notification from iTunes that user has been successfully charged for upcoming month
Notification when iTunes successfully refunds a user for whatever reason
Notification when a user cancels a subcription directly from iTunes (not from the app). I know in this case it will mean that it stops the auto-renewal, but I still need to know that this has happened.
Notification when a user un-cancels the auto-renewal.
Does iTunes support any of these actions via Webhook or Push or IPN (instant payment notifications) etc? I havent come across it, if it does.
I know that there is something called as Validating Receipts but that seems to be not a good solution for me, since I need to know ASAP rom iTunes that one of the above flows has happened.
What, if any, are the workarounds to get this information? I am afraid that getting this info from my app is neither timely nor guaranteed to get it.
If you're expecting a direct feed from iTunes, you need to reevaluate your requirements. The in-app purchase ecosystem simply doesn't work that way. You may have the option to write your own subscription processing system (requires an outside payment processor) but whether Apple will approve it will depend on the exact nature of your content. From your description, you have mutually-exclusive requirements.
If the immovable requirement is that you use iTunes, you will need to validate receipts and forward those results to your server.
I need to build an app for a system, which already has a subscription on its website. It looks like Apple doesn't allow to use any own subscriptions and forces to integrate any app with iOS in-app subscriptions.
Is it any way to integrate two subscription systems? The main problem is that users can manage iOS subscriptions via iTunes and I can't find whether it's possible to get information about this and to stop subscription in the existing system if it's stopped via iTunes.
So is it possible to get notifications about unsubscribed iTunes users?
Using third party subscriptions
First off, it is possible to support an existing subscription system in your app, but it must be in addition to the App Store subscriptions. Also you have to be very careful about the UI you use. You can't prompt users to bypass the App Store and purchase through your server, but you can offer existing subscribers the ability to sign in with credentials they may have previously obtained through your website.
That said, Apple can be fairly capricious in their rulings on what is and isn't allowed in the App Store. I have worked on apps that have done this sort of thing, but they have been for fairly well known magazine publications. There's no guarantee that they will allow it for everyone.
Detecting unsubscribed App Store subscriptions
As for using App Store subscriptions, when a user purchases a subscription in your app, they will receive a receipt in the SKPaymentTransaction object. This receipt should be posted to your backend server to make sure it is valid before you give the user access to anything. See the In-App Purchase Programming Guide for more details.
When you setup a subscription type, you specify how long that subscription lasts. So if you log the transaction date in the SKPaymentTransaction when you receive a receipt, you can determine exactly when that subscription should expire by adding the duration of the subscription to the transaction date.
If it's an auto-renewing subscription, you will receive a new receipt when the subscription is renewed. So once you have validated that with your backend server, you can update your expiry date based on the new transaction date. If you don't receive a new receipt before the first one expires, it's likely the user has cancelled their subscription.
On the backend, your server can also tell when a particular subscription will expire based on the response from the verification server. First there is the status code which will tell you whether the subscription has already expired, but there is also an expiry date returned in the decoded receipt which will tell you when it is expected to expire if it hasn't already.
For more details, see the Auto-Renewable Subscriptions documentation.
Testing auto-renewing subscriptions
It's worth noting that when you are testing auto-renewing subscriptions in the App Store sandbox environment, the length of the various subscription types is dramatically shortened to make it easier to test. For example a 1 week subscription lasts only 3 minutes in the sandbox environment. You can see the full list of times in the iTunes Connect Developer Guide.
So you want the people that have bought the service from the website to be able to use the app, exactly like if they had purchased it from in App Purchases and in App Purchases people to be able to join the service just like people that joined through the site? As far as I know, Apple doesn't allow you to pay through other services as you said, but let's say someone buys the service from the app. What should happen would be that the money will be transferred to the company. Then after the payment you should include some code doing what the site does after a new person has payed for the service, so create his account as a paid account. Then, the app should also have a login screen where the registered users (no matter where they registered from) will be able to login into the app and use the service. Now the problem is indeed that if the subscription is stopped through iTunes you would never know, though a way around this would be to make a check in the server of this company which should monitor the income coming from one account. Then if this user has stopped paying (or stopped the subscription) you would be able to stop the service from the app. And you should recheck the server for payment after the duration of the subscription has passed, let's say a weekly subscription should be checked every week. (Sorry I would do this a comment but I haven't got enough reputation for this)