I'm working on an Android application, where a user can buy a monthly/yearly subscription to unlock content. Since the app is not very dependant on the internet I try to do as less comunication with backend servers as possible. However, I have to check if the user holds a valid subscription.
So my plan is to let the user buy the subscription and set the expiry date to today + 1 month/year.
As long as the current date is before this expiry date, I do not need to check the subscription anymore. But once the current date is after this expiry date, I need to check again if the subscription is still there. If so I need to update the expiry date by another month/year.
But how long is a month/year for Google? A month can be between 28 and 31 days long. A year between 365 and 366 days.
As per the documentation:
Monthly — Google Play bills the customer’s Google Wallet account at the time of purchase and monthly subsequent to the purchase date (exact billing intervals can vary slightly over time).
Annually — Google Play bills the customer's Google Wallet account at the time of purchase and again on the same date in subsequent years.
Seasonal — Google Play bills the customer's Google Wallet account at the beginning of each "season" (you specify the season beginning and end dates). This is intended for annual purchases of seasonal content (such as sports-related content). The subscription runs through the end of the season, and restarts the next year at the start of the season.
So for monthly subscriptions, it renews when the date number matches the purchase date (not sure what it does if you start on the 31st though) and for yearly it just renews on the same day the following year.
Related
I want to publish an Android app with 15 days as a trial period and after that, there will be a one-time subscription charge applicable for the lifetime. I see there is an option in play store developer account for the trial period, so my question is if the user cancels the subscription in the trial period after that is that user will able to use the app? I don't want to change any code for this in my .apk file.
In the Developer Console, you can set up a free trial period that lets users try your subscription content before buying it. The trial period runs for the period of time that you set and then automatically converts to a full subscription managed according to the subscription's billing interval and price.
When the trial period ends, Google Play automatically initiates billing against the credit card that the user provided during the initial purchase, at the amount set for the full subscription, and continuing at the subscription interval. If necessary, the user can cancel the subscription at any time during the trial period. In this case, the subscription remains active until the end of the trial period, but Google Play sets the subscription not to renew automatically; at the end of the trial period the subscription expires, and Google Play does not charge the user.
You can set up a trial period for a subscription in the Developer Console, without needing to modify or update your APK. Just locate and edit the subscription in your product list, set a valid number of days for the trial (must be 7 days or longer), and publish. You can change the period any time, although note that Google Play does not apply the change to users who have already "purchased" a trial period for the subscription. Only new subscription purchases will use the updated trial period. You can create one free trial period per subscription product.
For more information, please check the documentation: https://developer.android.com/google/play/billing/billing_subscriptions.html
I have an app in the playstore for my website, that offers a monthly recurring subscription, and on my backend I am both granting that month of premium usage and recording the fact that another payment occurred whenever the expiry time runs out on the last receipt and I re-query the Google subscription to check it is still active using https://developers.google.com/android-publisher/api-ref/purchases/subscriptions
There are other forms of payment on my website and apps, so I found this approach was working best. However recently I noticed my system had recorded too many payments compared to what was reported by Google itself.
It turned out that at renew time when I re-query the subscription, Google was returning that it was still active but expired in 1 day, instead of in ~30 days. My system would record that a payment must have occurred and then check again in 1 day (which this time would give the correct expiry time), and then again record that a payment must have occurred when Google again reported it was still active.
For example:
20th February - Initial purchase on app, app tells server the receipt etc. Expires in 30 days.
21st March - The expiry time is up so server re-checks status and Google says "expires March 22nd".
22nd March - The expiry time is up so server re-checks status and Google says "expires April 21st" (this is what it should have said last time)
21st April - The expiry time is up so server re-checks status and Google AGAIN says it only expires in 1 day, on the 22nd of April
etc
I am at a loss as to why Google is reporting the wrong expiry times once a month. I do not have any free days / trial period set up for my IAP subscription. As long as Google reported the correct expiry times then I would have recorded the payments correctly. But if the expiry time is not reliable, how can I tell if a payment has actually occurred?
The subscriptions resource returned by the above API call does not return the orderId of the most recent payment. I can't find a way to link the receipt I have stored server-side with its purchaseToken to any billing information of subsequent renewal payments.
Is there a way to link a receipt/purchaseToken stored server-side to actual payments that are occurring using a Google API? How can I get the most recent orderIds?
But if the expiry time is not reliable, how can I tell if a payment has actually occurred?
I am working on exactly the same problem and have the same observation.
It seems that even if you have no Grace period, it will behave like you have set grace period to 1 day.
Since you don't have grace period, my suggestion is to check the newly queried expiry time against the previous expiry time (you need to store that somewhere).
If it differs by around 1 month, then you can consider that a successful payment. Otherwise, the difference should be around 1 day and it's Google's grace logic at work (probably).
Take note that the time the expiry time varies (i.e: if you first expiry is on 21st March 12:00:00, the second expiry can be after, like 21st April 13:12:32), so you shouldn't use sharp check (i.e diff == exactly 1 month).
Here is an example from Google merchant history. The Date column is approximately equal to the expiry time.
Is there a way to link a receipt/purchaseToken stored server-side to actual payments that are occurring using a Google API? How can I get the most recent orderIds?
You can get the client to send both orderID and purchaseToken as part of the payload, then link them on server.
That seems to be the only place with knowledge of both, for now.
I am implementing an app that will have an in-app subscription purchase. The subscription is renewed on a monthly basis. When a user purchases the subscription, they get a free 30 day trial. I understand that I have access to the purchaseDate value from the JSON that is returned, however I have a few questions about this:
When a person's subscription renews, does the purchaseTime / purchaseDate get updated to the date/time of the renewal? Or does it always remain the original purchase date?
I am trying to figure out the best way to cache this locally in the application so as to only have a check using getPurchases a couple of times per month around the time of renewal, are there any good examples or best practices I could follow?
Please don't respond by posting the documentation link. I know where to find that and have read it already :)
The getPurchases() method mentioned here only pulls non-expired purchases. Therefor, if your app notices that a user does not have a purchase (no purchases returned from 'getPurchases()', but they DO have purchase info (has_purchase, purchase_token, etc..) in your app's DB, then you found an expired purchase, so remove all purchase info in the DB for that user.
Hope that helps.
Here is my current guess on this I haven't been able to find a good doc either.
I believe the simple answer is that the purchase date is the original purchase date not the date of the renewal.
In other words if the subscription started on March 1 and you do getPurchases in July the purchase date will still be March 1 even though there have been a few renewals.
You can tell the subscription is active with getPurchaseState() = "0" (Purchased), "1" = Cancelled, "2" = Refunded.
To know the expiration date use the Day of the Month from the Purchase Date and find the next occurence of that Day of the Month. For example if today is July 15th and the getPurchaseState() = "0" then the expiration date must be August 1.
All of the above is a bit of guesswork. I wish I could find a good doc on this too.
On the iOS platform, an auto-renewing in-app subscription renews 24 hours prior to expiry.
What is the equivalent time at which an auto-renewing in-app subscription renews on Android? I have a number of subscriptions within 24 hours of expiry, but they don't appear to be renewed/renewing. I have a block of more than 200 in-app subscriptions all within 24 hours of expiry but not a single one appears to have an extended expiration date when I reverify it with Google. It is unlikely that my user retention rate across this number of samples is actually 0%.
Thanks!
Looks like they're rather vague in the documentation:
Monthly — Google Play bills the customer’s Google Checkout account at
the time of purchase and monthly subsequent to the purchase date
(exact billing intervals can vary slightly over time)
I feel like this means they would try to be as close to the original billing time as possible, although I couldn't be sure.
Is it possible in Android In-app purchase to create something like registered members or subscribers, to allow the users in that group to download content and to take fee at the end of the month?
As of now, not with Google Play. The Amazon in-app billing API does support this though.
It is possible with unmanaged purchase, but you will need to have server side support for this.
You will have to save the purchases in your own system, keep track of the expiry for each user, etc.
Also, you could do it with managed purchase by creating a new product for each month, but it has its limitations. E.g. you offer monthly subscriptions from the first day to the last of the month and the user buys one on the last day of the month, the he/she will pay the full monthly price for only one day. I do not recommend it.