Unable to get the subscription information from Google Play Android Developer API

android, google-api, google-play, java, subscription

Solution

I got it working! The steps I followed:

Prerequisite

Before start, we need to generate a refresh token. To do this first we have to create an APIs console project:

- Go to the APIs Console and log in with your Android developer account (the same account used in Android Developer Console to upload the APK).

- Select Create project.

- Go to Services in the left-hand navigation panel.

- Turn the Google Play Android Developer API on.

- Accept the Terms of Service.

- Go to API Access in the left-hand navigation panel.

- Select Create an OAuth 2.0 client ID:

- On the first page, you will need to fill in the product name, but a logo is not required.

- On the second page, select web application and set the redirect URI and Javascript origins. We will use it later the redirect URI.

- Select Create client ID. Keep in mind the Client ID and the Client secret, we will use them later.

So, now we can generate the refresh token:

- Go to the following URI (note that the redirect URI must match the value entered in the client ID exactly, including any trailing backslashes):

https://accounts.google.com/o/oauth2/auth?scope=https://www.googleapis.com/auth/androidpublisher&response_type=code&access_type=offline&redirect_uri=REDIRECT_URI&client_id=CLIENT_ID

- Select Allow access when prompted.

- The browser will be redirected to your redirect URI with a code parameter, which will look similar to 4/eWdxD7b-YSQ5CNNb-c2iI83KQx19.wp6198ti5Zc7dJ3UXOl0T3aRLxQmbwI. Copy this value.

Create a main class with:

public static String getRefreshToken(String code)
{

    HttpClient client = new DefaultHttpClient();
    HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
    try 
    {
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
        nameValuePairs.add(new BasicNameValuePair("grant_type",    "authorization_code"));
        nameValuePairs.add(new BasicNameValuePair("client_id",     GOOGLE_CLIENT_ID));
        nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
        nameValuePairs.add(new BasicNameValuePair("code", code));
        nameValuePairs.add(new BasicNameValuePair("redirect_uri", GOOGLE_REDIRECT_URI));
        post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

        org.apache.http.HttpResponse response = client.execute(post);
        BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer buffer = new StringBuffer();
        for (String line = reader.readLine(); line != null; line = reader.readLine())
        {
            buffer.append(line);
        }

        JSONObject json = new JSONObject(buffer.toString());
        String refreshToken = json.getString("refresh_token");                      
        return refreshToken;
    }
    catch (Exception e) { e.printStackTrace(); }

    return null;
}

`GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` and `GOOGLE_REDIRECT_URI` are the previously values.

Finally, we have our refresh token! This value does not expire, so we can store in some site, like a property file.

Accessing to Google Play Android Developer API

Getting the access token. We will need our previosly refresh token:

private static String getAccessToken(String refreshToken){

HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/token");
try 
{
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(4);
    nameValuePairs.add(new BasicNameValuePair("grant_type",    "refresh_token"));
    nameValuePairs.add(new BasicNameValuePair("client_id",     GOOGLE_CLIENT_ID));
    nameValuePairs.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENT_SECRET));
    nameValuePairs.add(new BasicNameValuePair("refresh_token", refreshToken));
    post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    org.apache.http.HttpResponse response = client.execute(post);
    BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    StringBuffer buffer = new StringBuffer();
    for (String line = reader.readLine(); line != null; line = reader.readLine())
    {
        buffer.append(line);
    }

    JSONObject json = new JSONObject(buffer.toString());
    String accessToken = json.getString("access_token");

    return accessToken;

}
catch (IOException e) { e.printStackTrace(); }

return null;

}

Now, we can access to the Android API. I'm interesting in the expiration time of a subscription, so:

private static HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static JsonFactory JSON_FACTORY = new com.google.api.client.json.jackson2.JacksonFactory();

private static Long getSubscriptionExpire(String accessToken, String refreshToken, String subscriptionId, String purchaseToken){

try{

    TokenResponse tokenResponse = new TokenResponse();
    tokenResponse.setAccessToken(accessToken);
    tokenResponse.setRefreshToken(refreshToken);
    tokenResponse.setExpiresInSeconds(3600L);
    tokenResponse.setScope("https://www.googleapis.com/auth/androidpublisher");
    tokenResponse.setTokenType("Bearer");

    HttpRequestInitializer credential =  new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
            .setJsonFactory(JSON_FACTORY)
            .setClientSecrets(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
            .build()
            .setFromTokenResponse(tokenResponse);

    Androidpublisher publisher = new Androidpublisher.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).
            setApplicationName(GOOGLE_PRODUCT_NAME).
            build();

    Androidpublisher.Purchases purchases = publisher.purchases();
    Get get = purchases.get(GOOGLE_PACKAGE_NAME, subscriptionId, purchaseToken);
    SubscriptionPurchase subscripcion = get.execute();

    return subscripcion.getValidUntilTimestampMsec();

}
catch (IOException e) { e.printStackTrace(); }
return null;

}

And that's all!

Some steps are from https://developers.google.com/android-publisher/authorization.

Problem

I'trying to use Google APIs Client Library for Java to get information about user's subscriptions purchased in my android app. Here is how I'm doing for now: ``` HttpTransport HTTP_TRANSPORT = new NetHttpTransport(); JsonFactory JSON_FACTORY = new JacksonFactory(); GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT) .setJsonFactory(JSON_FACTORY) .setServiceAccountId(GOOGLE_CLIENT_MAIL) .setServiceAccountScopes("https://www.googleapis.com/auth/androidpublisher") .setServiceAccountPrivateKeyFromP12File(new File(GOOGLE_KEY_FILE_PATH)) .build(); Androidpublisher publisher = new Androidpublisher.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential). setApplicationName(GOOGLE_PRODUCT_NAME). build(); Androidpublisher.Purchases purchases = publisher.purchases(); Get get = purchases.get("XXXXX", subscriptionId, token); SubscriptionPurchase subscripcion = get.execute(); //Exception returned here ``` `GOOGLE_CLIENT_MAIL` is the email address from API Access from the Google Console. `GOOGLE_KEY_FILE_PATH` is the p12 file downloaded from the API Access. `GOOGLE_PRODUCT_NAME` is the product name from the branding information. In Google APIS Console the Service "Google Play Android Developer API" is enabled. What I'm getting is: ``` { "code" : 401, "errors" : [ { "domain" : "androidpublisher", "message" : "This developer account does not own the application.", "reason" : "developerDoesNotOwnApplication" } ], "message" : "This developer account does not own the application." } ``` I really appreciate your help for this issue...

Original source

Related problems