We are verifying Google subscriptions on backend using requests to:
https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptions?hl=en
we have also integrated with server notifications, so that we have updated data on all subscriptions.
I started to compare numbers displayed on play.google.com/console to what we have in our app and those are nowhere close. On our backend we see 30% more subscriptions that are marked as active then on Play Console.
On Play console I have restricted Subscription data chart to only single day and got number of subscriptions that were active at least for one day within given time window (so 1 day).
On our backend I got all subscriptions that had startTimeMillis before (or equal) given day and expiryTimeMillis after (or equal)
The difference was around 30% (Play console shows lower numbers). For all subscriptions I got updated data from purchase.subscriptions api (linked at the top) and confirmed that all of them should be active:
paymentState=1
checked date is between start/end date for subscription
According to other stackoverflow answers like:
How to verify purchase for android app in server side (google play in app billing v3)
checking expire date should be enough to verify if subscription should be active or not. But Maybe I'm missing something? Or maybe Play Console is not showing what I think I see?
Related
I am using InAppPurchase to sell subscription to users with one month plan.
Setup is done and i can test Purchase flow, but renewal is not working in sand-box mode.
I am using billing library version 4
implementation 'com.android.billingclient:billing:4.0.0'
After successfull purchase while validating receipt on server side getting autoRenew param in json with value blank. After 5 min plan is expired as describe in doc, but as per doc auto renew will expires after 6 times. In my case after first purchase auto renew not happening.
Can any one help me in this where i am wrong in this.
I already spent 4 days in searching for this issue.
Thanks in advance
From your screenshot I'm deducing you are in India.
A few months ago, Google has announced that it would pause new signups of auto-renewing subscriptions for users in India:
Subscriptions will continue to be available as single access passes that provide users a single billing period of access (eg. 1-month access). At the end of the billing duration, Google says users will need to sign up again in order to continue their subscription.
source: https://www.xda-developers.com/google-play-suspend-free-trials-auto-renewing-subscriptions/
Maybe you should try to test on another market.
I have implemented Subscriptions in mine Android app, and wondering how to check expired subscription. As I understood, expired subscription should not be returned in getPurchases() method.
The problem is - I tested 1 month subscription using test account (which renews subscription every 5 minutes, as described here https://developer.android.com/google/play/billing/billing_testing#testing-subscriptions), and after expiration time I still recieved that purchase in getPurchases(), even after 1 day. However, if I manually tried to subscribe one more time, Play Market didn`t refuse, and everything worked fine.
Also, when I was selecting 'decline payment' in subscription settings, it dissapeared from purchases list, as it supposed to be.
Thanks in advance.
I didn't understand what do you mean by "renews every 5 minutes".
Once you subscribe to Google play to any app/service, it will be available until the end of the subscription.
For example:
I purchased a subscription with an APP for 6 months.
I went to Google Play after 2 days and canceled my subscription but the app will still see that I am subscribed for the remaining 6 months because I already paid the subscription fees.
It's not something that you can handle from Google Play :)
Hope this helps.
I have an Android app offering auto-renewing subscriptions via In-App Billing, using https://developer.android.com/google/play/billing/billing_library.html.
I'm using a lightly modified BillingManager.java from https://github.com/googlesamples/android-play-billing/ to help with purchase management.
Previously, prior to release (around 4-8 weeks ago), whenever a subscription trial ended and the subscription auto-renewed, I would continue to receive a corresponding Purchase object in the purchases lists upon querying purchases:
PurchasesResult subscriptionResult = mBillingClient.queryPurchases(SkuType.SUBS);
List<Purchase> list = purchasesResult.getPurchasesList();
(see queryPurchases here)
The OrderID had an incremented counter value appended according to the number of renewals that had occurred since the original order (as described under Subscription Order Numbers here).
In the last few days, it seems that whenever a customer's subscription converts to paid from trial, or renews subsequently, queryPurchases returns zero Purchases thereafter. I expect to receive one Purchase object for users with an active subscription (and was getting this during testing a while back - I have the data in my db to confirm it.)
As a result, the app no longer calls our backend server to update the subscription validity and users are denied access to functionality for which they have been charged - not great.
I can view the customer's order (with incremented OrderID) on Google Play Console and the subscription shows as valid (and is not cancelled) and a purchase token is available and can be validated.
Does anyone have any idea why would queryPurchases would stop returning a valid Purchase after the first renewal? (The Purchase is returned as expected prior to the renewal date.)
I'm using the current billing client library, as follows:
implementation 'com.android.billingclient:billing:1.0'
(As a workaround, I can fix this on the back-end by periodically rechecking all submitted purchase tokens, but I'd much prefer to do it on demand triggered by the app, which was working fine previously.)
I trying to test Android In-App Billing V3 to make subscription purchases.
Im aware of the following:
"Test subscription purchases recur daily, regardless of the product's subscription period."
but I noticed the following behavior:
A user buys a monthly subscription through google play, the client passes the information to the server. On the server side, I make an API call to google to get more info about the subscription.
I go to the Google play dashboard and cancel the subscription. (it changes from renewing on X to expire on X).
I buy the same subscription again but I have the following behavior:
Purchase token is the same as in #1. My assumption that the purchase
token will be different.
autoRenewing is still set to false (even
though google play dashboard shows "will renew on x").
expiryMills still shows the original expiration which is in the past (I resubscribed a couple of days later so I would expect the expiryMills to be updated)
Im not sure if this is the correct beahvior or not ...
I would expect the following: If im in within the period, so after the user cancels and then resubscribes, the autoRenewing will "true", and if im after the period, I will get a new purchase token so that the information I get from google api will match the google play dashboard.
Ofir
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.