Google Play In App Purchase Validation in Node.js
How to validate in-app purchases server side for Google Play apps
Introduction
In-app purchase validation is a critical task that every app supporting purchases and subscription should implement as a means to prove the integrity of purchase tokens and transaction records. Validation can be used to validate a newly created transaction or validate a subscription to check it is still active.
An in-app purchase is initiated on a user’s device; the user authenticates a purchase which is then processed on Google servers, and a successful response should be sent back to the user’s device.
It is with this successful response that a purchaseToken
is provided — a unique string that acts as a receipt of the purchase. In order to validate a purchase with Google Billing at any time in the future, the purchaseToken
must be supplied to such API calls, that will be discussed further down.
Needless to say, the purchaseToken
should be securely persisted in your database and associated with a particular user of your app, otherwise it would not be possible to validate any purchases made by that user.
This article will explain the setup process of validating Google Play in-app purchases. It is split into two parts:
- Part 1: Walking through the process of setting up the necessary credentials on Google Cloud Platform and Google Play Console for in-app purchase receipt validation. This entails a Service Account with access to Google Play developer services to access in-app purchase history, that exists under the financial data umbrella of permissions.
- Part 2 will demonstrate how to integrate the
google-play-billing-valida
tor package in a Node.js environment in order to validate receipts server side on your server at any time. Both apurchaseToken
andproductId
need to be provided, along with your App ID, to successfully validate an in-app purchase or subscription.
Note that google-play-billing-valida
tor (or other means of validation) should also be used in the initial transaction processing stage after a purchaseToken
is generated and sent to your endpoint that processes successful in-app purchases. This initial validation can be achieved with the code we’ll discuss further down.
This piece focuses on the validating purchases after they have been made. If you are looking for detailed instructions on how to set up in-app purchases and subscriptions for React Native, check out my published piece: In App Purchases and Subscriptions in React Native: 2021 Walkthrough.
Before delving into Node.js, some setup is required on the Google Play side in order to gain API access to your app’s in-app purchase history. Let’s cover this setup process next.
Gaining API Access to In App Purchases
The prerequisites of setting up API Access for your in-app purchases are:
- Access to the Google Play Console where your apps are hosted. Signing up to Google Play requires a one-off fee of $25.
- A Google Cloud Platform account, that could either be on a free trial or fully activated account.
Setting up a GCP project and service account
This section will summarise the important steps for our in-app purchase validation requirements. Google provide instructions for this initial setup here; a page worth visiting for new users.
From your Google Play Console, find the API Access option under the Setup menu. Alternatively, search for API Access in the search bar.
If you are accessing the API Access page for the first time you will need to accept some terms and conditions as well as create a project on Google Cloud Platform. Click Create new project to do just that — the project will automatically be generated and linked to your Google Play Console.
So what just happened with this automated project generation? Google set up a pre-configured project with all the necessary roles enabled for Google Play access (as well as access to the majority of their cloud services).
If you visit the Roles menu option from Google Cloud Platform you can see quite an exhaustive list of roles, that created service accounts under the project can inherit from:
In any case, with the GCP project now created you are able to add a service account that will act as the identity accessing in-app purchase data when making API calls.
Back in Google Play Console, the following dashboard is now presented on the API Access page:
Under the Service Accounts section, click Create new service account. This opens a modal that provides instructions on how to set up the service account from your Google Cloud Platform console:
A service account can be thought of as an identity that can be configured to have access to various APIs in the Google ecosystem. Service accounts are Google’s solution for access control.
Once a service account is created, the private key and email address associated with the service account can be used to make API requests to the granted services.
Follow the instructions presented in the above modal and ensure that you download your private key file; a JSON file containing credentials needed to make API requests when using google-play-billing-valida
tor.
We will be interested in the private_key
and client_email
fields within this file.
Once your service account is created we can verify that it has been successfully linked to Google Play. Not only will the account be under Service accounts in API Access, but also in Users and permissions, that can be found in the Google Play Console main menu:
Clicking the blue arrow next to the service account and opening the Account permissions tab will reveal the account permissions the service account has been granted (you can also toggle the permissions from here).
Notice that the account has full access to the financial data items, giving the service account access to IAP history, subscriptions and order management:
Here is where things begin to make sense in regards to in-app purchases; the service account is now configured and we can start communicating with the data.
Integrating Google Play Billing Validator
google-play-billing-valida
tor works well for both REST APIs and standalone Node.js processes. Install the package with NPM or yarn:
yarn add google-play-billing-validator
The version installed at the time of writing was 2.1.3
.
Firstly, import the package along with your private key file for authenticating with the API service.
// import validator and private key
const GoogleReceiptVerify = require('google-play-billing-validator')
const ServiceAccount = require('./service-account-key')
Do not commit your private key file to source control, SSH into your server to securely embed the file.
Instantiate a new GoogleReceiptVerify
object from the package, feeding in your private_key
and client_email
fields from your private key file as an argument:
// instantiate google receipt verify
var googleReceiptVerify = new GoogleReceiptVerify({
email: ServiceAccount.client_email,
key: ServiceAccount.private_key
});
From here we can either call the googleReceiptVerify.verifyINAPP
method to validate a one-time purchase, or googleReceiptVerify.verifySub
to validate a subscription. Both API calls require the Product ID as well as the purchase token that was generated at the time of the initial purchase.
The following code provides a solution for the verifySub
call, that sources the expiry timestamp from the response payload
: