> For the complete documentation index, see [llms.txt](https://docs.payengine.co/developer-docs-v2.5/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payengine.co/developer-docs-v2.5/processing-payments/google-pay-tm.md).

# Google Pay™

Google Pay™ offers the convenience of using cards stored in your Google Account, delivering a fast and secure payment solution across websites, apps, and in-store purchases. Platform currently supports all major card brands—Visa, MasterCard, American Express, and Discover—in the US and Canada for Google Pay™ transactions.

Note: By integrating Google Pay, you agree to Google’s [terms of service](https://payments.developers.google.com/terms/sellertos) and Google Pay™ API's [Acceptable Use Policy](https://payments.developers.google.com/terms/aup)

## Enabling Google Pay™ for your account

{% hint style="danger" %}
Please contact your support representative to enable Google Pay™ for your account.
{% endhint %}

## Using Google Pay™ in your Web Application

{% hint style="warning" %}
For native app integration, please contact your assigned solution engineer for further implementation details. Also review [Google Pay Android developer documentation](https://developers.google.com/pay/api/android/), [Google Pay Android integration checklist](https://developers.google.com/pay/api/android/guides/test-and-deploy/integration-checklist) and [Google Pay Android brand guidelines](https://developers.google.com/pay/api/android/guides/brand-guidelines).
{% endhint %}

This platform makes it easy to present Google Pay™ during the checkout process in your web application. If you're already using the JS library, it's as simple as calling an extra function to present Google Pay™ button.

{% hint style="info" %}
To learn more about the JS library, please [see our guide](/developer-docs-v2.5/getting-started-1/frontend-frameworks.md).
{% endhint %}

{% tabs %}
{% tab title="Client Application (HTML)" %}

```html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Google Pay Demo</title>
    <script src="https://console.payengine.co/js/1.0.0/embed.js?key=<your public key>" async></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.22.0/axios.min.js"
    integrity="sha512-m2ssMAtdCEYGWXQ8hXVG4Q39uKYtbfaJL5QMTbhl2kc6vYyubrKHhr6aLLXW4ITeXSywQLn1AhsAaqrJl8Acfg=="
    crossorigin="anonymous" referrerpolicy="no-referrer"></script>
</head>

<body>
  <h4>Google Pay</h4>
  <div id="button"></div>
  <script>
    const merchantId = "<Your Merchant ID>";
    const amount = <Amount you want to charge>;
      const submit = (token) => {
        axios
          .post(
            "<Your Back End Application>/api/charge",
            {
              merchant_id: merchantId,
              token: token,
              amount: String(amount),
            }
          )
          .then((resp) => {
            //Handle Response from your backend
          })
          .catch((err) => {
            //Handle Error from your backend
          });
      };
    window.onload = () => {
      Platform.GooglePay.configure({
        merchant_id: merchantId,
        hmac: <Your HMAC>,
        amount: amount,
        selector: "#button",
        button_type: "pay", 
        button_color: 'black',
        callback: function (response, error) {
            if (!error) {
              //Handle Success here. Typically call your backend to call Platform ccsale API
              submit(response.token);
            } else {
              //Handle Google Pay Authorization Error
            }
          },
      });
    };
  </script>
</body>

</html>
```

{% endtab %}

{% tab title="Server Side (Node)" %}
{% code lineNumbers="true" %}

```javascript
// Credit Card Sale
// Note that this call is not changed and can pass in Google Pay Token just like Credit card tokens
exports.charge = async function (req, res) {
    try{
        const response = await axios.post(Platform_Server + "/api/payment/sale",
            {
                "merchant_id": req.body.merchant_id,
                "data": {
                    "transaction_amount": req.body.amount,
                    "card_token": req.body.token,
                    "currency_code": "USD"
                }
            },
            {
                headers: {
                    'Content-type': 'application/json',
                    'Accept': 'text/plain',
                    'Authorization': 'Basic ' + secret_key
                }
            })
        res.json(response.data)
    }catch(error){
        res.json({error: error.response?.data ?? error})
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Presenting the Google Pay™ button

As shown in the example above, in your client app you just call `GooglePay.configure` function to present Google Pay™ as an option.\
\
Please note that you need to have provide the amount before you call this method.

```javascript
Platform.GooglePay.configure({
  merchant_id: <Your Merchant ID>,
  hmac: <Your HMAC>,
  amount: <Amount You want to charge>,
  selector: "#button",
  button_type: "pay", 
  button_color: "default", 
  billing_address_required: true,
  shipping_address_required: true,
  callback: function (response, error) {
    if (!error) {
      //Call Your backend server to execute Platform sale API
    } else {
      // Handle error here  
    }
  },
});
```

{% hint style="info" %}
To request billing and/or shipping address set the `billing_address_required` and `shipping_address_required` properties to true.\
\
You can also include extra billing and shipping address parameters if default response is not sufficient. Please see Google Pay documentation [here](https://developers.google.com/pay/api/web/reference/request-objects#BillingAddressParameters)
{% endhint %}

#### Sample Token Response with metadata

```json
{
    "token": "pe_sandbox_***************",
    "metadata": {
        "shipping_address": {
            "address3": "",
            "sorting_code": "",
            "address2": "",
            "country_code": "US",
            "address1": "123 Main Street",
            "postal_code": "90245",
            "name": "John Doe",
            "locality": "Los Ageles",
            "administrative_area": "CA"
        },
        "billing_address": {
            "address3": "",
            "sorting_code": "",
            "address2": "",
            "country_code": "US",
            "address1": "123 Main Street",
            "postal_code": "90245",
            "name": "John Doe",
            "locality": "Los Angeles",
            "administrative_area": "CA"
        }
    },
    "merchant_id": "<Your Merchant ID>"
}
```

### Customizing Google Pay™ button

You can customize the label and color of your Google Pay™ Button by providing `button_type` and `button_color` attributes in Google Pay™ configuration object.

```javascript
  button_type: 'pay', // "book" | "buy" | "checkout" | "donate" | "order" | "pay" | "plain" | "subscribe" | "long" | "short"
  button_color: 'default', // "default" | "black" | "white"

```

In addition, you can control the sizing of the button by enclosing it in another element (typically a `div`) with specific width and height attributes.

### Dynamic Pricing Setup with Google Pay <a href="#dynamic-pricing-setup-with-google-pay" id="dynamic-pricing-setup-with-google-pay"></a>

#### Overview <a href="#overview" id="overview"></a>

This document outlines the setup for dynamic pricing using Google Pay, including how to configure shipping options, handle payment data changes, and calculate transaction information based on selected shipping options.

#### Setup Shipping Options <a href="#setup-shipping-options" id="setup-shipping-options"></a>

Shipping options define the available delivery methods for customers. Each option includes an ID, label, and description.

```javascript
const shippingOptions = [
    {
        "id": "shipping-001",
        "label": "$0.00: Free shipping",
        "description": "Free Shipping delivered in 5 business days."
    },
    {
        "id": "shipping-002",
        "label": "$1.99: Standard shipping",
        "description": "Standard shipping delivered in 3 business days."
    },
    {
        "id": "shipping-003",
        "label": "$2.99: Express shipping",
        "description": "Express shipping delivered in 1 business day."
    }
]
```

* **id**: A unique identifier for each shipping option.
* **label**: The display text shown to the user.
* **description**: Additional information about the shipping method.

#### Setup Shipping Parameters and Handle Callback <a href="#setup-shipping-parameters-and-handle-callback" id="setup-shipping-parameters-and-handle-callback"></a>

This section configures the Google Pay API with the necessary parameters, including shipping address requirements and options.

```javascript
Platform.GooglePay.configure({
    ...parameters,
    shipping_address_required: true,
    shipping_address_parameters: {
        phone_number_required: false
    },
    shipping_option_required: true,
    shipping_option_parameters: {
        default_selected_option_id: shippingOptions[0].id,
        shipping_options: shippingOptions
    },
    on_payment_data_changed: onPaymentDataChanged
})
```

* **shipping\_address\_required**: Indicates if the shipping address is mandatory.
* **shipping\_address\_parameters**: Configuration for the shipping address, including whether the phone number is required.
* **shipping\_option\_required**: Indicates if a shipping option must be selected.
* **shipping\_option\_parameters**: Sets the default selected shipping option and provides the list of available options.
* **on\_payment\_data\_changed**: A callback function that handles changes in payment data.

#### Sample of onPaymentDataChanged Handler <a href="#sample-of-onpaymentdatachanged-handler" id="sample-of-onpaymentdatachanged-handler"></a>

The `onPaymentDataChanged` function processes updates to the payment data based on user interactions, such as selecting a shipping option or entering a shipping address.

```javascript
var calculateTransactionInfo = (shippingOptionData) => {
    var shippingOptionId = shippingOptionData.id
    var shippingFee = shippingOptionId === 'shipping-001' ? 0 : shippingOptionId === 'shipping-002' ? 1.99 : 2.99
    return {
        display_items: [
            {
                label: "Subtotal",
                type: "SUBTOTAL",
                price: amount.toString(),
            },
            {
                label: "Shipping Fee",
                type: "LINE_ITEM",
                price: shippingFee.toString(),
            }
        ],
        currency_code: "USD",
        total_price_status: "FINAL",
        total_price: (amount + shippingFee).toString(),
        total_price_label: "Total"
    }
}

const onPaymentDataChanged = async (intermediatePaymentData) => {
    const { callbackTrigger, shippingAddress, shippingOptionData } = intermediatePaymentData

    // return empty object if no update
    let paymentDataRequestUpdate = {}

    // update transaction info
    // simulate server call to calculate dynamic pricing
    await new Promise(resolve => setTimeout(resolve, 2000))

    if (callbackTrigger == "INITIALIZE" || callbackTrigger == "SHIPPING_ADDRESS") {
        if(shippingAddress.countryCode == "JP")  {
            paymentDataRequestUpdate.error = {
                reason: 'SHIPPING_ADDRESS_NOT_SUPPORTED',
                message: 'We do not offer shipping to your selected shipping address',
                intent: 'SHIPPING_ADDRESS'
            }
        }
        else {
            const selectedShippingOption = shippingOptions[1]
            paymentDataRequestUpdate.new_shipping_option_parameters = {
                default_selected_option_id: selectedShippingOption.id,
                shipping_options: shippingOptions
            }
            paymentDataRequestUpdate.new_transaction_info = calculateTransactionInfo(selectedShippingOption)
        }
    }
    else if (callbackTrigger == "SHIPPING_OPTION") {
        paymentDataRequestUpdate.new_transaction_info = calculateTransactionInfo(shippingOptionData)
    }

    return paymentDataRequestUpdate
}
```

* **calculateTransactionInfo**: A function that calculates the transaction details based on the selected shipping option, including subtotal, shipping fee, and total price.
* **onPaymentDataChanged**: This function handles different callback triggers:
  * **INITIALIZE**: When the payment process starts.
  * **SHIPPING\_ADDRESS**: When the user updates their shipping address.
  * **SHIPPING\_OPTION**: When the user selects a different shipping option.

This setup allows for a flexible and dynamic pricing model using Google Pay, enhancing the user experience by providing real-time updates based on shipping selections.\
For more detailed please refer to the official Google Pay API docs <https://developers.google.com/pay/api/web/reference/client#onPaymentDataChanged>
