Google Pay Setup Flow (Merchant Button)

Table of Contents

1. Overview

This guide helps you to easily add Google PayTM as a payment option in your web-based app. With Google Pay, your customers can use their saved Google Pay data to pay for goods and services quickly and securely.

Google Web Developer Resources
Google Pay API for Web Overview
Google Pay Web Integration Checklist
Google Pay Web Brand Guidelines

Notes: By integrating the Google Pay API, you must accept the Google Pay API Terms of Service.

Payment Process
• When a customer selects Google Pay as their payment method, your website requests that customer's encrypted payment card or wallet information.
• Your website then passes that encrypted data to PXP, which decrypts and tokenizes the data. The PXP JavaScript file will handle this step on behalf of your merchant.
• Your website receives the tokenized data by calling get payment account API (section 7), and then passes it to the PXP Gateway in an authorization request. Supported authorization methods: ecom.sale, ecom.preauthorization.
• Your website then receives a response from the PXP Gateway, completing the transaction.

2. Public Key Service

The public key service should be called from the merchant server before starting a new Google Pay transaction, to obtain an API key and encryption key to use in the Google Pay Process.

Please follow the link below to the Public Key section of this document

Public Key Service

2.1 Public Key Service API key

The API key will be used as authentication to access other PXP Financial API's and should be passed in the
authorization header as shown below:
PublicApiKey fa5a7568-1191-4a93-8681-20b1b48c5b58

2.2 Public Key Service encryption key

The encryption key should be stored by the merchant payment system, to be used later in the process with the Get Payment Account request.

3. Merchant payment page

The merchant payment page must have the following:

3.1 Import the javascript file

The javascript file must be imported in the header of the merchant payment page

  <script src="./gp.js"></script>

3.2 Add the merchant div and button

The div must be hidden by default

     <div id="merchant-google-pay-button" hidden>
       <input
         type="button"
         value="Merchant GooglePay Button"
         onclick="onMerchantButtonClick();"
       />
     </div>

3.3 Add the handleGooglePayReady function

This is used to show the merchant button after the Googple Pay API has been checked to make sure its accessible.

     function handleGooglePayReady(event) {
       let element = document.getElementById("merchant-google-pay-button");
       element.removeAttribute("hidden");
     }

3.4 Add the handlePaymentResult function

Within this function the merchant must add their own code to POST the event.detail to the merchant server, which in turn calls the PXP Get Payment Account API

     function handlePaymentResult(event) {
       console.log("Payment complete", event.detail);
       //Merchant to add POST back code
     }

Google Pay uses the EMV Payment Tokenization Specification. The service keeps customer payment information private from the retailer by replacing the customer's credit or debit card Funding Primary Account Number (FPAN) with a tokenized Device Primary Account Number (DPAN).

When handling the handlePaymentResult event merchants must only use the event.detail object, all other information provided by the event object is not needed for the payment.

Below shows the information the event.detail will provide, if any properties are null they will be omitted.

clientSystemTransactionId: "1689695428327"
transactionAccountId: "a5df3acc-cd1d-4ad6-8d4e-d91723cb2ce7"
transactionMethod: "GooglePay"
cryptogram: "4234325656gffgd646436fds45" //only returned for a DPAN
eciIndicator: "05" //only returned for a DPAN
redirectData: "" //ignore this property if returned

Note cryptogram and eciIndicator properties will only be returned in the case of a DPAN and not FPAN.

In scenerios where an error has occurred the event.detail will be in the format, if any properties are null they will be omitted.

code:"4000340"
description:"GeneralValidationError"
details:
message: "The Token field is required."


3.5 Add the handlePaymentError function

As with the handlePaymentResult event merchants must only use the event.detail object, when handling the handlePaymentError event.

The event.detail will be a string containing the exception message.

     function handlePaymentError(event) {
       console.log("Error event", event.detail);
       //Merchant must add code to deal with any errors
     }

The information passed back in the event.detail will be the raw low level error, which the merchant must interpret in cases where a formatted payment result from the PXP Finiancial payment servers is not available.

3.6 Calling the runGooglePay function

The call to this javascript function should be called when the merchant payment page loads to make sure the Google Pay API's are up and to allow the merchant payment page to show their own Google Pay button.

      runGooglePay(
        merchantId,
        shopId, 
        clientSystemTransactionId, //transaction reference
        ["PAN_ONLY", "CRYPTOGRAM_3DS"],// static dont change
        ["AMEX", "DISCOVER", "INTERAC", "JCB", "MASTERCARD", "VISA"], //cards allowed
        "GB", // country code
        "GBP", // currency code
        "FINAL", // static dont change
        "100.00", // transaction amount
        "test", // test or prod
        "64900ef1-05ba-493c-92ec-e32570be1703", // Public API key
        false,//set to false to not show the Google Pay default button
        merchantNo, // to display on Google Pay window
       merchantName  // to display on Google Pay window
      );
     }

4. Parameters passed to the runGooglePay function

4.1 Basic request

4.1.1 mid

Merchant ID issued by PXP. It is a string used to identify the merchant in the PXP system.

4.1.2 sid

Store ID issued by PXP. It is a string similar to the merchant but it is a subdivision on the merchant side, in case the merchant has multiple labels.

4.1.3 clientSystemTransactionId

This is the merchant transaction id and created by the merchant. It can be used for queries and other operations.

4.1.4 allowedMethods

Always coded to ["PAN_ONLY", "CRYPTOGRAM_3DS"**]

PAN_ONLY (non-tokenized) - cards stored in the customer`s Google account. These cards are available on any device of the customer.
The token contains the number and expiration date of the physical card. That is why 3DS authentication is required for these cards. Read more in the Section 9 (Enabling 3DS for PAN_ONLY credentials).

CRYPTOGRAM_3DS (tokenized) - cards that are stored tokenized on the customer’s device. Tokenized cards are only available on the device where the card was added to the Google Pay app.
The token contains the number and expiration date of the virtual card as well as the 3DS cryptogram. Customer 3DS verification for tokenized cards is not required.

4.1.5 allowedCardNetworks

List of allowed card networks. The PXP gateway only accepts Visa, MasterCard, AMEX, Discover, and JCB through Google Pay for now.

4.1.6 countryCode

Two-digit country code

4.1.7 currencyCode

A three-letter ISO 4217 currency code that represents the currency for the transaction.

4.1.8 amountStatus

Always coded to "FINAL".

4.1.9 amount

The total price for the transaction is represented as a string in the format "123.45" (without currency symbols).

4.1.10 profile

Always coded to "test" or "prod".

4.1.11 publicKeyApi

Key obtained from the Public Key Service.

4.1.12 useGooglePayButton

True or false if the merchant requires the Google Pay button to render on their page.

4.1.13 merchantNo

A Google merchant identifier is issued after registration with the Google Pay and Wallet Console. Required when PaymentsClient is initialized with an environment property of PRODUCTION. The merchantNo can have 12-18 characters.

4.1.14 merchantName

Merchant name encoded as UTF-8. Merchant name is rendered in the payment sheet. In TEST environment, or if a merchant isn't recognized, a “Pay Unverified Merchant” message is displayed in the payment sheet.

4.2 Extensive request

4.2.1 optionalParams

4.2.1.1 existingPaymentMethodRequired (Boolean) - Set to true, the Google Pay/merchant button will only be displayed if the user already has an existing payment that they can use to make a purchase.

4.2.1.2 emailRequired (Boolean) - Set to true to request an email address.

4.2.1.3 billingAddressRequired (Boolean) - Set to true if you require a billing address. A billing address should only be requested if it is required to process the transaction.

4.2.1.4 billingAddressParameters (BillingAddressParameters - Section 4.2.1.4) - You set additional fields to be returned for a requested billing address

a. format (String - optional) - Billing address format required to complete the transaction.
• MIN: Name, country code, and postal code (default).
• FULL: Name, street address, locality, region, country code, and postal code.

b. phoneNumberRequired (Boolean - optional) - Set to true if a phone number is required to process the transaction.

4.2.1.5 callbackIntents (String[ ]) - Specifies the following callback intents for the callback function.
• OFFER
• PAYMENT_AUTHORIZATION
• SHIPPING_ADDRESS
• SHIPPING_OPTION

4.2.1.6 shippingAddressRequired (Boolean) - Set to true to request a full shipping address.

4.2.1.7 shippingAddressParameters (ShippingAddressParameters - Section 4.2.1.7) - If shippingAddressRequired is set to true, specify shipping address restrictions

a. allowedCountryCodes (String[ ]- Optional) - ISO 3166-1 alpha-2 country code values of the countries where shipping is allowed. If this object isn't specified, all shipping address countries are allowed.

b. phoneNumberRequired (Boolean - Optional) - Set to true if a phone number is required for the provided shipping address.

4.2.1.8 shippingOptionRequired (Boolean) - Set to true when the SHIPPING_OPTION callback intent is used. This field is required if you implement support for Authorize Payments or Dynamic Price Updates.

4.2.1.9 shippingOptionParameters (ShippingOptionParameters - Section 4.2.1.9) - A default shipping option.

a. defaultSelectedOptionId (String - Optional) - An identifier to the default selected shipping option. If this field isn't provided, the first option is the default option.

b. shippingOptions (SelectionOption[] – Required) - All of the shipping options are available for the current request:
• id (String - Required);
• label (String - Required) - the label to be displayed on the Payment Sheet as the option;
• description (String - Optional) - a descriptive text that is displayed below the option label on Payment Sheet.

4.2.1.10 additionalTransactionInfo (AdditionalTransactionInfo - Section 4.2.1.10) - Additional information about the transaction.

a. displayItems (DisplayItem[] - Optional) - All of the available charges for the current payment request. This is only populated in the payment sheet if you use Authorize Payment or Dynamic Price Updates. This field is required if you implement support for Authorize Payments or Dynamic Price Updates.

b. totalPriceLabel (String - Optional) - Custom label for the total price within the display items.

c. checkoutOption (String – Optional) - Affects the submit button text displayed in the Google Pay payment sheet.
• DEFAULT: Standard text applies for the given totalPriceStatus (default).
• COMPLETE_IMMEDIATE_PURCHASE: The selected payment method is charged immediately after the payer confirms their selections. This option is only available when totalPriceStatus is set to FINAL.

4.2.1.11 allowPrepaidCards (Boolean) - Set to false if you don't support prepaid cards. Default: The prepaid card class is supported for the card networks specified

4.2.1.12 allowCreditCards (Boolean) - Set to false if you don't support credit cards. Default: The credit card class is supported for the card networks specified.

4.2.1.13 offerInfo (OfferInfo[]- Section 4.2.1.13) - Provides information about any Offers currently applied to a transaction

offers (OfferDetail[ ] – Section 4.2.1.20) - All of the applied offers for the current transaction

4.2.1.14 buttonColor (String) - There are values: "default" | "black" | "white". Just apply for using Google button (Brand guidelines | Google Pay API | Google for Developers)

4.2.1.15 buttonLocale (String) - This ISO 639-1 code represents the desired button language.

Supported locales include en, ar, bg, ca, cs, da, de, el, es, et, fi, fr, hr, id, it, ja, ko, ms, nl, no, pl, pt, ru, sk, sl, sr, sv, th, tr, uk, and zh. Just apply for using Google button (Brand guidelines | Google Pay API | Google for Developers)

4.2.1.16 buttonSizeMode (String) - There are values: "static" | "fill". Just apply for using Google button (Brand guidelines | Google Pay API | Google for Developers)

4.2.1.17 buttonType (String) - There are values: "book" | "buy" | "checkout" | "donate" | "order" | "pay" | "plain" | "subscribe" | "long" | "short". Just apply for using Google button. (Brand guidelines | Google Pay API | Google for Developers)

4.2.1.18 onPaymentDataChanged (Function – Section 4.2.1.18) - Invoked when the following callbackIntents values are set in PaymentDataRequest:
SHIPPING_ADDRESS
SHIPPING_OPTION

This method handles payment data changes in the payment sheet such as shipping address and shipping options.
Dynamic Price Updates allows a merchant to dynamically update shipping options and transaction information based on a chosen shipping address. Additionally, you can dynamically update transaction information based on a chosen shipping option.

Arguments: intermediatePaymentData - An object that contains the selected address and shipping option in the payment sheet. For details, see IntermediatePaymentData (Section 5.6).

Returns: promise - Resolved: An object that contains information about new transaction information, shipping options, and payment data errors. For details, see PaymentDataRequestUpdate (Section 4.2.2).

Rejected: An error object with an error intent and message to be rendered in the payment sheet. For details, see PaymentDataError (section 5.1).
Note: Reject isn't used to update the payment sheet with new shipping options and transaction info. Don't intentionally return reject if possible.

This is an example of the result that handlePaymentResult (section 3.4) gets when the merchant makes an extensive request.

"transactionAccountId": "1111111111111111111",
"clientSystemTransactionId": "111111111111111",
"transactionMethod": "GooglePay",
"billingAddress": {
    "phoneNumber": "+811111111",
    "address3": "",
    "sortingCode": "",
    "address2": "",
    "countryCode": "VN",
    "address1": "Test",
    "postalCode": "Test",
    "name": "Test",
    "locality": "Test",
    "administrativeArea": ""
},
"shippingAddress": {
    "phoneNumber": "+84 967 116 039",
    "address3": "",
    "sortingCode": "",
    "address2": "",
    "countryCode": "VN",
    "address1": "Test",
    "postalCode": "70000",
    "name": "Test",
    "locality": "Test",
    "administrativeArea": ""
},
"email": "[email protected]",

4.2.1.19 onPaymentAuthorized (Function – Section 4.2.1.19) - Invoked when the following callbackIntents values are set in PaymentDataRequest: PAYMENT_AUTHORIZATION

Arguments: paymentData (An object that contains the requested shopper data. For details, see PaymentData (section 5.3)

Returns: Promise

Resolved: An object that contains information about payment transaction results. For details, see PaymentAuthorizationResult.
Rejected: An error object with an error intent and message to be rendered in the payment sheet. For details, see PaymentDataError.

Authorize Payments is used to start the payment process and acknowledge a payment's authorization status. To set up Authorize Payments, take the following steps.

Register onPaymentAuthorized callbacks

The following code sample shows how to register onPaymentAuthorized callbacks:

let merchantOptionalParams = {  
            callbackIntents: ["PAYMENT_AUTHORIZATION"],  
            onPaymentAuthorized: onPaymentAuthorized, // callback functions  
        };

    runGooglePay(
        merchantId, shopId,
        paymentData.clientSystemTransactionId,
        ["PAN_ONLY", "CRYPTOGRAM_3DS"],
        ["MASTERCARD", "VISA"],
        country,
        currency,
        "FINAL",
        amount,
        envProfile,
        publicApiKey,
        paymentData.useDigitalWalletButton,
        providerMerchantNo,
        providerMerchantName,
        merchantOptionalParams);

Implement onPaymentAuthorized().
The onPaymentAuthorized() callback is invoked with a PaymentData object by Google after a payer approves payment through a user gesture, such as if they click Pay.

The callback returns a Promise value. The PaymentAuthorizationResult (see section 6.2) object has a SUCCESS or ERROR transaction state status. Upon success, the payment sheet is closed successfully. If you encounter an error, the payment sheet renders the error details returned after the payment is processed. The user can change the payment sheet’s payment data and authorize the payment again. See the following code sample:

function onPaymentAuthorized(paymentData) {  
            let error = {  
                transactionState: "ERROR",  
                error: {  
                    intent: "PAYMENT_AUTHORIZATION",  
                    message: "Payment Data Invalid",  
                    reason: "PAYMENT_DATA_INVALID",  
                },  
            };  
            return new Promise(function (resolve, reject) {  
                processPayment(paymentData)  
                    .then((data) => {  
                        if (data?.transactionAccountId) {  
                            resolve({ transactionState: "SUCCESS" });  
                        }  
                        else {  
                            resolve(error);  
                        }

                })
                .catch( () => {
                    resolve(error);
                });
        });
    }

4.2.1.20 OfferDetail

a. redemptionCode (String - Required) - The promotional code associated with the Offer. It should be the same as the code entered into the payment sheet.

b. description (String - Required) - A description of the promotion applied by the Offer code.

4.2.1.21 DisplayItem

a. label (String - Required) - The label to be displayed for the given option.

b. type (String – Required) - Type of displayed line item:
• LINE_ITEM
• SUBTOTAL

c. price (String - Required) - The monetary value of the cart item with an optional decimal precision of two decimal places. Negative values are allowed.

d. status (String – Optional) - The following variables define price variance:
• FINAL
• PENDING
Default to FINAL if not provided.

4.2.2 PaymentDataRequestUpdate

  • newOfferInfo (OfferInfo – Optional) - Updates the offers currently active in the payment sheet.

  • newTransactionInfo (TransactionInfo – Optional) - Updates the transaction info in the payment sheet.

  • newShippingOptionParameters (ShippingOptionParameters – Optional) - Updates the shipping options in the payment sheet.

  • error (PaymentDataError – Optional) - Adds an error message to the payment sheet.

5. Google Response

5.1 PaymentDataError

  • reason (String - Required) - List of predefined error reasons:
    • OFFER_INVALID
    • PAYMENT_DATA_INVALID
    • SHIPPING_ADDRESS_INVALID
    • SHIPPING_ADDRESS_UNSERVICEABLE
    • SHIPPING_OPTION_INVALID
    • OTHER_ERROR
  • message (String - Required) - Error message to the user that's displayed in a dialog.
  • intent (String - Required) - The intent of the error. This must be one that’s been registered in TransactionInfo from the start of the flow.
    • OFFER
    • PAYMENT_AUTHORIZATION
    • SHIPPING_ADDRESS
    • SHIPPING_OPTION

5.2 PaymentAuthorizationResult

  • transactionState (String - Required) - The state of the transaction is resolved by one of the following merchant results:
    • SUCCESS
    • ERROR
  • error (PaymentDataError – Optional (Section 4.1) - The error is to be rendered in the payment sheet for the user when it's necessary to retry the payment.

5.3 PaymentData

This is a response object that's returned by Google after a payer approves payment.

  • apiVersion (number; it always exists) - Major API version. The value in the response matches the value provided in PaymentDataRequest.
  • apiVersionMinor (number; it always exists) - Minor API version. The value in the response matches the value provided in PaymentDataRequest.
  • paymentMethodData (PaymentMethodData – Section 5.5; it always exists) - Data about the selected payment method.
  • email (String; it does not always exist) - Email address, if emailRequired is set to true in the PaymentDataRequest. If another request has the property set to true there's no effect
  • shippingAddress (Address – Section 5.4; it does not always exist) - Shipping address, if shippingAddressRequired is set to true in the PaymentDataRequest.

5.4 Address

This object provides information about a requested postal address. All the properties are strings.
A MIN address format may be returned if billingAddressFormat is set to MIN. A shipping address is returned in the FULL address format. All properties in a MIN formatted response exist in a FULL formatted response.

  • name (min format) - Updates the offers currently active in the payment sheet.
  • postalCode (min format) - Updates the transaction info in the payment sheet.
  • countryCode (min format) - ISO 3166-1 alpha-2 country code.
  • phoneNumber (min format) - A telephone number, if phoneNumberRequired is set to true in the PaymentDataRequest.
  • address1 (full format) - The first line of the address.
  • address2 (full format) - The second line of the address.
  • address3 (full format) - The third line of the address.
  • locality (full format) - City, town, neighborhood, or suburb.
  • administrativeArea (full format) - A country subdivision, such as a state or province.
  • sortingCode (full format) - The sorting code.

5.5 PaymentMethodData

  • type (string; it always exists) - PaymentMethod type selected in the Google Pay payment sheet.
  • description (string; it always exists) - User-facing message to describe the payment method that funds this transaction.
  • info (object; it always exists) - The value of this property depends on the payment method type returned.
  • tokenizationData (object; it always exists) - Payment tokenization data for the selected payment method.

5.6 IntermediatePaymentData

  • callbackTrigger (string; optional) - Describes the reason for which payment data callback was invoked.
    • INITIALIZE
    • SHIPPING_ADDRESS
    • SHIPPING_OPTION
    • OFFER
  • offerData (object; optional) - The promotional code is provided by the user.
  • shippingAddress (object; optional) - The selected address in the payment sheet.
  • shippingOptionData (object; optional) - The selected shipping option is in the payment sheet.

Example:
This example shows the intermediate payload returned from Google Pay.

{  
  callbackTrigger: "SHIPPING_ADDRESS"  
  "offerData": {  
    redemptionCode: "exampleCode",  
  }  
  shippingAddress: {  
    administrativeArea: "NY"  
    countryCode: "US"  
    locality: "New York"  
    postalCode: "10011"  
  },  
  shippingOptionData: {  
    id: "shipping-001"  
  }  
}

6. Calling the Get Payment Account API

After the handlePaymentResult function (step 2.4) has been called from the PXP Financial javascript (gp.js), the merchants payment page must submit the data returned in this event to its own servers, where they need to store any cryptogram and eci values to allow them to be sent in the transaction request to the PXP Financial payment servers.
The merchant server must then call the PXP Financial Get Payment Account API, passing the transactionAccountId, merchantId, storeId and encryptionKeyId (from the call to the Public Key service).
The response to this call will return the information needed to then process a transaction as normal.

Please follow the link below to the Get Payment Account section of this document

Get Payment Account

7. Decrypting Google Pay Data

This section is for your reference only. The PXP JavaScript will take care of this step for you.
The PXP JavaScript will request encrypted Google Pay data and transmit it to the PXP gateway to create a payment account using the PXP Create Payment Account API (decrypting Google Pay Data and returning the transactionAccountId to the merchant to call the Get Payment Account API).
Please follow the link below to the Create Payment Account section of this document: Create Payment Account API.
The setting to request encrypted Google Pay payload:

tokenizationSpecification = {  
       type: "PAYMENT_GATEWAY",  
       parameters: {  
           "gateway": "pxpfinancial",  
            "gatewayMerchantId": pMid // Merchant ID issued by PXP. It is a string used to identify the merchant in the PXP system.  
       }  
   };

8. Enabling 3DS for PAN_ONLY credentials

Paying with Google Pay may require 3DS authentication. 3DS is required for PAN_ONLY cards. PAN_ONLY card can be indicated by the cardType field in Get Payment Account API (Section 7)
CardType = Card: PAN_ONLY
CardType = Token: 3DS

Please follow the link below to for details of how to process a 3D Secure 2.0 authenticated transaction: https://developer.pxp-solutions.com/docs/3d-secure-2
How to process a 3D Secure Redirect: https://developer.pxp-solutions.com/docs/3d-secure-redirect-guide (3D Secure Redirect is a powerful product that encapsulates 3D Secure 1, 3D Secure 2 and SCA Exemptions into a fully managed, easy to integrate product, removing all complexities for a merchant when it comes to complying to the PSD2 rules on Strong Customer Authentication).

9. Diagram

This is a overall process flow of the Google Pay process.

10. Google Pay Popup

Example of the Google Pay popup.

11. Browser Console Flow

For a good Google Pay payment through the runGooglePay function the browser should log information in its console similar to that shown below.