Am I Getting the Steps Right for Verifying a User's Android In-App Subscription

Am I getting the steps right for verifying a user's Android in-app subscription?

As it turns out, my steps were not correct. It took me weeks to figure this out and it doesn't seem to be documented anywhere else. You're welcome:

  1. Create a Web Application account in the Google APIs Console. Put any website as a "redirect URI"; it doesn't matter since you will not really be using it. You will get a client id and client secret when you create the account.

  2. In a browser on your computer go to https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=[YOUR REDIRECT URI]&client_id=[YOUR CLIENT ID] and allow access when prompted.

  3. Look in the address bar. At the end of the URI you entered originally will be your refresh token. It looks like 1/.... You will need this "code" in the next step. The refresh token never expires.

  4. Convert this "code" to a "refresh token" by going to https://accounts.google.com/o/oauth2/token?client_id=[YOUR CLIENT ID]&client_secret=[YOUR CLIENT SECRET]&code=[CODE FROM PREVIOUS STEP]&grant_type=authorization_code&redirect_uri=[YOUR REDIRECT URI]. You can save the resulting value right in your program; it never expires unless explicitly revoked. (this step inserted by @BrianWhite -- see comments)
    Make sure you are using POST.(inserted by Gintas)

  5. In your code, send an HttpPost request to https://accounts.google.com/o/oauth2/token with the BasicNameValuePairs "grant_type","refresh_token", "client_id",[YOUR CLIENT ID], "client_secret",[YOUR CLIENT SECRET], "refresh_token",[YOUR REFRESH TOKEN]. For an example look here. You will need to do this in a separate thread, probably using AsyncTask. This will return a JSONObject.

  6. Get the access token from the returned JSONObject. For an example look here. You will need to get the string "access_token". The access token expires in 1 hour.

  7. In your code, send an HttpGet request to https://www.googleapis.com/androidpublisher/v1/applications/[YOUR APP'S PACKAGE NAME]/subscriptions/[THE ID OF YOUR PUBLISHED SUBSCRIPTION FROM YOUR ANDROID DEVELOPER CONSOLE]/purchases/[THE PURCHASE TOKEN THE USER RECEIVES UPON PURCHASING THE SUBSCRIPTION]?accesstoken="[THE ACCESS TOKEN FROM STEP 4]". For an example look here.

Am I getting these steps right for checking a user's in-app billing subscription?

Yes I am.

I have successfully implemented in-app billing this way.

How to securely verify a user's subscription to an Android app?

Obfuscate your app code as a minimum. Also do the subscription check on the server, before you send the content. That is one of the reasons they have an Web API.

Basically, anything the user (and potential cracker) has access to (i.e., your app) cannot be trusted. Things they don't have direct access to (i.e., your content server) can be trusted a bit more and it is a good idea to move all sensitive operations and/or data there, where possible.

How to verify purchase for android app in server side (google play in app billing v3)

It sounds what you're looking for is a way to check if the user has premium features enabled on their account, so this is where I would start;

Ensure there is a flag of some sort on your database indicating if the user has premium features and include that in the API response payload when requesting account info. This flag will be your primary authority for "premium features".

When a user makes an in-app purchase, cache the details (token, order id, and product id) locally on the client (i.e the app) then send it to your API.

Your API should then send the purchaseToken to the Google Play Developer API for validation.

A few things might happen from here:

  1. The receipt is valid, your API responds to the client with a 200 Ok status code
  2. The receipt is invalid, your API responds to the client with a 400 Bad Request status code
  3. Google Play API is down, your API responds with a 502 Bad Gateway status code

In the case of 1. or 2. (2xx or 4xx status codes) your client clears the cache of purchase details because it doesn't need it anymore because the API has indicated that it has been received.

Upon a successful validation (case 1.), you should set the premium flag to true for the user.

In the case of 3. (5xx status code) or a network timeout the client should keep trying until it receives a 2xx or 4xx status code from your API.

Depending on your requirements, you could make it wait a few seconds before sending again or just send the details to your API when ever the app is launched again or comes out of background if the purchase details are present on the app cache.

This approach should take care of network timeouts, servers being unavailable, etc.

There are now a few questions you need to consider:

What should happen immediately after a purchase? Should the app wait until validation is successful before providing premium content or should it tentatively grant access and take it away if the validation fails?

Granting tentative access to premium features smooths the process for a majority of your users, but you will be granting access to a number of fraudulent users too while your API validates the purchaseToken.

To put this in another way: Purchase is valid until proven fraudulent or; fraudulent until proven valid?

In order to identify if the user still has a valid subscription when their subscription period comes up for renewal, you will need to schedule a re-validation on the purchaseToken to run at the expiryTimeMillis that was returned in the result.

If the expiryTimeMillis is in the past, you can set the premium flag to false. If it's in the future, re-schedule it again for the new expiryTimeMillis.

Lastly, to ensure the user has premium access (or not), your app should query your API for the users details on app launch or when it comes out of background.

How to check if a user has a subscription (Android in-app billing)?

I believe the answer is a couple of paragraphs above in the same document :

  • Store subscription expiry on your servers

  • Cache expiration and purchaseState

  • Query for subscription status only at expiration

Generally, what they are saying is that you should cache the state of subscription and don't query it each time.

Playstore subscriptions - testing strategy

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.



Related Topics



Leave a reply



Submit