How to Integrate GooglePay in React
Apr 9, 2020 • 13 Minute Read
Introduction
As a developer, you will have to deal with payments when working on e-commerce applications. Fortunately, there are already solutions available for you through legitimate services. One such trusted solution that you'll learn about in this guide is the Google Pay API.
The Google Pay API allows developers to easily integrate a payment method that provides a streamlined, secure, and confidential experience for your users or customers.
Why Use Google Pay
When accepting payments, you'll probably have a checkout form where the user enters shipping and card details. But here's what you'll need to consider: your customers do not remember the 16-digit number, the security code, or the expiration date of their credit or debit card. They may not trust the website, even though it has an SSL certificate and there's a green lock on the address bar. On top of this, your user has to deal with entering the same details on every e-commerce application.
These factors may cause friction for users in the checkout flow and thereby decrease sales. To help you build a seamless and simple checkout process, Google Pay API allows you convenient access to the user's card details saved in their Google account. This way, your users do not have to enter the card details manually into the checkout form—you can programmatically fetch them using the Google Pay API.
Load the Google Pay API JavaScript Library
First, add the script tag to your application's index.html file to load the Google Pay JavaScript library.
<script
async
src="https://pay.google.com/gp/p/js/pay.js"
onload="onGooglePayLoaded()"
></script>
Initialize Google Pay API
As soon as the script is loaded, construct the PaymentsClient object. Begin by instantiating the client object globally in the window object, which you will use to make calls to the Google Pay API from your component later on.
function onGooglePayLoaded() {
window.googlePayClient = new google.payments.api.PaymentsClient({
environment: "TEST"
});
}
The payment client is initialized with a PaymentOptions object. For the TEST environment, you don't need to register with Google. In the TEST environment, Google will give access to real card details, but you won't be able to charge them. To enable actual payments, you need to register with Google for PRODUCTION access.
Configure the Payment Methods
In the App.js file, define the card networks and the authentication methods that will be allowed by your application.
const { googlePayClient } = window;
const baseCardPaymentMethod = {
type: "CARD",
parameters: {
allowedCardNetworks: ["VISA", "MASTERCARD"],
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"]
}
};
Define the API Version
After you have configured the payment methods, define the Google Pay API version that will be used to process the payment, along with the allowedPaymentMethods property to which you need to pass the baseCardPaymentMethod object.
const googlePayBaseConfiguration = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [baseCardPaymentMethod]
};
Determine Readiness to Pay With Google Pay
Now that the payment client is configured and defined, check whether Google Pay API is ready to make payments. This also includes checking whether the API is supported for the current device and browser.
Check the readiness as soon as the component is mounted. If it is a class component, use the componentDidMount() lifecycle method, and if it is a functional component, use the useEffect hook.
function App() {
// ...
useEffect(() => {
googlePayClient
.isReadyToPay(googlePayBaseConfiguration)
.then(res => {
if (res.result) {
createAndRenderPayButton();
} else {
alert("Unable to pay using Google Pay");
}
})
.catch(function (err) {
console.error("Error determining readiness to use Google Pay: ", err);
});
}, []);
// ...
}
The isReadyToPay() method takes in the base configuration as its argument and determine readiness to pay. As it is asynchronous in nature, you need to attach the .then() and .catch() calls to it. If there's a successful response, render the Google Pay Button to the user. Otherwise, show alternative payment methods as a fallback.
Add the Pay With GPay Button
Now, when you know that the user is ready to make a payment, call the second API, createButton(). The createButton() method will return the Pay with GPay button HTML element. You can pass options like buttonColor and buttonType to style the button so that it blends in well with your overall site colors. You can find more info on the options here.
Set the button HTML in your component's state so that it can be rendered by JSX using the dangerouslySetInnerHTML prop.
// ...
const [gPayBtn, setGPayBtn] = useState(null);
function createAndAddButton() {
if (googlePayClient) {
const googlePayButton = googlePayClient.createButton({
buttonColor: "default",
buttonType: "long",
onClick: processPayment
});
setGPayBtn(googlePayButton);
}
}
return (
<div className="App">
<h1>Click the Pay button</h1>
<div
onClick={processPayment}
dangerouslySetInnerHTML={{ __html: gPayBtn && gPayBtn.innerHTML }}
/>
</div>
);
// ...
When the button is clicked, call processPayment(), which will start the payment process.
Payment
Once you add the button to your page and the user clicks on the Google Pay Button, call the loadPaymentData() method to open up the Google Pay payment window. Construct the paymentDataRequest object, which includes a set of payment configurations which will be used for this particular transaction.
function processPayment() {
// ...
googlePayClient
.loadPaymentData(paymentDataRequest)
.then(function (paymentData) {
console.log(paymentData);
})
.catch(function (err) {
console.log(err);
});
}
In addition to the payment credentials, you can also request additional information such as email, phone number, shipping address, billing address, etc.
const cardPaymentMethod = {
type: "CARD",
tokenizationSpecification: tokenizationSpecification,
parameters: {
allowedCardNetworks: ["VISA", "MASTERCARD"],
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
billingAddressRequired: true,
billingAddressParameters: {
format: "FULL",
phoneNumberRequired: true
}
}
};
The transaction and merchant information, along with the base configuration object, should be included in the paymentDataRequest object.
const transactionInfo = {
totalPriceStatus: "FINAL",
totalPrice: "123.45",
currencyCode: "USD"
};
const merchantInfo = {
// merchantId: '01234567890123456789', Only in PRODUCTION
merchantName: "Your Merchant Name"
};
const paymentDataRequest = {
...googlePayBaseConfiguration,
...{
allowedPaymentMethods: [cardPaymentMethod],
transactionInfo,
merchantInfo
}
};
tokenizationSpecification is an object which contains the payment request tokenization parameters. Here, you define which payment gateway you'll be using in your application.
const tokenizationSpecification = {
type: "PAYMENT_GATEWAY",
parameters: {
gateway: "example",
gatewayMerchantId: "gatewayMerchantId"
}
};
In this guide, you'll use the Stripe Processor, but there are a bunch of other options available.
const tokenizationSpecification = {
type: "PAYMENT_GATEWAY",
parameters: {
gateway: "stripe",
"stripe:version": "v3",
"stripe:publishableKey": YOUR_STRIPE_PUBLISHABLE_KEY
}
};
The tokenization specification defines how the payment method chosen by your customers is managed and used to complete a transaction. When you've constructed the request object, pass it to loadPaymentData, an async call which will open a Google payment sheet. After the user makes a selection, Google will return you a paymentData object, which consists of metadata about the user's selection. It includes the payment token, which you can use to complete the transaction. At this point, you have carried out all of the required steps, and your transaction is ready to be completed.
To learn more about handling the card token, check out this Stripe Integration guide.
Complete Source Code
Below you'll find the complete code for your reference.
import React, { useState, useEffect } from "react";
import "./styles.css";
const { googlePayClient } = window;
const baseCardPaymentMethod = {
type: "CARD",
parameters: {
allowedCardNetworks: ["VISA", "MASTERCARD"],
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"]
}
};
const googlePayBaseConfiguration = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [baseCardPaymentMethod]
};
export default function App() {
const [gPayBtn, setGPayBtn] = useState(null);
function createAndAddButton() {
if (googlePayClient) {
const googlePayButton = googlePayClient.createButton({
buttonColor: "default",
buttonType: "long",
onClick: processPayment
});
setGPayBtn(googlePayButton);
}
}
function processPayment() {
console.log("test");
const tokenizationSpecification = {
type: "PAYMENT_GATEWAY",
parameters: {
gateway: "stripe",
"stripe:version": "v3",
"stripe:publishableKey": "pk_test_35p114pH8oNuHX72SmrvsFqh00Azv3ZaIA"
}
};
const cardPaymentMethod = {
type: "CARD",
tokenizationSpecification: tokenizationSpecification,
parameters: {
allowedCardNetworks: ["VISA", "MASTERCARD"],
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
billingAddressRequired: true,
billingAddressParameters: {
format: "FULL",
phoneNumberRequired: true
}
}
};
const transactionInfo = {
totalPriceStatus: "FINAL",
totalPrice: "123.45",
currencyCode: "USD"
};
const merchantInfo = {
// merchantId: '01234567890123456789', Only in PRODUCTION
merchantName: "Example Merchant Name"
};
const paymentDataRequest = {
...googlePayBaseConfiguration,
...{
allowedPaymentMethods: [cardPaymentMethod],
transactionInfo,
merchantInfo
}
};
googlePayClient
.loadPaymentData(paymentDataRequest)
.then(function (paymentData) {
console.log(paymentData);
})
.catch(function (err) {
console.log(err);
});
}
useEffect(() => {
googlePayClient
.isReadyToPay(googlePayBaseConfiguration)
.then(function (response) {
if (response.result) {
createAndAddButton();
} else {
alert("Unable to pay using Google Pay");
}
})
.catch(function (err) {
console.error("Error determining readiness to use Google Pay: ", err);
});
}, []);
return (
<div className="App">
<h1>Click the Pay button</h1>
<div
onClick={processPayment}
dangerouslySetInnerHTML={{ __html: gPayBtn && gPayBtn.innerHTML }}
/>
</div>
);
}
Conclusion
In this guide, you have learned how to implement Google Pay API in your React application. Given the fact that the checkout process can be one of the worst experiences a user faces, you should consider integrating Google Pay with all your e-commerce applications. Remember, Google Pay API won't process the payment; it will be done by a payment processor like Stripe or Paypal. Google Pay plays a vital role in facilitating the exchange of sensitive information between the user and the payment processor.
Hopefully, these basic instructions gave a general overview of the payment process flow with Google Pay and how to implement it with the Google Pay API.