1. Introduction
What you'll build
At the completion of this codelab, you will have a minimum viable website with a working Google Pay integration. This project retrieves a payment token which may sent to a payment service provider for processing.
What you'll learn
- How to load and configure the Google Pay API
- How to display the Google Pay button and handle clicks
- How to request a payment token from Google Pay
What you'll need
- A text editor of your choice to edit HTML and JavaScript files.
- The Google Chrome web browser, or another way to test a local website.
- For production, you will need a Google Pay
merchantId
. It only takes a minute to register at Google Pay & Wallet Console so might as well take care of it now.
Follow along using Project IDX
2. Create the HTML page
Create project files
- Create a folder on your computer named
gpay-web-101
and inside that folder create two empty text files namedindex.html
andmain.js
.Your directory structure should look like this:gpay-web-101/ index.html main.js
- Open
index.html
in your IDE of choice and add the following code:<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Google Pay API for Web 101</title> </head> <body> <div id="gpay-container"></div> <p>Transaction info and errors will be logged to the console.</p> <script type="text/javascript" src="main.js"></script> <script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayLoaded()"> </script> </body> </html>
Code explanation
- An empty DIV is added to the page with the ID
gpay-container
. This DOM element will be the parent element in which the Google Pay button is added. You may position this element in your website's layout where appropriate. - The
main.js
script tag is placed in the DOM after thegpay-container
element. This is necessary to ensure the container DIV is present in the DOM before themain.js
queries for it. Additionally, the script is synchronous to ensure it is loaded beforepay.js
loads asonGooglePayLoaded()
method must exist prior to load completion. There are other ways to achieve the same effect but they won't be discussed here. - Finally,
pay.js
is loaded asynchronously and configuresonGooglePayLoaded()
as it'sonload
handler. This method will be defined inmain.js
.
3. Configure Google Pay
A Google Pay payment request requires a request object. The object defined here as baseGooglePayRequest
contains the minimum common settings for all requests. Additional settings will be added depending on the request made which we'll review in this codelab.
Add the Google Pay configuration constants to the empty main.js
file:
//=============================================================================
// Configuration
//=============================================================================
// The DOM element that the Google Pay button will be rendered into
const GPAY_BUTTON_CONTAINER_ID = 'gpay-container';
// Update the `merchantId` and `merchantName` properties with your own values.
// Your real info is required when the environment is `PRODUCTION`.
const merchantInfo = {
merchantId: '12345678901234567890',
merchantName: 'Example Merchant'
};
// This is the base configuration for all Google Pay payment data requests.
const baseGooglePayRequest = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [
{
type: 'CARD',
parameters: {
allowedAuthMethods: [
"PAN_ONLY", "CRYPTOGRAM_3DS"
],
allowedCardNetworks: [
"AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"
]
},
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'example',
gatewayMerchantId: 'exampleGatewayMerchantId'
}
}
}
],
merchantInfo
};
// Prevent accidental edits to the base configuration. Mutations will be
// handled by cloning the config using deepCopy() and modifying the copy.
Object.freeze(baseGooglePayRequest);
Code explanation
- Set the constant variable
GPAY_BUTTON_CONTAINER_ID
to the Id of the DOM element used on the HTML page as the parent container for the Google Pay button. - Create the configuration object
baseGooglePayRequest
with relevant settings for your application. Each of the properties and values can be found in the reference documentation. The values shown in this example may or may not perfectly match your needs, so review carefully. - Update the
merchantId
andmerchantName
properties with your own values. These fields are optional when the environment isTEST
.
Resources
- Blog post: Want a smoother checkout with Google Pay? Configure your payment options!
- API Reference: Google Pay API request objects documentation
- API Reference: Refer to
PaymentMethod
for more information about the allowed authorization methods, allowed card networks, and tokenization specifications including the proper gateway value.
4. Add payments client
A payments client is used to make payment requests and register callbacks. In this codelab we will only make payment requests. Additionally, you may configure PaymentDataCallbacks
to handle when payment data has changed or authorization has changed. However, these advanced topics are not covered in this codelab.
Append this client code to the bottom of main.js
:
//=============================================================================
// Google Payments client singleton
//=============================================================================
let paymentsClient = null;
function getGooglePaymentsClient() {
if (paymentsClient === null) {
paymentsClient = new google.payments.api.PaymentsClient({
environment: 'TEST',
merchantInfo,
// todo: paymentDataCallbacks (codelab pay-web-201)
});
}
return paymentsClient;
}
Code explanation
- The
paymentsClient
variable will hold the instance to the client once its been created. The variable is not accessed directly by our code, but instead always by thegetGooglePaymentsClient()
method. - The
getGooglePaymentsClient()
method checks to see if a client was already instantiated and returns that instance. If one was not previously instantiated then one is created, saved and returned. This method ensures that only one instance is created and used throughout the lifespan of this script. - To instantiate a client, the
PaymentsClient()
method is invoked. In this example, we're telling the client that we are in aTEST
environment. The alternative isPRODUCTION
. However,TEST
is default and may be omitted.
5. Add helpers
The following helper functions are used later in the script and have been added for the sole purpose of improved code readability and maintainability.
Append the helper functions to the bottom of main.js
:
//=============================================================================
// Helpers
//=============================================================================
const deepCopy = (obj) => JSON.parse(JSON.stringify(obj));
function renderGooglePayButton() {
const button = getGooglePaymentsClient().createButton({
onClick: onGooglePaymentButtonClicked
});
document.getElementById(GPAY_BUTTON_CONTAINER_ID).appendChild(button);
}
Code explanation
deepCopy()
is a utility that uses JSON serialization and deserialization to create a deep copy of the provided object. It's a convenient way to clone objects without worrying about shared references.renderGooglePayButton()
is a utility that invokes thecreateButton()
library method to display the Google Pay button. The passed argument is a set of options that define how the button should behave such as registeringonGooglePaymentButtonClicked()
function to handle button clicks.
6. Add event handlers
In this script we're configuring two event handlers. The first is called when the pay.js
library finishes loading and the other is called when the Google Pay button is clicked.
Append the event handlers to the bottom of main.js
:
//=============================================================================
// Event Handlers
//=============================================================================
function onGooglePayLoaded() {
const req = deepCopy(baseGooglePayRequest);
getGooglePaymentsClient()
.isReadyToPay(req)
.then(function(res) {
if (res.result) {
renderGooglePayButton();
} else {
console.log("Google Pay is not ready for this user.");
}
})
.catch(console.error);
}
function onGooglePaymentButtonClicked() {
// Create a new request data object for this request
const req = {
...deepCopy(baseGooglePayRequest),
transactionInfo: {
countryCode: 'US',
currencyCode: 'USD',
totalPriceStatus: 'FINAL',
totalPrice: (Math.random() * 999 + 1).toFixed(2),
},
// todo: callbackIntents (codelab gpay-web-201)
};
// Write request object to console for debugging
console.log(req);
getGooglePaymentsClient()
.loadPaymentData(req)
.then(function (res) {
// Write response object to console for debugging
console.log(res);
// @todo pass payment token to your gateway to process payment
// @note DO NOT save the payment credentials for future transactions
paymentToken = res.paymentMethodData.tokenizationData.token;
})
.catch(console.error);
}
Code explanation
onGooglePayLoaded()
is invoked whenpay.js
script has completed loading as defined in the HTML file.isReadyToPay()
method is invoked to determine whether or not to show the Google Pay button. If the consumer is ready to pay (meaning they have added a form of payment to their Google Wallet) then the Google Pay button is rendered.onGooglePaymentButtonClicked()
is invoked when the Google Pay button is clicked. This method invokesloadPaymentData()
library method which is used to retrieve a payment token. Once you have the payment token you would send it to your payment gateway for processing the transaction.transactionInfo
describes the transaction that should be processed with this button click.
7. Conclusion
Congratulations on completing this Codelab! You have learned how to integrate the Google Pay APi into a website.
Run the project
Test with Google Chrome
Using the Google Chrome web browser, open index.html
using File > Open File... from Chrome's main menu. Chrome will execute main.js
when the project is opened this way. Other web browsers might not allow JavaScript execution.
– or –
Test with a local web server
If you have Python installed, run python3 -m http.server
from a terminal prompt in the root pay-web-101
folder.
$ cd /your/path/to/pay-web-101
$ python3 -m http.server
Serving HTTP on :: port 8000 (http://[::]:8000/) ...
Then, visit your site at http://localhost:8000
.
Where to go from here
Additional resources
- Join the conversation in the #payments channel on Discord
- Follow @GooglePayDevs on X
- Watch Google Pay related videos on YouTube