Developer Portal
14 Appendix A: GooglePay Javascript
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ /** * Define the version of the Google Pay API referenced when creating your * configuration * * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentDataRequest|apiVersion in PaymentDataRequest} */ const baseRequest = { apiVersion: 2, apiVersionMinor: 0 }; /** * Card networks supported by your site and your gateway * * @see {@link https://developers.google.com/pay/api/web/reference/object#CardParameters|CardParameters} * @todo confirm card networks supported by your site and gateway */ const allowedCardNetworks = ["AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"]; /** * Card authentication methods supported by your site and your gateway * * @see {@link https://developers.google.com/pay/api/web/reference/object#CardParameters|CardParameters} * @todo confirm your processor supports Android device tokens for your * supported card networks */ const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"]; /** * Identify your gateway and your site's gateway merchant identifier * * The Google Pay API response will return an encrypted payment method capable * of being charged by a supported gateway after payer authorization * * @todo check with your gateway on the parameters to pass * @see {@link https://developers.google.com/pay/api/web/reference/object#Gateway|PaymentMethodTokenizationSpecification} */ const tokenizationSpecification = { type: 'PAYMENT_GATEWAY', parameters: { 'gateway': 'payway', 'gatewayMerchantId' : 'BCR2DN6T7OL6ZBJG' //'gatewayMerchantId' : '123123123' } }; /** * Describe your site's support for the CARD payment method and its required * fieldsfau * * @see {@link https://developers.google.com/pay/api/web/reference/object#CardParameters|CardParameters} */ const baseCardPaymentMethod = { type: 'CARD', parameters: { allowedAuthMethods: allowedCardAuthMethods, allowedCardNetworks: allowedCardNetworks, billingAddressRequired: true, billingAddressParameters: { format : 'MIN', // 'FULL' for complete address info phoneNumberRequired : false } } }; /** * Describe your site's support for the CARD payment method including optional * fields * * @see {@link https://developers.google.com/pay/api/web/reference/object#CardParameters|CardParameters} */ const cardPaymentMethod = Object.assign( {}, baseCardPaymentMethod, { tokenizationSpecification: tokenizationSpecification } ); /** * An initialized google.payments.api.PaymentsClient object or null if not yet set * * @see {@link getGooglePaymentsClient} */ let paymentsClient = null; /** * Configure your site's support for payment methods supported by the Google Pay * API. * * Each member of allowedPaymentMethods should contain only the required fields, * allowing reuse of this base request when determining a viewer's ability * to pay and later requesting a supported payment method * * @returns {object} Google Pay API version, payment methods supported by the site */ function getGoogleIsReadyToPayRequest() { return Object.assign( {}, baseRequest, { allowedPaymentMethods: [baseCardPaymentMethod] } ); } /** * Configure support for the Google Pay API * * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentDataRequest|PaymentDataRequest} * @returns {object} PaymentDataRequest fields */ function getGooglePaymentDataRequest() { const paymentDataRequest = Object.assign({}, baseRequest); paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod]; paymentDataRequest.transactionInfo = 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: '<YOUR MERCHANT ID FROM GOOGLE>', merchantName: '<YOUR MERCHANT NAME>' }; return paymentDataRequest; } /** * Return an active PaymentsClient or initialize * * @see {@link https://developers.google.com/pay/api/web/reference/client#PaymentsClient|PaymentsClient constructor} * @returns {google.payments.api.PaymentsClient} Google Pay API client **/ function getGooglePaymentsClient() { if ( paymentsClient === null ) { console.log ( "getGooglePaymentsClient: create new client" ) ; paymentsClient = new google.payments.api.PaymentsClient({environment: 'TEST'}); } console.log ( "getGooglePaymentsClient: google pay client returned" ) ; return paymentsClient; } /** * Initialize Google PaymentsClient after Google-hosted JavaScript has loaded * * Display a Google Pay payment button after confirmation of the viewer's * ability to pay. */ function onGooglePayLoaded() { console.log ( "load google pay client" ) ; try { const paymentsClient = getGooglePaymentsClient(); } catch ( err ) { console.log ( err ) ; return ; } console.log ( "Check if ready for google pay" ) ; paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest()) .then(function(response) { if (response.result) { addGooglePayButton(); // @todo prefetch payment data to improve performance after confirming site functionality // prefetchGooglePaymentData(); } }) .catch(function(err) { // show error in developer console for debugging console.log("onGooglePayLoaded" ) ; alert ( err ) ; }); } /** * Add a Google Pay purchase button alongside an existing checkout button * * @see {@link https://developers.google.com/pay/api/web/reference/object#ButtonOptions|Button options} * @see {@link https://developers.google.com/pay/api/web/guides/brand-guidelines|Google Pay brand guidelines} */ function addGooglePayButton() { if ( document.getElementById('googleButton') === null ) { console.log ( "No googleButton on page, skip add google pay button" ) ; return ; } const paymentsClient = getGooglePaymentsClient(); const button = paymentsClient.createButton({onClick: onGooglePaymentButtonClicked, buttonColor: "white" } ); document.getElementById('googleButton').appendChild(button); } /** * Provide Google Pay API with a payment amount, currency, and amount status * * @see {@link https://developers.google.com/pay/api/web/reference/object#TransactionInfo|TransactionInfo} * @returns {object} transaction info, suitable for use as transactionInfo property of PaymentDataRequest */ function getGoogleTransactionInfo() { return { currencyCode: 'USD', totalPriceStatus: 'FINAL', // set to cart total totalPrice: '1.00' }; } /** * Prefetch payment data to improve performance * * @see {@link https://developers.google.com/pay/api/web/reference/client#prefetchPaymentData|prefetchPaymentData()} */ function prefetchGooglePaymentData() { console.log ( "get google payment data request" ) ; const paymentDataRequest = getGooglePaymentDataRequest(); // transactionInfo must be set but does not affect cache paymentDataRequest.transactionInfo = { totalPriceStatus: 'NOT_CURRENTLY_KNOWN', currencyCode: 'USD' }; const paymentsClient = getGooglePaymentsClient(); console.log ( "pre fetch payment data" ) ; paymentsClient.prefetchPaymentData(paymentDataRequest); } /** * Show Google Pay payment sheet when Google Pay payment button is clicked */ function onGooglePaymentButtonClicked() { console.log ( "OnGooglePaymentButtonClicked: get google payment data request" ) ; const paymentDataRequest = getGooglePaymentDataRequest(); paymentDataRequest.transactionInfo = getGoogleTransactionInfo(); console.log ( "OnGooglePaymentButtonClicked: " + JSON.stringify ( paymentDataRequest ) ) ; const paymentsClient = getGooglePaymentsClient(); paymentsClient.loadPaymentData(paymentDataRequest) .then(function(paymentData) { // handle the response processPayment(paymentData); }) .catch(function(err) { // show error in developer console for debugging console.error(err); }); } /** * Process payment data returned by the Google Pay API * * @param {object} paymentData response from Google Pay API after user approves payment * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentData|PaymentData object reference} */ function processPayment(paymentData) { console.log( paymentData ) ; paymentToken = paymentData.paymentMethodData.tokenizationData.token; console.log( paymentToken.toString() ) ; var request = new XMLHttpRequest() ; request.onload = function() { try { JSON.parse ( request.responseText ) ; } catch ( err ) { console.log ( "Payment error" ) ; console.error ( err ) ; } if (request.status === 200 ) { console.log ( "Google payment request completed.") } else { console.log ( request.statusText ) ; } try { console.log ( request.responseText ) ; // set the response in the current document and submit to sample confirmation page document.getElementById('results').value = request.responseText ; document.getElementById("ResultsTransaction").submit() ; } catch ( err ) { console.log ( "Page error: " + err ) ; } } ; request.onerror = function() { console.log ("Payment error: " + request.statusText ) ; } ; try { // Set up the json request var requestjson = { accountInputMode : "googlePay", paywayRequestToken : document.getElementById('paywayRequestToken').value, request : "sendQueuedTransaction", googlePayToken : paymentData , cardAccount : { accountNotes1: "notes1", accountNotes2: "notes2", accountNotes3: "notes3" } } ; var resource = document.getElementById('serviceLocation').value + '/PaywayWS/Payment/CreditCard' ; console.log ( 'send request to: ' + resource ) ; request.open('POST', resource, true ) ; request.setRequestHeader("Content-type", "application/json"); console.log ( 'request: ' + JSON.stringify ( requestjson ) ) ; request.send( JSON.stringify ( requestjson ) ) ; } catch ( err ) { console.log ( "sendQueuedTransaction error: " + err.message ) ; } }