Google Pay™

Google Pay™ allows shoppers to pay with a credit or debit card stored in their Google Account.

Note: When retrieving the details of an order the actual credit or debit card is shown as payment method (e.g. "MAESTRO") instead of Google Pay.

The used (sample) scripts can be downloaded from the sandbox environment:

Prerequisites

For Google Pay the following prerequisites need to be fulfilled:

Enable Google Pay on your account

  • Google Pay (and relevant credit and debit card payment methods) needs to be enabled on your account.

Integration Checklist

  • To ensure that you have completed all the required steps in your web integration, check integration checklist.

Google Pay acceptance policy

More details about the Google Pay API can be found at: Google Pay web developer documentation

Google Pay in the Menu

Google Pay is available in the menu if the prerequisites are fulfilled. No additional information is required in the create-request.

Google Pay on your checkout page

This rest of this page covers how to implement Google Pay on your own checkout page.

Besides, implementing Authorize a Google Pay payment to the Payment Service, the Google Pay JS API has to be used.

Google Pay Button

Google has described how to display the Google Pay Button.

Google has strict requirements on the look, size and placement of the Google Pay button. See the Brand Guidelines > Google Pay for more details.

Payment Flow

The following diagram shows the payment flow when using Google Pay on your checkout page.

Google Pay Payment Flow

Creating an Order

An order has to be created before Google Pay can be used. (See Create a new order.)

Checking for Google Pay availability

Before showing the Google Pay button to the shopper the availability of Google Pay needs to be checked. This must be done with the isReadyToPay-method of the Google Payments client (PaymentsClient).

The allowed card networks for the request can be determined using: List payment methods of an Order.

Example IsReadyToPayRequest:

{
  "apiVersion": 2,
  "apiVersionMinor": 0,
  "allowedPaymentMethods": [
    {
      "type": "CARD",
      "parameters": {
        "allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
        "allowedCardNetworks": ["MASTERCARD", "VISA"]
      }
    }
  ]
}

For more details see:

Example javascript:

function isReadyToPayWithGooglePay(environment, request, name) {
    const paymentsClient = getGooglePaymentsClient(environment);
    paymentsClient.isReadyToPay(JSON.parse(request))
        .then(function (response) {
            console.info("Can pay with Google Pay: " + response.result);
            if (response.result) {
                addGooglePayButton(environment, name)
            }
            window.canPayWithGooglePay(response.result);
        })
        .catch(function (e) {
            console.error("Error checking if ready to pay with Google Pay.", e);
            window.canPayWithGooglePay(false);
        });
}

function addGooglePayButton(environment, name) {
    let elements = document.getElementsByName(name);
    if (elements.length != 0) {
        let element = elements.item(0);
        if (!element.hasChildNodes()) {
            // When there are child nodes the button was already added.
            const paymentsClient = getGooglePaymentsClient(environment);
            const button = paymentsClient.createButton({
                onClick: function () {
                },
                buttonType: "short",
                buttonColor: "black",
                buttonSizeMode: "fill"
            });
            element.appendChild(button);
        }
    } else {
        console.error("No elements with name " + name);
    }
}

    function getGooglePaymentsClient(environment) {
        if ( paymentsClient === null ) {
            paymentsClient = new google.payments.api.PaymentsClient({environment: environment});
        }
        return paymentsClient;
    }
  

Loading Payment Data

When the shopper clicks on the Google Pay button the Google payments client should be asked to load the payment data. This shows a payment sheet pop-up, and allows the shopper to select a card or enter a new card.

The merchant id, merchant_origin, allowed card networks, gateway (id), and country code (merchant country) for the request can be determined using: List payment methods of an Order.

The merchant key should be used as gateway merchant id.

Example PaymentDataRequest:

{
  "apiVersion": 2,
  "apiVersionMinor": 0,
  "merchantInfo": {
    "merchantId": "exampleMerchantId",
    "merchantOrigin": "www.example.com",
    "merchantName": "Example Merchant"
  },
  "allowedPaymentMethods": [
    {
      "type": "CARD",
      "parameters": {
        "allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
        "allowedCardNetworks": ["MASTERCARD", "VISA"]
      },
      "tokenizationSpecification": {
        "type": "PAYMENT_GATEWAY",
        "parameters": {
          "gateway": "example",
          "gatewayMerchantId": "exampleGatewayMerchantId"
        }
      }
    }
  ],
  "transactionInfo": {
    "totalPriceStatus": "FINAL",
    "totalPrice": "33.20",
    "currencyCode": "EUR",
    "countryCode": "NL"
  }
}

Note that only CRYPTOGRAM_3DS is supported as allowed authentication method.

For more details see:

Example javascript:

    /**
     * Authorize a Google Pay payment.
     *
     * @param {string} merchantKey The merchant key.
     * @param {string} orderKey The order key.
     * @param {string} serverUrl The url of the Payment System Mobile services:
     *                           <ul>
     *                             <li>Sandbox/test: https://testsecure.docdatapayments.com/mobile</li>
     *                             <li>Production: https://secure.docdatapayments.com/mobile</li>
     *                           </ul>
     * @param {string} environment The environment of Google to use. Either production (value 'PRODUCTION') or test (value 'TEST').
     * @param {json} request The <a href="https://developers.google.com/pay/api/web/reference/request-objects?authuser=1#PaymentDataRequest">PaymentDataRequest</a> as JSON
     * @see <a href="https://developers.google.com/pay/api/web/guides/tutorial">Google Pay for Payments - Web - Tutorial</a>
     */
    function authorizeGooglePayPayment(merchantKey, orderKey, serverUrl, environment, request) {
        const paymentsClient = getGooglePaymentsClient();
        paymentsClient.loadPaymentData(JSON.parse(request))
            .then(function(paymentData) {
                window.showGooglePaySpinner();
                // handle the response
                processPayment(merchantKey, orderKey, serverUrl, JSON.stringify(paymentData.paymentMethodData));
            })
            .catch(function(e) {
                console.error(e);
            });
    }

Authorizing the payment

When the shopper selected a card, the details are returned as payment data by the Google payments client. The paymentData.paymentMethodData must be sent as-is to the Payment System in the Authorize a Google Pay payment request.

The server url can be determined using: List payment methods of an Order.

Example javascript:

    /**
     * Process payment method data returned by the Google Pay API
     *
     * @param {string} merchantKey The merchant key.
     * @param {string} orderKey The order key.
     * @param {string} serverUrl The url of the Payment System Mobile services:
     *                           <ul>
     *                             <li>Sandbox/test: https://testsecure.docdatapayments.com/mobile</li>
     *                             <li>Production: https://secure.docdatapayments.com/mobile</li>
     *                           </ul>
     * @param {json} paymentMethodData response from Google Pay API after user approves payment
     * @see {@link https://developers.google.com/pay/api/web/reference/response-objects#PaymentMethodData|PaymentMethodData object reference}
     */
    function processPayment(merchantKey, orderKey, serverUrl, paymentMethodData) {
        googlePayDebug(serverUrl, paymentMethodData);
    
        let xhttp = new XMLHttpRequest();
    
        xhttp.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    let response = JSON.parse(this.responseText);
                    let redirectUrlData = findUrlWithPurpose(response.urls, 'REDIRECT');
    
                    /**
                     * URL with 'REDIRECT' purpose signifies 3DSv1 authentication, otherwise it is 3DSv2 authentication.
                     */
                    if (redirectUrlData) {
                        redirectForThreeDsOneAuthentication(redirectUrlData.url, redirectUrlData.parameters);
                    } else {
                        let challengeUrlData = findUrlWithPurpose(response.urls, 'IFRAME');
                        if (!challengeUrlData) {
                           throw Error('3dsv2 Authentication URL data not present');
                        }
    
                        let acsMethodUrlData = findUrlWithPurpose(response.urls, 'HIDDEN_IFRAME');
    
                        let methodUrl = acsMethodUrlData === null ? null : acsMethodUrlData.url;
                        // The parameter is named 'threeDSMethodData'.
                        let methodData = acsMethodUrlData === null ? null : acsMethodUrlData.parameters['threeDSMethodData'];
    
                        performThreeDsAuthentication(methodUrl, methodData, challengeUrlData.url, "{}", false);
                    }
                }
            }
        };
    
        var authorizationUrl = serverUrl + "/mobile/googlepay/merchants/" + merchantKey + "/payments/" + orderKey + "/authorize";
    
        xhttp.open("POST", authorizationUrl, true);
        xhttp.setRequestHeader("Content-type", "application/json");
        xhttp.send(paymentMethodData);
    }

Note: The window.pollOrderStatus(); method is only available in the menu, and used to get the details of the order and redirect the shopper back to the webshop if appropriate. For your own menu, you should implement a similar function.

Note: For 3DS authentication and details about methods findUrlWithPurpose(urls, purpose), redirectForThreeDsOneAuthentication(authenticationUrl, postParameters) and performThreeDsAuthentication(acsMethodUrl, acsMethodData, authenticationUrl, authenticationData, forceAuthentication), see Credit/Debit Card Authentication.

Determining the status of the order

The Payment System sends status change notifications to the customer service agent application during the authorization of the payment, which should be used to get the order details from the Payment System.

The order details should be used to determine if the shopper has paid the order or that another payment attempt can be made by the shopper.