Create a Google Pay transaction

The CM.com Online Payments API enables you to create a Google Pay transaction. The diagram below presents the interaction that takes place between Consumer/Device, Merchant (You), CM.com Online Payments API, and Google when creating a Google Pay transaction:

In the diagram above the following steps are performed:

  1. A Merchant wants to enable Google Pay payments for a Consumer/Device. In order to do this, a Merchant makes a request to initialize Google Pay transaction.

  2. Merchant receives a successful transaction response including details. These details are passed to Consumer/Device because they are used to render the Google Pay button on the Device.

  3. Checking for Google availability; before showing the Google Pay button to the Consumer/Device the availability of Google Pay needs to be checked. This must be done with the isReadyToPay method of the Google Payments client (PaymentsClient). For more details see: Checking For Google Pay Availability, PaymentsClient.isReadyToPay, IsReadyToPayRequest.

    1. Example IsReadyToPayRequest:

      {
        "apiVersion": 2,
        "apiVersionMinor": 0,
        "allowedPaymentMethods": [
          {
            "type": "CARD",
            "parameters": {
              "allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
              "allowedCardNetworks": ["MASTERCARD", "VISA"]
            }
          }
        ]
      }
      
    2. 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;
          }
        
      
      
  4. Loading Payment Data; after the Consumer clicks on the Google Pay button the Google payments client should be asked to load the payment data. This will make the payment sheet pop-up appear, allowing the customer to select a card or enter a new card.

    1. The merchant id, merchant name, allowed card networks, gateway (id), and country code (merchant country) for the request can be determined using the retrieved Google Pay transaction details. The merchant key should be used as gatewayMerchantId. Note that only CRYPTOGRAM_3DS is supported as allowed authentication method. For more details see: Register an event handler for user gestures, PaymentsClient.loadPaymentData, PaymentDataRequest.
      1. Example PaymentDataRequest:
        {
          "apiVersion": 2,
          "apiVersionMinor": 0,
          "merchantInfo": {
              "merchantId": googlePayTransaction.details.merchantId,
              "merchantName": googlePayTransaction.details.merchantName,
          },
          "allowedPaymentMethods": [
            {
              "type": "CARD",
              "parameters": {
                "allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
                "allowedCardNetworks": googlePayTransaction.details.allowedCardNetworks,
              },
              "tokenizationSpecification": {
                "type": "PAYMENT_GATEWAY",
                "parameters": {
                  "gateway": googlePayTransaction.details.gatewayId,
                  "gatewayMerchantId": googlePayTransaction.details.merchantKey, // The merchant key goes here
                }
              }
            }
          ],
          "transactionInfo": {
            "totalPriceStatus": "FINAL",
            "totalPrice": (googlePayTransaction.amount / 100).toString(),
            "currencyCode": googlePayTransaction.currency,
            "countryCode": googlePayTransaction.details.merchantCountry
          }
        }
        
      2. 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(googlePayTransaction, paymentDataRequest) {
                const paymentsClient = getGooglePaymentsClient();
                paymentsClient.loadPaymentData(paymentDataRequest)
                    .then(function(paymentData) {
                        window.showGooglePaySpinner();
                        // handle the response
                        processPayment(googlePayTransaction, paymentData));
                    })
                    .catch(function(e) {
                        console.error(e);
                    });
            }
        
  5. Authorizing the payment; when the customer has selected a card, the details are returned as paymentData by the Google payments client. The paymentData.paymentMethodData must be sent as-is in your request to the authorize Google Pay transaction endpoint. If this endpoint gives a successful response it will contain an action.redirect.url where customers should be redirected to. This will make them land on a CM.com Online Payments API 'redirect action' url.

    1. Example javascript:

      /**
       * Process payment data returned by the Google Pay API
       *
       * @param googlePayTransaction
       * @param {object} paymentData response from Google Pay API after user approves payment
       * @see {@link https://developers.google.com/pay/api/web/reference/response-objects#PaymentData|PaymentData object reference}
       */
      function processPayment(googlePayTransaction, paymentData) {
          // show returned data in developer console for debugging
          console.log("Payment data returned by Google Pay is: ", paymentData);
      
          let controller = new AbortController();
          const signal = controller.signal;
          const reqOptions = {
              method: "POST",
              headers: {
                  'Content-Type': "application/json",
                  Authorization: `Bearer ${document.getElementById('token').value}`,
                  Accept: `application/json`
              },
              mode: "cors",
              body: JSON.stringify(paymentData.paymentMethodData),
              signal: signal
          };
          console.debug('Authorization URL:', `${googlePayTransaction.details.serverUrl}/api/v1/paymentmethods/google-pay/v1/transactions/${googlePayTransaction.id}/authorize`);
          document.getElementById('paymentLoader').classList.remove('d-none');
          // Execute fetch
      
          fetch(`${googlePayTransaction.details.serverUrl}/api/v1/paymentmethods/google-pay/v1/transactions/${googlePayTransaction.id}/authorize`, reqOptions)
              .then(response => {
                  if (!response.ok) {
                      console.error(response);
                      displayMessage(response.statusText);
                      controller.abort();
                  }
                  return response.json();
              })
              .then(result => {
                  console.log('Authorization response:', result);
                  let responseElement = document.getElementById('response');
                  let btnRedirect = document.getElementById('btnRedirect');
                  responseElement.innerHTML = `<pre>${JSON.stringify(result, null, 2)}</pre>`;
                  responseElement.classList.remove('d-none');
                  btnRedirect.classList.remove('d-none');
                  document.getElementById('btnRedirect').addEventListener("click", function () {
                      window.location.href = result.action.redirect?.url;
                  });
                  document.querySelector('#gpay-container button').remove();
              })
              .catch(displayMessage)
              .finally(() => {
                  displayStatus(false);
              });
      }
      
  6. Eventually the status of the CM.com Online Payments API transaction will be updated and that will redirect Consumers again from the 'redirect action' url to the returnUrl(s) specified by you when the transaction was initialized.

  7. If you specified webhooks in the original request then CM.com Online Payments API will trigger the proper webhooks requests. When using webhooks, be aware that they are only a "best effort" mechanism.

  8. You get eventually the latest details of the transaction by making a call to the get transaction endpoint. You can use the latest details to update your system.

The API endpoints involved on this flow are:

Create a refund for the payment made with a Google Pay transaction

The CM.com Online Payments API enables you to create a refund for the payment made with a Google Pay transaction. The diagram below presents the interaction that takes place between Merchant (You) and CM.com Online Payments API when requesting a refund for the payment made with a Google Pay transaction

The API endpoints involved on this flow are: