# 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. PayEngine 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="info" %}
Please contact your support representative to enable Google Pay™ for your account.
{% endhint %}

## Using Google Pay™ in your Web Application&#x20;

{% hint style="info" %}
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](https://docs.payengine.co/payengine-developer-docs/getting-started-1/5.-frontend-frameworks).
{% 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",
            {
              merchantID: merchantId,
              token: token,
              amount: String(amount),
            }
          )
          .then((resp) => {
            //Handle Response from your backend
          })
          .catch((err) => {
            //Handle Error from your backend
          });
      };
    window.onload = () => {
      PayEngine.GooglePay.configure({
        merchantId: merchantId,
        hmac:<Your HMAC>,
        amount: amount,
        selector: "#button",
        buttonType: "pay", 
        buttonColor: 'black',
         callback: function (response, error) {
            if (!error) {
              //Handle Success here. Typically call your backend to call PayEngine 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(PayEngine_Server + "/api/payment/sale",
            {
                "merchant_id": req.body.merchantID,
                "data": {
                    "transactionAmount": req.body.amount,
                    "cardToken": req.body.token,
                    "currencyCode": "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
PayEngine.GooglePay.configure({
  merchantId: <Your Merchant ID>,
  hmac:<Your HMAC>,
  amount: <Amount You want to charge>,
  selector: "#button",
  buttonType: "pay", 
  buttonColor: "default", 
  billingAddressRequired: true,
  shippingAddressRequired: true,
  callback: function (response, error) {
    if (!error) {
      //Call Your backend server to execute PayEngine sale API
    } else {
      // Handle error here  
    }
  },
});
```

{% hint style="info" %}
To request billing and/or shipping address set the `billingAddressRequired` and `shippingAddressRequired` 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)&#x20;
{% endhint %}

#### Sample Token Response with metadata

```json
{
    "token": "pe_sandbox_***************",
    "metadata": {
        "shippingAddress": {
            "address3": "",
            "sortingCode": "",
            "address2": "",
            "countryCode": "US",
            "address1": "123 Main Street",
            "postalCode": "90245",
            "name": "John Doe",
            "locality": "Los Ageles",
            "administrativeArea": "CA"
        },
        "billingAddress": {
            "address3": "",
            "sortingCode": "",
            "address2": "",
            "countryCode": "US",
            "address1": "123 Main Street",
            "postalCode": "90245",
            "name": "John Doe",
            "locality": "Los Angeles",
            "administrativeArea": "CA"
        }
    },
    "merchantId": "<Your Merchant ID>"
}
```

### Customizing Google Pay™ button

You can customize the label and color of your Google Pay™ Button by providing `buttonType` and `buttonColor` attributes in Google Pay™ configuration object.&#x20;

```javascript
  buttonType: 'pay', // "book" | "buy" | "checkout" | "donate" | "order" | "pay" | "plain" | "subscribe" | "long" | "short"
  buttonColor: '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
PayEngine.GooglePay.configure({
    ...parameters,
    shippingAddressRequired: true,
    shippingAddressParameters: {
        phoneNumberRequired: false
    },
    shippingOptionRequired: true,
    shippingOptionParameters: {
        defaultSelectedOptionId: shippingOptions[0].id,
        shippingOptions: shippingOptions
    },
    onPaymentDataChanged: onPaymentDataChanged
})
```

* **shippingAddressRequired**: Indicates if the shipping address is mandatory.
* **shippingAddressParameters**: Configuration for the shipping address, including whether the phone number is required.
* **shippingOptionRequired**: Indicates if a shipping option must be selected.
* **shippingOptionParameters**: Sets the default selected shipping option and provides the list of available options.
* **onPaymentDataChanged**: 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 {
        displayItems: [
            {
                label: "Subtotal",
                type: "SUBTOTAL",
                price: amount.toString(),
            },
            {
                label: "Shipping Fee",
                type: "LINE_ITEM",
                price: shippingFee.toString(),
            }
        ],
        currencyCode: "USD",
        totalPriceStatus: "FINAL",
        totalPrice: (amount + shippingFee).toString(),
        totalPriceLabel: "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.newShippingOptionParameters = {
                defaultSelectedOptionId: selectedShippingOption.id,
                shippingOptions: shippingOptions
            }
            paymentDataRequestUpdate.newTransactionInfo = calculateTransactionInfo(selectedShippingOption)
        }
    }
    else if (callbackTrigger == "SHIPPING_OPTION") {
        paymentDataRequestUpdate.newTransactionInfo = 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>
