<script async src="https://pay.google.com/gp/p/js/pay.js"
onload="onGooglePayLoaded()"></script>
<div id="container"></div>
<input type="button" id="container" onclick="onGooglePayLoaded()" value="Add a Google Pay button and press on it!"></input>
const baseRequest = {
apiVersion: 2,
apiVersionMinor: 0
};
const allowedCardNetworks = ["AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"];
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];
const tokenizationSpecification = {
type: 'PAYMENT_GATEWAY',
parameters: {
'gateway': 'example',
'gatewayMerchantId': 'exampleGatewayMerchantId'
}
};
const baseCardPaymentMethod = {
type: 'CARD',
parameters: {
allowedAuthMethods: allowedCardAuthMethods,
allowedCardNetworks: allowedCardNetworks
}
};
const cardPaymentMethod = Object.assign(
{},
baseCardPaymentMethod,
{
tokenizationSpecification: tokenizationSpecification
}
);
let paymentsClient = null;
function getGoogleIsReadyToPayRequest() {
return Object.assign(
{},
baseRequest,
{
allowedPaymentMethods: [baseCardPaymentMethod]
}
);
}
function getGooglePaymentDataRequest() {
const paymentDataRequest = Object.assign({}, baseRequest);
paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod];
paymentDataRequest.transactionInfo = getGoogleTransactionInfo();
paymentDataRequest.merchantInfo = {
merchantName: 'Example Merchant'
};
paymentDataRequest.callbackIntents = ["PAYMENT_AUTHORIZATION"];
return paymentDataRequest;
}
function getGooglePaymentsClient() {
if ( paymentsClient === null ) {
paymentsClient = new google.payments.api.PaymentsClient({
environment: 'TEST',
paymentDataCallbacks: {
onPaymentAuthorized: onPaymentAuthorized
}
});
}
return paymentsClient;
}
function onPaymentAuthorized(paymentData) {
return new Promise(function(resolve, reject){
// handle the response
processPayment(paymentData)
.then(function() {
resolve({transactionState: 'SUCCESS'});
})
.catch(function() {
resolve({
transactionState: 'ERROR',
error: {
intent: 'PAYMENT_AUTHORIZATION',
message: 'Insufficient funds, try again. Next attempt should work.',
reason: 'PAYMENT_DATA_INVALID'
}
});
});
});
}
function onGooglePayLoaded() {
const paymentsClient = getGooglePaymentsClient();
paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest())
.then(function(response) {
if (response.result) {
addGooglePayButton();
}
})
.catch(function(err) {
console.error(err);
});
}
function addGooglePayButton() {
const paymentsClient = getGooglePaymentsClient();
const button =
paymentsClient.createButton({onClick: onGooglePaymentButtonClicked});
document.getElementById('container').appendChild(button);
}
function getGoogleTransactionInfo() {
return {
displayItems: [
{
label: "Subtotal",
type: "SUBTOTAL",
price: "11.00",
},
{
label: "Tax",
type: "TAX",
price: "1.00",
}
],
countryCode: 'RO',
currencyCode: "EUR",
totalPriceStatus: "FINAL",
totalPrice: "1.00",
totalPriceLabel: "Total"
};
}
function onGooglePaymentButtonClicked() {
const paymentDataRequest = getGooglePaymentDataRequest();
paymentDataRequest.transactionInfo = getGoogleTransactionInfo();
const paymentsClient = getGooglePaymentsClient();
paymentsClient.loadPaymentData(paymentDataRequest);
}
let attempts = 0;
function processPayment(paymentData) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
paymentToken = paymentData.paymentMethodData.tokenizationData.token;
if (attempts++ % 2 == 0) {
reject(new Error('Every other attempt fails, next one should succeed'));
} else {
resolve({});
}
}, 500);
});
}
This Pen doesn't use any external CSS resources.