Created
December 23, 2020 16:27
-
-
Save haigopi/3e1cc439e081e4df2d38db5457bae72b to your computer and use it in GitHub Desktop.
VueJS Integration with Google Pay
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vue from 'vue'; | |
declare let google: any | |
export default class GooglePayUtils extends Vue { | |
name = 'GooglePayUtils: '; | |
googlePayURL = 'https://pay.google.com/gp/p/js/pay.js'; | |
private static _instance: GooglePayUtils; | |
private constructor() { | |
super(); | |
} | |
public static getInstance(): GooglePayUtils { | |
return this._instance || (this._instance = new GooglePayUtils()); | |
} | |
baseRequest = { | |
apiVersion: 2, | |
apiVersionMinor: 0 | |
}; | |
allowedCardNetworks = ["AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"]; | |
allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"]; | |
tokenizationSpecification = { | |
type: 'PAYMENT_GATEWAY', | |
parameters: { | |
'gateway': 'example', | |
'gatewayMerchantId': 'exampleGatewayMerchantId' | |
} | |
}; | |
baseCardPaymentMethod = { | |
type: 'CARD', | |
parameters: { | |
allowedAuthMethods: this.allowedCardAuthMethods, | |
allowedCardNetworks: this.allowedCardNetworks | |
} | |
}; | |
cardPaymentMethod = Object.assign( | |
{}, | |
this.baseCardPaymentMethod, | |
{ | |
tokenizationSpecification: this.tokenizationSpecification | |
} | |
); | |
paymentsClient: any = null; | |
getGoogleIsReadyToPayRequest() { | |
return Object.assign( | |
{}, | |
this.baseRequest, | |
{ | |
allowedPaymentMethods: [this.baseCardPaymentMethod] | |
} | |
); | |
} | |
getGooglePaymentDataRequest() { | |
const paymentDataRequest: any = Object.assign({}, this.baseRequest); | |
paymentDataRequest.allowedPaymentMethods = [this.cardPaymentMethod]; | |
paymentDataRequest.transactionInfo = this.getGoogleTransactionInfo(); | |
paymentDataRequest.merchantInfo = { | |
// @todo a merchant ID is available for a production environment after approval by Google | |
// See {@link https://developers.google.com/pay/api/web/guides/test-and-deploy/integration-checklist|Integration checklist} | |
// merchantId: '01234567890123456789', | |
merchantName: 'Example Merchant' | |
}; | |
return paymentDataRequest; | |
} | |
getGooglePaymentsClient() { | |
if (this.paymentsClient === null) { | |
this.paymentsClient = new google.payments.api.PaymentsClient({ environment: 'TEST' }); | |
} | |
return this.paymentsClient; | |
} | |
onGooglePayLoaded() { | |
console.debug('**---> Google Pay Script Loaded: '); | |
const paymentsClient = this.getGooglePaymentsClient(); | |
this.paymentsClient?.isReadyToPay(this.getGoogleIsReadyToPayRequest()) | |
.then(response => { | |
console.debug('**---> 1', response); | |
if (response.result) { | |
console.debug('**---> 2', response, this); | |
this.addGooglePayButton(); | |
// @todo prefetch payment data to improve performance after confirming site functionality | |
//this.prefetchGooglePaymentData(); | |
} | |
}) | |
.catch(function (err) { | |
// show error in developer console for debugging | |
console.error(err); | |
}); | |
} | |
addGooglePayButton() { | |
const paymentsClient = this.getGooglePaymentsClient(); | |
const button = | |
paymentsClient.createButton({ onClick: this.onGooglePaymentButtonClicked }); | |
this.createGoogleContainerIfNotAvailable(); | |
console.log(document.getElementById('google-button-container')); | |
document.getElementById('google-button-container')?.appendChild(button); | |
} | |
public createGoogleContainerIfNotAvailable() { | |
if (document.getElementById('google-button-container')) { | |
console.log('Container Avaibale'); | |
return; | |
} else { | |
const superParent = document.getElementById('googleParent'); | |
const parent = document.createElement('div'); | |
parent.setAttribute('id', 'googleButtons'); | |
superParent?.appendChild(parent); | |
const child = document.createElement('div'); | |
child.setAttribute('id', 'google-button-container'); | |
parent?.appendChild(child); | |
} | |
} | |
getGoogleTransactionInfo() { | |
return { | |
countryCode: 'US', | |
currencyCode: 'USD', | |
totalPriceStatus: 'FINAL', | |
// set to cart total | |
totalPrice: '1.00' | |
}; | |
} | |
prefetchGooglePaymentData() { | |
const paymentDataRequest = this.getGooglePaymentDataRequest(); | |
// transactionInfo must be set but does not affect cache | |
paymentDataRequest.transactionInfo = { | |
totalPriceStatus: 'NOT_CURRENTLY_KNOWN', | |
currencyCode: 'USD' | |
}; | |
const paymentsClient = this.getGooglePaymentsClient(); | |
paymentsClient.prefetchPaymentData(paymentDataRequest); | |
} | |
onGooglePaymentButtonClicked(event) { | |
const comp = GooglePayUtils.getInstance(); | |
const paymentDataRequest = comp.getGooglePaymentDataRequest(); | |
paymentDataRequest.transactionInfo = comp.getGoogleTransactionInfo(); | |
const paymentsClient = comp.getGooglePaymentsClient(); | |
paymentsClient.loadPaymentData(paymentDataRequest) | |
.then(function (paymentData) { | |
// handle the response | |
comp.processPayment(paymentData); | |
}) | |
.catch(function (err) { | |
// show error in developer console for debugging | |
console.error(err); | |
}); | |
} | |
processPayment(paymentData) { | |
// show returned data in developer console for debugging | |
console.log(paymentData); | |
// @todo pass payment token to your gateway to process payment | |
const paymentToken = paymentData.paymentMethodData.tokenizationData.token; | |
console.log(paymentData, paymentToken); | |
} | |
public createPayPalButtons() { | |
console.log('Asking to load the google pay script..'); | |
Vue.prototype | |
.$loadScript(this.googlePayURL, { | |
}) | |
.then(() => { | |
this.onGooglePayLoaded() | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment