In-App purchase - Receipt validation - Expires date wrong - ios

Goodmorning everyone ! I have a little question that I would like to ask you without going to waste an incident with Apple ...
In practice I am validating the receipt of payment for an in-app purchase, specifically a one-month subscription that unlocks some features of my app.
I parse the json correctly and apparently it seems to work fine but this does not always happen! In fact it often happens that the expiration date that I go to read from the json is not correct as if the subscription was not included in the receipt and I fished only those of the day before or in any case the previous ones.
This happens in sandbox and having checked the code and reviewed well, the parse of the document I could not find a solution because often the validation of the subscription is successful. I also searched online to see if it was a common problem but I did not find a solution or a discussion. My subscription does not include trial periods.
In the specific case this morning the first test was successful, but the validation was not valid. Checking the date shown was that of the previous day and then a previous subscription made yesterday. Once the subscription to the second test expired, the subscription was successful and also validated.

Related

iOS Subscription latest_receipt_info

I'm building a react native app that has a 1 month subscription component. I have integrated into the apple API to get the receipts but I have one question I can't seem to figure out in test mode. Probably a newbie question but here we go...
When a user has an auto-renewing subscription and I call the Apple API there is the latest_receipt_info.
Will I get a new one every month? if so when does it come through?
So will all I have to do is call the Apple API, grab the latest transaction from latest_receipt_info and look at the "expires_date" field. If we are still before this date then I assume the subscription is still active? Can it be this simple to see if a subscription is active or not?
I've seen talks online about a "cancellation_date_ms" field but I can't seem to find it in sandbox mode, but why would this be needed if I just use the logic I stated above?
You can get an updated receipt any time by calling Apple with receipt data from the application, even if you send older data Apple always sends you the latest receipt.
You can check for the expiration date within, however it is the case if a user gets a refund the expiration date may still be in the future - in that case you'd be sent the cancellation_date_ms as well, so you should look out for that.
To get a better understanding of what all can be in latest_receipt_info, read through the entries in here, search for responseBody.latest_receipt_info:
https://www.namiml.com/blog/app-store-verify-receipt-definitive-guide

What is the best way to very an IOS auto renewable subscription is active?

I am looking for some advice on how to go about checking the current status of a users auto renewable subscription.
At the minute I am using the following setup.
User registers and subscribes to the product.
The receipt is posted to my server.
Each night the server pulls all the users where the expiry date is in the past and then using the receipt check to see if the product has been renewed.
Now I think I have an issue with the above setup, it works ok for a small number of people but lets say I have a few thousand. I noticed that calling the Apple servers takes time and so I can't really run the above setup reliably.
I am thinking should I check the receipt locally every time the user opens the app and then post the latest info to my server each time and keep it updated that way? The only issue I have here is that if a user doesn't open for a while then I cant validate their status and my database isn't up to date.
Any advice on the proper approach to take would be great thanks.
This is a real problem.
At Elevate we would do exactly what you described, checking everyone's receipt every night. This was fine until the time it took to check all of our receipts exceeded 24 hours. At this point we implemented some smart pacing: Each time we checked a receipt and it wasn't subscribed and the user hadn't logged in, we would extend the date where we would check it.
This isn't bullet proof but is a decent balance of accuracy and efficiency.
I thought this was such a crappy problem I started a company to solve it. We do all the nasty receipt checking so you can just ask if a user is active or not.

Best strategy to Get In-App Purchase Auto-Renewable Subscription end date

I have been reading a lot about auto-renewable subscriptions but so far I could not get a satisfactory answer to my questions.
Imagine a user subscribed to my app for 1 month and the very first view of the app has some content that only visible with subscription. Now imagine it's the first day of second's month subscription (after auto-renewed). If I don't query the expiry date from apple server, user can't see subscription items, because the expiry date of first month already passed and we need to get the new expiry date.
My questions are:
1- Is there a way to get the end date of the subscription offline and without disturbing the user (with password prompt etc.)? How user will get subscription content if it is the first day of auto-renewed subscription (second month and so on) and if user don't have internet? Will he see locked content if he has no internet? If so this is sounds weird to me.
2- If it is not possible to get expiry date of auto-renewed subscription offline, what is the best approach to get expiry date of auto-renewed subscription without asking or prompting something to user? Because we want to show the very first page of the app with subscription content smoothly. What comes to my mind is to make user wait during launching and check expiry date from server.
I am sure many developers are still concerned with those issues.
It's been a long time since the last time that I integrated an auto renewable subscription and it harder than I expected, but I can give you some general hints and some more specific for your question.
Starting from your question.
Not exactly, you can get the last updated receipt by asking getting the receipt from the receiptURL, here is where I've found a really gray area. I never had a chance to understand exactly when a receipt is updated automatically, probably this happen right after Apple charged you (of course this update needs a connection). This doesn't seems to happen when you have restored a purchase on another device.
Yes there are, when you have a chance to validate the receipt you can store the expire date somewhere (maybe in a secure way) and only before one or two days after that day try to validate it again. If you want you can apply also a grace period after.
Other tips:
you MUST create a way to restore the purchase or your app will be rejected
on sandbox at the first launch the receipt will not exist, but in production an app will always have a receipt, maybe without subscription info, but there is. Thus if you want to simulate some use case in sandbox environment is better if you restore the purchase right after the launch of the application.
restore purchase always requires username and pwd and refresh receipt seems too
Maybe some of this info are a little bit outdated, I made the integration with iOS7 and never had a chance to update it.

Subscription renewal not showing in latest_receipt_info

Our backend does server side receipt verification. In order to check the last expiration date for a renewable subscription, we look at the information in latest_receipt_info. This approach works most of the times.
However, we have some cases of users that, even with active subscriptions, latest_receipt_info only contains the initial subscription, which has already expired. I wonder if someone has already experienced this issue of having missing transactions. It looks extremely weird to me, because Apple is not returning the right information. These users were charged properly, but the Apple response does not reflect that. Am I missing something? Documentation is far from being great... Thanks!

in-app purchase for auto-renewal subscriptions notifications

I've been reading the various threads on in-app purchases auto-renewal subscriptions, and I think I've pieced together most of the information I need, but there are a few missing pieces. I'm hoping someone can help me.
The situation:
I have various subscription packages the user can subscribe to (e.g., package A for £1 a month, package B for £2 a month, etc.). I store the user's subscription information in my database. When the user logs in, I check which package he's on and if it's expired or not. My website, android and iOS all use the same database, hence this approach seems to make sense.
Subscribing users via in-app purchase seems straight forward enough. I check paymentQueue and once the payment is cleared, I can update my database.
My questions:
1) My understanding is the user can use iTunes to manage their subscription. Say, they go in to iTunes and cancel their subscription, how can I be notified so I can update my database? Do I need a daemon that checks expired subscriptions to see if the user renewed?
2) If the user wants to upgrade their subscription from Package A to Package B, how do I handle the pricing? Say on Jan 1st, they buy Package A, I charge them £1.00 and set the expiry date to Jan. 31st. On Jan. 15th, they want to upgrade to package B via in-app purchase. Ideally, I would charge them £2 for Package B minus £0.50 of credit they have for Package A and set the new expiry date to feb 14th. However, Apple forces me to associate each package with a tier price. How can I handle this? I don't want the user to wait until the end of the month to put them on a higher tier package...if they upgraded mid-month, it means they want the new content package B will deliver to them immediately.
Any help appreciated!
Thanks!
1) Yes you'll have to reverify your receipt check out the Receipt Validation Programming Guide in the documentation. They mention some important keys:
status - 0 if receipt is valid, or an error code
receipt - JSON response of the receipt
latest_receipt (auto-renewable only) - base 64 encoded receipt for the most recent renewal
latest_receipt_info - JSON version of latest_receipt
With this information, when a purchase is made, send the receipt to your backend for validation, the backend will keep the receipt in the DB and verify with status = 0 that it's a valid receipt. From there, every x days you can validate that receipt with a chron job, daemon, etc. and reverify. The response back each time will have latest_receipt_info that you now need to save to your DB so you have an up-to-date receipt for the next check in x days. This way you will always have the latest receipt. There is no instant notification for telling when a user cancels a subscription, but with this you'll know every x days if they have the subscription still.
2) Pricing like this unfortunately can't be handled. It was not intended for a user to "upgrade" with subscriptions - each subscription is access to it's own exclusive content as of this writing. However, if a customer emails in and complains about it, you could ask for their user name and figure out in your DB if this user has indeed upgraded mid-month and reimburse them appropriately. Very old-school and not feasible for a big user base, but hopefully you won't have that many and can keep them happy.
EDITED
For the second question, Apple's auto-renewable subscription system does not technically offer upgradeable plans between different products.
Every subscription is a stand alone product and it's up to the user to turn on/off subscriptions manually using the Subscription Manager in the iTunes Store.
However if package A and package B offer the exact same content only different duration than what ajay_nasa said is correct, you can create an single auto-subscription product with different duration options. If the user is on 1 month subscription and then the user tries to change to 2-months subscription they will get the following error message asking them go to the App Store's subscriptions manager
So basically the ONLY place the user can actually change the subscription's length is in the App Store. Whether Apple decide to pro-rate the amount left on the old subscription or just append it to the current one is really up to Apple. You need to make sure the user have access to the subscription as long as it's active by reading the Original Purchase Date and Subscription Expiration Date field from each receipt entry and determining the start and end dates of the subscription.
Answering question 1, you can verify subscription receipts in the same way as other IAP, but you'll need to check it periodically to see if the subscription has expired (the verification will tell you if it's expired).
There is more info on the Apple docs here:
http://developer.apple.com/library/mac/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/RenewableSubscriptions/RenewableSubscriptions.html
Actually, Apple's auto-renewable subscription system does offer upgradeable plans.
To achieve this we simply should add duration in existing Auto-Renewable Subscription. Every Auto-Renewable Subscription could be family of Subscriptions so whenever developer wants to achieve upgradation in subscription he should add duration in existing Auto-Renewable Subscription with different productID.
Whenever, user upgrade his plan in between the month then his upgrade plan will be automatically works from next month.
Answering to your question #1
Recently Apple launched a feature to enable server notification whenever the subscription is renewed. However, the subscription should be in-app.
See the links given below for your reference:
https://help.apple.com/itunes-connect/developer/#/dev0067a330b
&
https://itunespartner.apple.com/en/apps/news/45333106?sc_cid=ITC-AP-ENREC
We Need to Check Cancellation-Date provided in Receipt.

Resources