Developer Portal
Google Pay™ Integration Guide
This document provides a guide to integrating Google Pay™ into your web applications. Google Pay provides a secure, wallet-based payment method for your users. Payway provides the RESTtful web service with which you will interact to implement your Google Pay interface.
The PaywayWS Integration Guide will describe the general integration process including accessing our development, staging, and production servers.
1 Related Documents
- PaywayWS Credit Card Integration Guide
- PaywayWS ACH Integration Guide
- PaywayWS Redirected Payment Form Integration Guide
- Payway Admin Guide
- Payway User Guide
- Payway ApplePay Integration Guide
2 Credit Card Data
To use Google Pay, a user must register a credit card account within their Google account. The PaywayWS integration supports web-based payments.
The user can pay for products and services using a Google Pay button you present on your web page. PaywayWS decrypts and manages the encrypted data and the interaction with the payment processors.
3 Recurring Transactions
After a user enters a Google Pay transaction, you will have access to a paywayAccountToken that references the Google Pay account used for the transaction. This token can then be used to enter recurring transactions, just like any other tokenized account.
4 Integration Method
To integrate with Google Pay, you will use the PaywayWS RESTful web service. The acquisition and processing of Google Pay data will be done on the web browser via a JavaScript. We will provide you with a sample JavaScript that can be plugged into your payment page. This script presents the Google Pay button on your page and sends Google Pay data to PaywayWS. We take care of all cryptography and certifications with Google Pay.
Details on the JavaScript can be found in Section XI, Code Details.
5 Managing Payway Transactions
The Payway Google Pay integration uses the PaywayWS RESTFul API to validate Google Pay merchants and perform Google Pay transactions. To manage your transactions, you can use PaywayWS requests. These include reading transactions and updating user accounts where needed. Reports and other payment management functionality is provided by Payway’s web application.
6 Managing Google Pay Data Collection
The included Google Pay JavaScript provides a section that controls the collection of payment data by your application. This controls the payment sheet and required fields that are presented when a user processes a payment with Google Pay. This can be set up to collect a minimum of cardholder name and zip, or full data including phone number. Note that requiring all data may require the user to modify their Google payment account since the Google Pay page will enforce your requirements.
All request and reply fields are documented by Google here: https://developers.google.com/pay/api/web/reference/object#PaymentOptions.
8 Acceptable User Policy
This page outlines the acceptable use policy for Google Pay: https://payments.developers.google.com/terms/aup.
You should also reference the acceptable use section of your Payway agreement.
9 Terms of Service
You will be directed to agree to the terms of service when you are ready to implement Google Pay in production.
10 Website Review
Google will conduct a review of your web site and provide a merchant account when you are ready to go into production. This merchant account id must be entered into your JavaScript to execute live transactions.
See Section 12″Code Details” for details on the JavaScript.
13 Hosted Payment Results
See the PaywayWS Integration Guide for details on hostedPaymentResults. This is the method for acquiring details on the completed transaction.
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 ) ; } }