One of my app is running well on Apple Appstore also generating revenues. In that app user has to pay through Auto-Renewable Subscription for registration. On 13th May (Day before yesterday) a user tried to create his account but after the payment was done, my server could not saved IAP Receipt. It might happen through internet connectivity issue with the device. The App flow is:
Put values for registration like name, surname, email, pwd
Press register button
In app purchase starts
Payment is done
Get receipt from apple.
Save receipt on my server db along with his login details
So in the case that failed, the process could not reach 5th and 6th step and I could not get payment receipt. Also there in no registration details are there on my server db.
After verifying the payment, I gave him access to use the app by creating his account manually. But still I want the payment receipt so that i can further check his subscription is active or not.
Is it possible to get payment receipt now? Even in NSData form? My I tunes account is having anything related to this?
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.
I'm using auto recurring subscriptions in my app in my app,I need to change the subscription status if recurring fails from iOS.
I am following this documentation, but there are a few things that are still not clear to me:
What if my server missed the post data from iOS
How do I know if the subscription got renewed
How do I link my app user memberId (unique id) to the transaction
What is the difference between latest_receipt form iOS post data(server to server notification) and bundle receipt url after purchase.
Here are the steps I take the user to subscribe:
Ask the user to sign in. If they don't sign in they can't subscribe.
Send the app receipt to my server and store it there. If this fails they can't subscribe. This need this to validate get the latest_receipt info from the server at any time.
The user subscribes through iTunes.
Validate their receipt with the app store and check the latest_receipt to make sure they are subscribed. (This is done server side)
Repeat step 4 periodically to make sure they are still subscribed
So to answer your questions:
What if my server missed the post data from iOS?
Since I get the app receipt from the user before they subscribe I can check the with itunes directly from my sever any time and get the status of their subscription.
How do I know if the subscription got renewed?
Since you have the user receipt on your server, you can use it to get the latest receipt from apple and check the current status of the subscription. Here is how you do it Validating Receipts With the App Store
How do I link my app user memberId (unique id) to the transaction?
You could use the "Original Transaction Identifier" from the receipt as a unique id. This value is the same for all receipts that have been generated for a specific subscription
What is the difference between latest_receipt form iOS post
data(server to server notification) and bundle receipt url after
purchase?
When you send a receipt to the app store to be validated, it will return a JSON representation of the receipt that was send, this can be found in the "receipt" field. If your receipt contains subscriptions you will get "latest_receipt" and "latest_receipt_info" fields. These fields are useful when checking whether an auto-renewable subscription is currently active. If the bundle receipt is up to date then the "receipt" and "latest_receipt" will be the same.
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.
I understand that If a user buy something using in app purchase, it should reflect in all the devices owned by the user ( based on logged in apple id ).
But in my case I need to handle it with "our own username and not apple id". That is if user logged in to our application in multiple device, We need to handle subscription all our own.
Just to clarify, even if user logged in to two devices with same apple id but different user in our application, only the username who actually bought our subscription should get the extended access.
I believed that non-renewable subscription is what We need, but on reading a bit, I think such a subscription should reflect in all devices registered by same apple id.
So it would be great if someone could help me to select which kind of in app purchase should i choose for this scenario.
Any help appreciated. Thanks.
The kind of in app purchase for this would be preferable is non consumable. In this case user don't have to buy the product again and again. Regarding your question with your own username you can maintain the record of purchase for single user in your local server. For that what you can do is while verifying the transaction receipt from your local server which you will get on every successful transaction from apple in app purchase server. For verifying the receipt you have to send the receipt to you local server in base64 encoded format then your local server will connect to the apple server you local server will verify the receipt while sending the receipt to your local server send the session id of the user to your local server if the verification of the receipt is successful then you local server will store the purchase information in local data base. If user will login in the second device also you local server will know that this user have purchase this many item and you can sink the data in all the device in which user have logged in.
After my new iOS App was approved last friday, today I recognized that I mistakenly rolled back an SVN change and therefor all In-App-Purchases that were made during the weekend were validated in the wrong place (Sandbox URL). (Error code 21008: This receipt is a production receipt, but it was sent to the sandbox server.)
Now, I can see in iTunes connect that there were a bunch of successful purchases. But the problem is that - since validation failed (due to the wrong URL) - I did not enabled the special features within the App for those users on the server side.
I tried the whole day to find out which of the app's users made a purchase, so that I can enable the extra features that the users paid for now (and to send them my apologize via email).
But since the receipt data is send via POST requests, I was not able to get this info from my server's log files. And in iTunes Connect I was not able to find some report(s) that include the receipt data for successful purchases.
The last option would be to enable the extra features within the app for all users who logged in during the weekend. However, I'd prefer to get my hands on the receipt data.
Is that possible at all? Does Apple grant access to this data? Any idea(s)?