Comrades, I present a ready-made JavaScript module for making payments using Google Pay. The module is supposed to be used in a modern npm development environment with export-import, however, those who want pure ES5, I think, can easily remake it.
Link to module. The code contains the necessary documentation and comments. Here I will give some explanations.
I must say that the Google documentation specifically for the payment button turned out to be not the simplest, and the list of errors returned by the Google Pay API is also not the most complete. Therefore, unlike working with ApplePay, with Google Pay we had to fiddle around a little before the module actually worked.
The work consists of two stages: first we must decide whether to show the button or not (not all browsers support Google Pay), and then perform the payment processing itself.
1. Show button
There's nothing complicated here. In options we pass two parameters - googleBaseCardPaymentMethod and environment.
googleBaseCardPaymentMethod is an object that lists payment types and parameters (more details here on the allowed search ). If it is not set, we call the standard setter in the code, which returns us a generic object:
environment is the environment, PRODUCTION or TEST
When calling the success callback, we actually draw (or show an already drawn) button. It's your choice. Just remember that Google requires compliance with its guides.
2. Processing
To display the Google Pay button, your browser's API created a paymentsClient object , which now, along with other parameters, needs to be passed to the processing function. Let's look at other parameters:
googleBaseCardPaymentMethod - see above
googlePayPublicKey, merc_id, merc_name - to successfully work with Google Pay you must have a registered merchant. We get its parameters then back.
In addition, we pass success and fail callbacks, as well as data for making a payment (see below).
So, to make a payment, we must take the previously created paymentsClient object and call its loadPaymentData method with the paymentDataRequest object : const paymentDataRequest = getGooglePaymentDataRequest() :
For a test environment, Google offers its merchantInfo object. It must be used with exactly the merchantId that is written in the example; merchantName is not essential.
Additionally, we need a token object :
→ Read more about the parameters here Next, when the object is formed, a request is sent to the Google server
using the loadPaymentData method, a frame with saved maps is opened, and after the operation is completed, the frame is closed:
After successfully completing the method (that is, calling the saved cards and passing verification), we can make an AJAX request to our own back in order to make a payment using Google Pay. In this request, we will need to pass the googleToken that came from Google , as well as the public key.
That's it, our Google Pay payment took place after processing on the back!
Link to module. The code contains the necessary documentation and comments. Here I will give some explanations.
I must say that the Google documentation specifically for the payment button turned out to be not the simplest, and the list of errors returned by the Google Pay API is also not the most complete. Therefore, unlike working with ApplePay, with Google Pay we had to fiddle around a little before the module actually worked.
The work consists of two stages: first we must decide whether to show the button or not (not all browsers support Google Pay), and then perform the payment processing itself.
1. Show button
Code:
export function showGooglePayButton(options, callbacks) {
// checking parameters
const check = checkParams("showGooglePayButton", options, callbacks);
if (!check) {
return false;
} else {
options = check.options;
}
const paymentsClient = new google.payments.api.PaymentsClient({environment: options.environment});
// in the application we remember the instance of the payment client that the API created
callbacks.setPaymentClient(paymentsClient);
const request = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [options.googleBaseCardPaymentMethod]
};
paymentsClient.isReadyToPay(request)
.then(function(response) {
if (response.result) {
callbacks.success();
return true;
} else {
console.log("The request to show the Google Pay button failed");
callbacks.fail();
}
})
.catch(function(err) {
console.log("showGooglePayButton ERROR");
callbacks.fail();
});
}
There's nothing complicated here. In options we pass two parameters - googleBaseCardPaymentMethod and environment.
googleBaseCardPaymentMethod is an object that lists payment types and parameters (more details here on the allowed search ). If it is not set, we call the standard setter in the code, which returns us a generic object:
Code:
const setGoogleBaseCardPaymentMethod = () => {
return {
type: "CARD",
parameters: {
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
allowedCardNetworks: ["AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"]
}
}
};
environment is the environment, PRODUCTION or TEST
When calling the success callback, we actually draw (or show an already drawn) button. It's your choice. Just remember that Google requires compliance with its guides.
2. Processing
To display the Google Pay button, your browser's API created a paymentsClient object , which now, along with other parameters, needs to be passed to the processing function. Let's look at other parameters:
googleBaseCardPaymentMethod - see above
googlePayPublicKey, merc_id, merc_name - to successfully work with Google Pay you must have a registered merchant. We get its parameters then back.
In addition, we pass success and fail callbacks, as well as data for making a payment (see below).
So, to make a payment, we must take the previously created paymentsClient object and call its loadPaymentData method with the paymentDataRequest object : const paymentDataRequest = getGooglePaymentDataRequest() :
Code:
const getGooglePaymentDataRequest = () => {
const cardPaymentMethod = Object.assign(
{},
baseMethod,
{
tokenizationSpecification: token
}
);
const paymentDataRequest = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods : [cardPaymentMethod],
/* for demo (enviroment TEST):
merchantInfo : {
merchantId: '12345678901234567890',
merchantName: 'JOHN SMITH'
},
*/
/* for prod (enviroment PRODUCTION):
merchantInfo : {
merchantId: options.merc_id,
merchantName: options.merc_name
},
*/
merchantInfo : {
merchantId: options.merc_id,
merchantName: options.merc_name
},
transactionInfo : {
currencyCode: options.currency,
totalPriceStatus: 'FINAL',
totalPrice: "" + options.sum
}
};
return paymentDataRequest;
};
For a test environment, Google offers its merchantInfo object. It must be used with exactly the merchantId that is written in the example; merchantName is not essential.
Additionally, we need a token object :
Code:
const token = {
/* for demo (enviroment TEST):
parameters: {
"protocolVersion": "ECv1",
"publicKey": yourTestPublicKey
}
*/
/* for prod (enviroment PRODUCTION):
parameters: {
"protocolVersion": "ECv1",
"publicKey": params.googlePayPublicKey
}
*/
type: 'DIRECT',
parameters: {
"protocolVersion": "ECv1",
"publicKey": options.googlePayPublicKey
}
};
→ Read more about the parameters here Next, when the object is formed, a request is sent to the Google server
using the loadPaymentData method, a frame with saved maps is opened, and after the operation is completed, the frame is closed:
Code:
paymentsClient.loadPaymentData(paymentDataRequest)
.then(function(paymentData) {
const googleToken = JSON.parse(paymentData.paymentMethodData.tokenizationData.token);
// your own client-back ajax request here
}
After successfully completing the method (that is, calling the saved cards and passing verification), we can make an AJAX request to our own back in order to make a payment using Google Pay. In this request, we will need to pass the googleToken that came from Google , as well as the public key.
That's it, our Google Pay payment took place after processing on the back!