How to validate android billing receipt server side

8.6k views Asked by At

I'd like to make server side validation of a purchase receipt made in an android application. I'm using a node.js backend.

I'm currently trying to do it using google-play-purchase-validator node module (https://www.npmjs.org/package/google-play-purchase-validator) which seems the most up-to-date module to do it (performing a real-time request to google purchase api).

In the Google developper console, i created a Google Service Accounts, and then obtained an email and key to be used in the module, I also connect this Services Accounts with my application as explained in this post Use service account to verify Google InAppPurchase). Unfortunatly it doesn't work. It seems that the jwt token generated by the node module isn't correctly signed (I get the following error : failed to sign JWT, the key is probably invalid).

Here's some code :

var Verifier = require('google-play-purchase-validator');
var options = {
  email:'[email protected]',
  key: 'myprivatekey',
};
var verifier = new Verifier(options);
verifier.verify(item.Receipt, function cb(err, response) {
if (err) {
    console.log("there was an error validating the receipt");
    console.log(err);
}
else{
    console.log("sucessfully validated the receipt");
    console.log(response);
}

The private key comes from a .pem file i was able to generate from a .p12 file provided by google using the following command :

openssl pkcs12 -in downloaded-key-file.p12 -out your-key-file.pem -nodes

The google-play-purchase-validator module is based on some others modules (google-oauth-jwt, request, crypto). I tried to debug a little, everything seems to be done correctly.

Any idea where i may be wrong ?

Paul

2

There are 2 answers

2
Subham kuswa On BEST ANSWER

This answer will be only useful once you have followed steps of Above accepted answer. i am using googleapis npm package to validate consumable purchase.

    import { google } from 'googleapis';
    
    const auth = new google.auth.GoogleAuth({
                credentials: {
                    client_email: 'email from json file',
                    private_key:
                        'private key from json file',
                },
                scopes: ['https://www.googleapis.com/auth/androidpublisher'],
            });
            const authClient = await auth.getClient();
            google.options({ auth: authClient });
            try {
// packageName,productId,token you can get from request sent from android
                const purchaseResponse: AndroidPurchaseResponse = await google
                    .androidpublisher({
                        version: 'v3',
                    }).purchases.products.get({
                        packageName: 'packageName',
                        productId: 'productId',
                        token: 'purchaseToken',
                    });
    
                if (purchaseResponse.data.purchaseState !== 0) {
                    throw new BadRequestException('Purchase is either Pending or Cancelled!');
                }
                if (purchaseResponse.data.consumptionState !== 0) {
                    throw new BadRequestException('Purchase is already consumed!');
                }
                if (purchaseResponse.data.orderId !== requestDto.orderId) {
                    throw new BadRequestException('Invalid orderId');
                }
                return purchaseResponse;
            } catch (e) {
                throw new BadRequestException(e);
            }
2
MaxM On

Just added instructions on how to get the correct credentials to the module's Readme.md.

https://www.npmjs.org/package/google-play-purchase-validator

Or find them here:

  1. Start off by going into the google play developer console as the main Administrator of the account (this role is the only one who is allowed to perform the following steps).
  2. Go to "Settings->API Access" to link a Google Developer project to this account.
  3. If you are new here choose "create new project".
  4. You will now have more options. Choose "Create Service Account".
  5. Follow the link to the Google Developer Console and your project
  6. Click "Create new client id" to create a new client ID
  7. Ignore the .p12 file that will be downloaded to your machine and instead click "generate new JSON key".
  8. This will download a JSON file to your machine. We will get back to that file in a second.
  9. Now go back to the play store publisher account and click "done". Your new generate user will appear here.
  10. Click "grant access" and grant the user rights to read your project.
  11. Now setup your Node.JS project with this module and provide the email-address and the private key found in the json file as options to this module.