Reputation: 63
I am working on an Android application with Google Play in-app purchases. I also have a server application(JAVA) working in the background. Whenever the user successfully makes a purchase in the app(purchasing is working), the server application should send a request to Google play to verify the purchase.
Google Play is offering the androidpublisher api for that: developers.google.com/android-publisher/getting_started
The problem is the access_token. Whenever I obtain a new access_token(either with the refresh or new token requesting method), it doesn't work, if I try to use the GET method to ask the information from a purchase inapp item from Google play store(https://developers.google.com/android-publisher/v1/purchases/get) -> it always results in error 401(invalid credential) or 403(access not configured).
after endless trying I find out that I only can get the method working with that link: https://developers.google.com/apis-explorer/#p/androidpublisher/v1.1/androidpublisher.inapppurchases.get, and I can only read the valid access_token from there, and only with that token I can get my server application working but only for one hour, after 1 hour I have to do the same step again...
now I really need a proper way to get a valid access_token with my application
I have researched a lot on internet but I couldn't find something useful. I know that I am not the only one with that problem, maybe someone of you guys know what to do or has already experience with that
Upvotes: 2
Views: 2356
Reputation: 5791
You can use com.google.api-client
and google-api-services-androidpublisher
libraries.
First go to the project on google developer console (https://console.developers.google.com)
Then add the just generated email address for the service account to your google play developer console (https://play.google.com/apps/publish/)
@developer.gserviceaccount.com
email account Now to the code. Add the following dependencies to your pom.xml file:
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.18.0-rc</version>
</dependency>
<dependency>
<groupId>com.google.http-client</groupId>
<artifactId>google-http-client-jackson2</artifactId>
<version>1.18.0-rc</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-androidpublisher</artifactId>
<version>v1.1-rev25-1.18.0-rc</version>
</dependency>
Then first validate the signature:
byte[] decoded = BASE64DecoderStream.decode(KEY.getBytes());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(decoded));
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initVerify(publicKey);
sig.update(signedData.getBytes());
if (sig.verify(BASE64DecoderStream.decode(signature.getBytes())))
{
// Valid
}
If the signature verifies fetch subscription details:
// fetch signature details from google
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(ACCOUNT_ID)
.setServiceAccountScopes(Collections.singleton("https://www.googleapis.com/auth/androidpublisher"))
.setServiceAccountPrivateKeyFromP12File(new File("key.p12"))
.build();
AndroidPublisher pub = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential)
.setApplicationName(APPLICATION_NAME)
.build();
AndroidPublisher.Purchases.Get get = pub.purchases().get(
APPLICATION_NAME,
PRODUCT_ID,
token);
SubscriptionPurchase subscription = get.execute();
System.out.println(subscription.toPrettyString());
This will take care of all the token issues by generating a JWT token so you don't have to handle it yourself.
Upvotes: 1