5

I implemented in-app billing in my mobile app. It uses auto renewing subscription. I want to check the subscription expiry date through the app. I found this link to check the subscription details : Purchases.subscriptions:get

The documentation shows that some authorization needed. I have tried but I am not able to get the result. I got client secret.json file but it does not contain client secret Id. So please help me to get the subscription expiry date.

Jijith J
  • 173
  • 2
  • 12

3 Answers3

2

My answer is late, but maybe it helps somebody else. See my answer here: Server side authorization with Google Play Developer API?

And these are the steps when you would do it manually:

1.) Create credentials in your OAuth2 configuration in Google API with the following link: https://developers.google.com/mobile/add?platform=android&cntapi=signin&cnturl=https:%2F%2Fdevelopers.google.com%2Fidentity%2Fsign-in%2Fandroid%2Fsign-in%3Fconfigured%3Dtrue&cntlbl=Continue%20Adding%20Sign-In

2.) Go to your Developer API console. If you have done the first step correct, the result should look like something like that: Credentials

3.) Go to Google Play Developer Console -> All Apps -> Settings -> API Access and link the project you defined in Developer API Console (step 2, black bar top left). (If you can't link your project in Google Play, because you didn't find some, you used different google accounts for Google Developer API and Google Play Developer Console.)

4.) Invoke the following link with your callback url: https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=http://www.yourdomain.com/oauth2callback&client_id=[WEBAPPLICATION_ID_FROM_ABOVE.apps.googleusercontent.com]
My /oauth2callback script is a simple php script. (This is not production safe. It's just for illustration):

oauth2callback.php

<?php
print_r($_REQUEST);
?>

5.) After you invoked the url from above, you will be asked for your google account and allowance to access the api. After you confirmed, you will be redirected to your callback url and get a result which looks like this:

4/vPv_eYX-az6YucwdpBzATpJEu8129gN9aYsUIMI3qgQ

6.)¹ Get an oauth2 access token and refresh token by invoking a POST request to https://accounts.google.com/o/oauth2/token with the following headers:

grant_type=authorization_code
code=4/vPv_eYX-az6YucwdpBzATpJEu8129gN9aYsUIMI3qgQ
client_id=[YOUR_WEBAPPLICATIONID.apps.googleusercontent.com]
client_secret=[YOUR CLIENT SECRET OF THIS WEBAPPLICATION ID]
redirect_uri=http://www.yourdomain.com/oauth2callback

(The client secret can be found when you click on the Web Client ID of the OAuth2 client IDs in the Developer Console from step 2)

The result will look like this:

{
    "access_token": "ya29.GdsCBbnM584k3SUzoxDgIdaY26pEM_p_AdhkIkFq3tsai8U7x8DuFKq3WEF7KquxkdLO89KHpuUFdJOgkhpGbGyDfxkD32bK1ncnsu2IkA0e_5ZayOEr86u4A1IN",
    "expires_in": 3600,
    "refresh_token": "1/U5HF1m0nHQwZaF2-X35f_xyFaSOofdw3SEubnkkYUQ0",
    "token_type": "Bearer"
}

7.) The access token is needed to invoke the Google Developer API requests, for example: https://www.googleapis.com/androidpublisher/v2/applications/[packageName]/purchases/subscriptions/subscriptionId/tokens/[purchaseToken]?access_token=ya29.GdsCBbnM584k3SUzoxDgIdaY26pEM_p_AdhkIkFq3tsai8U7x8DuFKq3WEF7KquxkdLO89KHpuUFdJOgkhpGbGyDfxkD32bK1ncnsu2IkA0e_5ZayOEr86u4A1IN

8.) The access token expires very quickly. With the refresh you can fetch new access tokens by using the following url and headers: POST https://accounts.google.com/o/oauth2/token

grant_type=refresh_token
client_secret=[YOUR CLIENT SECRET]
refresh_token=1/U5HF1m0nHQwZaF2-X35f_xyFaSOofdw3SEubnkkYUQ0
client_id=[YOUR_WEBAPPLICATION_ID.apps.googleusercontent.com]

Result:

{
    "access_token": "ya29.GlsCBZuN7hYJILi5VaVggIsCIb1_5feGvcjvQFmJRnPYXsnhsi_w3Md87tQwGd_WXmifo4s5739c3IU5INPmby8q64k0LdDFkO2JpNRG13K9sizvU1Sc-3cWzbf8",
    "expires_in": 3600,
    "token_type": "Bearer"
}

HINT (1): If you don't get a refresh token from the request of step 6, attach the following query params to your request: prompt=consent

Bevor
  • 8,396
  • 15
  • 77
  • 141
0

I also struggled a bit with this, but at least I found what needs to be done.

Google provides an android library google-api-services-androidpublishe that can be used to access the Purchase.Subscription.Get API.

implementation 'com.google.apis:google-api-services-androidpublisher:v3-rev74-1.25.0'

Here is a Kotlin code example:

import com.google.api.client.http.apache.ApacheHttpTransport
import com.google.api.client.json.jackson2.JacksonFactory
import com.google.api.services.androidpublisher.AndroidPublisher
...

fun retrieveSubscriptionInfo(sku: String) {

   val packageName = ""
   val sku = ""
   val purchasedSubscriptionToken = ""

   val apacheHttpTransport = ApacheHttpTransport()
   val jacksonJsonFactory = JacksonFactory.getDefaultInstance()

   val AndroidPublisher.Builder(apbacheHttpTransport, jacksonJsonFactory, null).build()

   val request = publisher.Purchases().subscriptions().get(packageName, sku, purchasedSubscriptionToken);

   return request.execute()
}        

Note that before the above code is executed you must first Authorize the AndroidPublisher. You would have to request the users permission in order to be able to query the Purchase.Subscription.Get

Hope that this is helpful.

NewestStackOverflowUser
  • 2,792
  • 5
  • 22
  • 31
  • could you please tell how to authorize Androidpublisher. I read a lot but it is a bit confusing! Thanks in advance – Nadeem Shaikh Jul 13 '20 at 07:38
  • How can I get the purchasedSubscriptionToken? – Wellington Yogui Aug 07 '20 at 13:53
  • The purchase token is returned by Google Play upon purchasing. – NewestStackOverflowUser Aug 07 '20 at 13:59
  • @NewestStackOverflowUser How to authorize for AndroidPublisher ? can you brief on it.. – Jay Rathod Dec 08 '20 at 10:04
  • 1
    @Jay Rathod RJ As far as I understand you would need to implement the OAuth flow of google. You can checkout this post that touches on the topic: https://stackoverflow.com/questions/52471362/how-to-get-authorization-for-accessing-google-play-developer-api But note that the API is usually intended to be used by a backend service and not by the android app. In order to support purchases in android you can use the billing library that google provides without implementing the authorization flow. – NewestStackOverflowUser Dec 09 '20 at 14:12
  • @NewestStackOverflowUser I wanted to use this method from backend itself to manage renew and cancellation flow and to updated related things in backend.. but when i am going to setup this with oAuth client it returns me error always. The project id used to call the Google Play Developer API has not been linked in the Google Play Developer Console. but project is also linked.. – Jay Rathod Dec 09 '20 at 14:20
  • @Jay Rathod RJ Google the error code/message that you receive from the Google Play Developer API and try to resolve it that way. Not sure what error you are receiving. FYI: If you need to update stuff in your backend when a subscription status changes you can use real time developer notifications https://developer.android.com/google/play/billing/rtdn-reference instead of polling the Developer API. – NewestStackOverflowUser Dec 09 '20 at 14:41
  • @NewestStackOverflowUser Thank you for your suggestion but i am not sure about how we implement it either at backend or at app side ? where do we get notified if we setup things at backend ? – Jay Rathod Dec 10 '20 at 13:12
0

Google's documentation here is horrible, no clear examples of implementation. I finally found the answer after a LOT of Googling thanks to @Sabeeh's answer here and lots of other snippets spread out online.

1. First step is to add the dependencies:

implementation "com.google.apis:google-api-services-androidpublisher:v3-rev142-1.25.0" // Update based on latest release
implementation "com.google.auth:google-auth-library-oauth2-http:1.12.1" // Update based on latest release

2. Follow these steps to link the Google Play Console with Google Play Developer API (choose the "Use a service account", not "Use OAuth clients" and follow until "Additional information").

3. Download the services JSON file from your Google Cloud service account (click on the account that you set up in the previous step). You can find/create this file under the "Manage Keys" action or the "Keys" tab. Add the exported JSON file in your assets folder in Android

4. Then you can call the Google Play Developer API to query subscriptions like this (important to call from a Thread, didn't work from the UI thread, not sure why):

new Thread(() -> {
    InputStream inputStream = context.getAssets().open("service_account_google_play.json"); // JSON file from step 3
    GoogleCredentials credentials = GoogleCredentials.fromStream(inputStream)
                    .createScoped(AndroidPublisherScopes.ANDROIDPUBLISHER);
    AndroidPublisher androidPublisher = new AndroidPublisher(
        new NetHttpTransport(),
        JacksonFactory.getDefaultInstance(),
        new HttpCredentialsAdapter(credentials)
    );
    SubscriptionPurchase purchase = androidPublisher.purchases().subscriptions().get(
        context.getPackageName(), subscriptionId, purchaseToken
    ).execute();
    // Do with the purchase object what you want here
}).start();

At the risk of being overly descriptive, the subscriptionId is the ID of your subscription in the Play Console (e.g. subscription_monthly or whatever you called it), and the purchaseToken is the token you get from the Purchase token after querying the BillingClient (querying subscriptions is explained in detail here).

Let me know if anything is unclear or doesn't work yet. This took me 6 hours to figure out and I'm happy to save others that pain.

Jorn Rigter
  • 745
  • 1
  • 6
  • 25