My app uses google's billing API to retrieve subscription options configured in google's developer console. We have some subscription options configured as free trials.
So far we've been using the IInAppBillingService.getSkuDetails() method. This reference -
https://developer.android.com/google/play/billing/billing_reference.html#getSkuDetails - shows what kind of data you can retrieve data regarding the subscription item. But sadly it does not include the trialPeriod nor billingPeriod.
I stumbled upon this google play API https://developers.google.com/android-publisher/api-ref/inappproducts that shows you can query the in-app products and get a response with more details.
Is this information somehow available using the IInAppBillingService ?
There is currently no API that returns the info if a subscription is bought directly or through free trial.
Haven't tried it myself yet, but a workaround I could think of is to have different periods for an actual subscription and a trial period. Say have an actual subscription to have a minimum of 1-month subscription, then for a free-trial, have it as 1-week. (The difference in periods kinda gives the free trial a demo-like thing into it too)
With that done, you could call Purchases.subscriptions.get (or depending on how you're getting the subscription details, so long as you get the details) to receive a Purchases.subscriptions resource.
From there, you could compare the startTimeMillis and expiryTimeMillis. If it's 7-days, it's a trial, else, an actual subscription. (similar idea as to what was mentioned in this answer.
With all that said, I would like to point out that I'm not entirely sure if this is good practice in determining free trial subscriptions.
Related
I am creating an app in which i need to update UI based on Google Play Subscriptions
I have two cases in which i have problem
is user used Free Trial Subscription
Is user used Introductory based Subscription or not
I know it will automatic adjust when user try to payment. But I need this in to update App UI
Google doesn't provide an API for this.
First option: If you're forcing users to sign in, then you can use Firebase RTDB to save the user's subscription/trail data and then you can listen to DB changes and update the UI on data changes.
Second one: You can use a service to track this data like Revenuecat. You can check Period Type from their API. I'm currently using it and it does the job.
Other than that, there's no way to get this information from Google yet.
Currently, I don't think there is a way to get the details of free trial subscriptions as per google play API. So as per your use cases, we can make a workaround it.
We can use purchases.subscriptions.get to get the timestamp when the subscription was taken and once that information is with us we can compare the subscription taken the time and we can compare it with the current time. If that time exceeds the Trial days limit we will know that its a Introductory based Subscription.
One of my Android apps has an in-app item that is essentially a token which people can buy and use at a later time.
I see that some people buy it and then refund it later. While implementing purchases I used the standard guide from Java section of the docs that Google provides on the topic, plus I do verify the purchases on my backend server.
All that said, I'm still not sure that it can't potentially lead to some kind of fraud. Generally speaking, is it possible for the user to buy this "token" use it and then refund it in a matter of few minutes? I didn't look into it yet, but it doesn't seem that Google would bother to send a refund callback to my backend..
Basically, how to handle these things correctly to prevent fraud?
Edit: to be more clear, I do the acknowledgePurchase() and I get valid sales that don't get refunded, not after a while, not ever. I just wonder how is it so happens that from time to time I see a purchase made, then after some time (which differs in length) it does become "refunded" (but not all of them, only some).
Please make sure after purchasing you did BillingClient.acknowledgePurchase() in your app. You can find details about this Here
If your code, when handling a purchase, does not call acknowledgePurchase() and neither call consumeAsync() then the purchase is refunded after a short time period
The only real way to verify the authenticity of a document is by verifying its signature, the same happens with in-app purchases.
A purchase token can be faked but a signature can not.
Look at this : https://stackoverflow.com/a/48531877/7690376
I'm writing an app that will support in-app subscriptions. The subscriptions will enable my users to use a number of services and benefits outside the Android world. I know that I can use Google Play Developer API to query the status of a subscription, but due to the nature of the offered services and benefits, it is not very convenient to do that. I was wondering if there is a way to get notified about the status of the subscription when it changes. Something like a web hook for example.
I wanted to post a comment in response to yours, but apparently this was too long. In addition to that, it is also kind of an answer to your question, so I thought this might be a good thing to just post it as an answer instead. Maybe it even solves your problem.
So, regarding your comment. You don't necessarily have to do it that way. Now, I don't know your system requirements, but I'll just share mine and hope it helps you out.
Save Users and Subscriptions on your server (database tables). Have a check_at column on the Subscriptions table, besides a renew_at one. Suppose the user has a monthly subscription created on the 1st of January. On that first day, you call your server from Android after the purchase is finished, save the subscription details, then set renew_at as February 1st and check_at as February 4th, considering you set 3 days as delay for transaction failure in Google Play Developer Console. This way, the user has time from 1st February to 3rd February to change credit card details if the payment fails on the 1st. Then on the 4th you will check the Google Play API for subscription details. But don't disable premium functionality during 1st-4th February. Disable it on the 4th if the subscription was canceled. This way, premium content is not delayed nor tampered with in any way. If the subscription end date returned by the API is in the future, then it was renewed, so you should keep premium activated. Now, how do you check it monthly on the 4th you may ask. Use some kind of scheduler to schedule tasks on the database.
This way you remove the need to rely on webhooks. Although I agree, webhooks would've been more efficient and probably even easier to implement.
Let me know if you have any questions or there are some flaws in the system I described.
Take a look at Real Time Notifications using Google Cloud's PubSub service. It sends notifications of payment/subscription events like: new buy, renewal, cancellation etc. It includes the token which can be used to retrieve additional info from the API like you do now.
You can also configure this PubSub Subscription to call a custom webhook (which still needs to query the PubSub) on each message that you receive.
I've searched high and low for guidance on how best to address this...
I've read Google Play In-App Subscriptions (http://developer.android.com/google/play/billing/billing_subscriptions.html) and the section on Implementing Subscriptions (http://developer.android.com/google/play/billing/billing_integrate.html#Subs) but I still don't see a way to avoid abuse.
I've also seen the related question here - Google Inapp purchasing and trial period. However, using the SharedPreferences is subject to relatively easy abuse.
I have an app that will require a subscription for full functionality. I set up a monthly subscription in-app purchase product, say ID = "myapp.subscription.monthly", costing $0.99/month.
I want to give people a chance to experience the full functionality, so I give "myapp.subscription.monthly" a 30-day trial period.
When the user installs the app for the first time, they are prompted to purchase the monthly subscription, they are charged $0.00 and told that starting 30 days from now their card will start getting charged $0.99/month.
When my app calls "getPurchases()", the fact that they have a subscription will be returned.
If they cancel during the free trial, or say after a couple of months of billing, a call to "getPurchases()" returns nothing, according to the "Implementing" section:
The call returns a Bundle with all the active subscriptions owned by the user. Once a subscription expires without renewal, it will no longer appear in the returned Bundle.
Since the user has no active subscriptions, my app will prompt them to purchase the subscription for full functionality. Again, they will get the 30-day free trial.
I've thought about having a second subscription product, say "myapp.subscription.monthly.no.free.trial" and I would have that be the available item for purchase. However, without a way to ask Google Play if the user ever previously purchased a subscription, my app can't know that is should be offering the "no free trial" product.
So, how to avoid someone just subscribing and cancelling over and over to keep getting the free 30 days? Is there a way to ask Google Play for the complete purchase history?
According to documentation (https://support.google.com/googleplay/answer/2476088?hl=en, Trial subscriptions), its says:
You can't sign up for multiple trials.
I guess Google automatically handle this
Google Play Store handles this automatically
If your user cancels the free trial and then tries to make a purchase, they will be shown the $0.99 rather than giving a Free trial again. But, if the user pays the $0.99 after canceling the free trial, the actual billing will only start after the canceled Free trial period has ended.
It would have been helpful if there was any way to know whether a product has a free trial or not on the client side. Hope that will be put into the In-App Billing APIs soon.
I am also using in app billing but google always provide one free trial per user.
If u subscribe same sku again then google will not provide trial period to that user.
Scenario:
I am on the verge of completing my google playstore in-app billing implementation. I am using a monthly or yearly subscription in order to charge my consumers.
Problem: I can't seem to find a way to remove a subscription from active state, since cancellation simply stops the billing from occurring. This doesn't allow QA to thoroughly test the purchase procedure without creating an account for each test, or waiting until the subscription period ends.
Question: Have I missed or am wrong about something? If so, what is it? If not, what should be done to allow QA to do proper testing?
According to what I have understood from your question,
you can not test subscription from the test account. Google play doesn't provide subscription testing using dummy product. you have to test on the real product.
Now question arises how can I test subscription
you can check subscription by purchasing real product and check product status or purchase cancellation using the purchase status api from your server.
you can also get more information from the given link below for the step by step cancellation purchase status:
1) link1
2) link2
you can simply query every day and check your subscription is valid or not and also get it's expiration date.
I also have one other option with out pay for any charges on your real product, you can set trial period in the Google console and before trial period ends up cancel subscription from the Google play store Menu -> MyApp -> Subsciption and cancel product and check above procedure given in the links.
EDIT:
Important: In all cases, you must continue to offer the content that
your subscribers have purchased through their subscriptions, for as
long any users are able to access it. That is, you must not remove any
subscriber’s content while any user still has an active subscription
to it, even if that subscription will terminate at the end of the
current billing cycle. Removing content that a subscriber is entitled
to access will result in penalties. Please see the policies document
for more information.
more information check below links:
1)
http://developer.android.com/google/play/billing/billing_subscriptions.html#cancellation
2) https://support.google.com/googleplay/answer/2476088?hl=en
3)
https://support.google.com/googleplay/android-developer/answer/140504?hl=en
You can not done this with out waiting until the subscription process cycle completes after cancellation of subs product, the only way remaining which is Free trial version it's only the way to provide us to test for the product cancellation in which product cancel immediately after you cancel subscription trial period, it will not continue until even trial periods ends.
more information check below link:
http://developer.android.com/google/play/billing/billing_subscriptions.html#administering
And I think it is better way because in the trial period you should go
with the actual credit card payment process but you doesn't need to
pay anything for it. Google play record the transaction as $0.00 for
the subscription process. And if you cancel the subscription the you
should not pay anything for testing, but yes I am not sure free trial version
is worked before you publish the app but it is only get by efforts only.
Conclusion:
In the current api it is not possible to test subcription product like
normal products and if user has been cancel the subscription product
then you have to wait to purchase the same product until the
subscription cycle has been expired, there is no another way if the
subscription cycle is going on and you can test for the same product
again before subscription cycle ends. And if you still want to test
for the same product then you have to choose another account for
testing it or another way is Free trials, you will not be any charged
until your Free trials period expired or cancel subscription in that
period and for the testing account before publish the app you will be refunded
automatically after 14 days of purchased product according to my
knowledge.
Hope it will solve your problem.
I have a horribly clunky workaround for this problem. Here is what I do every time I want to do a test of in-app subscriptions:
Create a new in-app subscription product in the google play developer console.
Point the android app at the new subscription product you just created.
In your code to check for active subscriptions, add a line to specifically ignore the order number of the previous subscription that you tested.
Export a release build of the app and transfer it directly to your testing device.
After testing, return to step #1 to test the next time.
Don't forget to fix your change from step #2 before deploying the app!
You might want to create many subscriptions in step #1 so you don't have to continually wait hours for them to propagate. Please comment if you know of a better way!
UPDATE: Google now has test subscriptions and is making it easier to use them! https://android-developers.googleblog.com/2018/01/faster-renewals-for-test-subscriptions.html
It seems that nowadays there is better solution:
Open your app page in Google Play Store application
Click "Manage subscriptions"
Click "Cancel subscription"
Go to "Settings", "Apps" in your phone.
Find Google Play Store and clear application data.
You should now be able to re-buy subscription.
Create a mock class that mocks out the Google Play methods that you are using.