# Implementation

Complete guide to integrating the Google Pay component into your application.

## Overview

The Google Pay component provides a fast, secure payment experience across devices and platforms. The component follows a simple three-step lifecycle:

1. **Initialise**: Configure the SDK with your session and transaction data.
2. **Create & mount**: Build the Google Pay button with your configuration and render it to your page.
3. **Handle callbacks**: Respond to payment success, errors, and other events.


The component automatically handles Google Pay authorization, tokenisation, and transaction processing.

Backend verification is mandatory. Always verify payments on your backend before fulfilling orders. Frontend callbacks can be manipulated by malicious users.

## Before you start

To use the Google Pay component, you first need to:

* Complete the [Google Pay onboarding](/guides/checkout/components/web/google-pay/onboarding) process in the Unity Portal.
* Ensure your website is served over HTTPS (required for Google Pay).
* Configure your Google Pay merchant account and link it to the Unity Portal.


### Browser and device compatibility

Google Pay for Web has specific requirements for optimal functionality.

#### Supported browsers

- Chrome 61+ on all platforms
- Safari 12.1+ on macOS and iOS
- Firefox 62+ on all platforms
- Edge 79+ on Windows and macOS


#### Device requirements

- Android devices: Android 5.0 (Lollipop) or later
- iOS devices: iOS 12.1 or later
- Desktop: Windows 7+, macOS 10.11+, or Linux


#### Configuration requirements

- The customer must have a supported payment method saved in their Google account
- For biometric authentication, the device must support fingerprint or face recognition


## Step 1: Install the Web SDK library

Install the latest version of the Web SDK from the npm public registry. You'll need to have Node.js 22.x or higher.


```shell
npm i @pxpio/web-components-sdk
```

The Google Pay component is part of the main SDK package. Import `PxpCheckout` directly from `@pxpio/web-components-sdk`.

## Step 2: Get your API credentials

In order to initialise Components for Web, you'll need to send authenticated requests to the PXP API.

To get your credentials:

1. In the Unity Portal, go to **Merchant setup > Merchant groups**.
2. Select a merchant group.
3. Click the **Inbound calls** tab.
4. Copy the *Client ID* in the top-right corner.
5. Click **New token**.
6. Choose a number of days before token expiry. For example, `30`.
7. Click **Save** to confirm. Your token is now created.
8. Copy the token ID and token value. Make sure to keep these confidential to protect the integrity of your authentication process.


As best practice, we recommend regularly generating and implementing new tokens.

## Step 3: Create a session on your backend

The Google Pay component requires a session from the PXP Sessions API. This must be done on your backend using HMAC authentication to keep your credentials secure.

For detailed HMAC authentication instructions, see the [card implementation guide](/guides/checkout/components/web/card/implementation#step-3-create-a-session-on-your-backend).

### Session request example


```json
{
  "merchant": "MERCHANT-1",
  "site": "SITE-1",
  "sessionTimeout": 120,
  "merchantTransactionId": "txn-123",
  "transactionMethod": {
    "intent": {
      "card": "Authorisation"
    }
  },
  "amounts": {
    "currencyCode": "USD",
    "transactionValue": 25.00
  },
  "allowTransaction": true
}
```

### Session response

The session response will include Google Pay configuration if it's enabled for your site:


```json
{
  "sessionId": "c5f0799b-0839-43ce-abc5-5b462a98f250",
  "hmacKey": "904bc42395d4af634e2fd48ee8c2c7f52955a1da97a3aa3d82957ff12980a7bb",
  "encryptionKey": "20d175a669ad3f8c195c9c283fc86155",
  "sessionExpiry": "2025-05-19T13:39:20.3843454Z",
  "allowedFundingTypes": {
    "cardSchemes": ["Visa", "Mastercard", "AmericanExpress"],
    "cards": [],
    "wallets": {
      "googlePay": {
        "merchantId": "BCR2DN4TWWPKJ45P",
        "merchantName": "Your Store Name",
        "gatewayMerchantId": "gateway-merchant-id"
      }
    }
  }
}
```

The Google Pay configuration is automatically included in the session response when Google Pay is configured for your site in the Unity Portal.

## Step 4: Initialise the SDK on your frontend

Import `PxpCheckout` from the SDK and initialise with your configuration.


```typescript
import { PxpCheckout, IntentType } from '@pxpio/web-components-sdk';

// Get session data from your backend
const sessionData = await fetch('/api/sessions', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' }
}).then(response => response.json());

// Initialise the SDK
const pxpSdk = PxpCheckout.initialize({
  environment: 'test',
  session: sessionData,
  ownerId: 'MERCHANT-1',
  ownerType: 'MerchantGroup',
  transactionData: {
    currency: 'USD',
    amount: 25,
    entryType: 'Ecom',
    intent: {
      card: IntentType.Authorisation
    },
    merchantTransactionId: crypto.randomUUID(),
    merchantTransactionDate: () => new Date().toISOString()
  },
  kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection
  onGetShopper: () => Promise.resolve({ 
    id: 'shopper-123',
    email: 'customer@example.com',
    firstName: 'John',
    lastName: 'Doe'
  })
});
```

## Step 5: Create and configure the Google Pay button

Use the SDK's `create()` method to build the Google Pay button with your desired configuration:


```typescript
const googlePayButton = pxpSdk.create('google-pay-button', {
  style: {
    type: 'buy',
    color: 'black',
  },
  paymentDataRequest: {
    allowedPaymentMethods: [{
        type: 'CARD',
        parameters: {
            allowedCardNetworks: ['VISA', 'MASTERCARD', 'AMEX'],
            allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
        },
    }],
    transactionInfo: {
      currencyCode: 'USD',
      countryCode: 'US',
      transactionId: sessionData.merchantTransactionId,
      totalPriceStatus: 'FINAL',
      totalPrice: '25',
      displayItems: [
        {
          label: 'Total',
          type: 'LINE_ITEM',
          price: '25',
          status: 'FINAL'
        }
      ],
      totalPriceLabel: 'Total',
      checkoutOption: 'DEFAULT'
    },
  },
  onPreAuthorisation: async () => {
    return {};
  },
  onPostAuthorisation: (data: any) => {
     // CRITICAL: Verify on backend before fulfilling order
     await verifyPaymentOnBackend(data);
  },
  onError: (error: any) => {
    console.error('Google Pay failed:', error);
  },
});
```

### Configuration options

| Parameter | Description |
|  --- | --- |
| `style`object | Button styling options. |
| `style.type`string | Button label type. Possible values: `'buy'`, `'plain'`, `'checkout'`, `'order'`, `'pay'`, `'subscribe'`, `'donate'`. |
| `style.color`string | Button colour. Possible values: `'black'`, `'white'`. |
| `paymentDataRequest`object | Google Pay payment data request configuration. |
| `paymentDataRequest.allowedPaymentMethods`array | Array of allowed payment methods. |
| `paymentDataRequest.allowedPaymentMethods[].type`string | Payment method type (e.g., `'CARD'`). |
| `paymentDataRequest.allowedPaymentMethods[].parameters`object | Payment method parameters. |
| `paymentDataRequest.allowedPaymentMethods[].parameters.allowedCardNetworks`array | Supported card networks (e.g., `['VISA', 'MASTERCARD', 'AMEX']`). |
| `paymentDataRequest.allowedPaymentMethods[].parameters.allowedAuthMethods`array | Allowed authentication methods (e.g., `['PAN_ONLY', 'CRYPTOGRAM_3DS']`). |
| `paymentDataRequest.transactionInfo`object | Transaction information. |
| `paymentDataRequest.transactionInfo.currencyCode`string | Currency code (e.g., `'USD'`). |
| `paymentDataRequest.transactionInfo.countryCode`string | Country code (e.g., `'US'`). |
| `paymentDataRequest.transactionInfo.transactionId`string | Unique transaction identifier. |
| `paymentDataRequest.transactionInfo.totalPriceStatus`string | Total price status (e.g., `'FINAL'`). |
| `paymentDataRequest.transactionInfo.totalPrice`string | Total price as a string. |
| `paymentDataRequest.transactionInfo.displayItems`array | Array of line items to display. |
| `paymentDataRequest.transactionInfo.totalPriceLabel`string | Label for total price. |
| `paymentDataRequest.transactionInfo.checkoutOption`string | Checkout option (e.g., `'DEFAULT'`). |
| `onPreAuthorisation`function | Callback fired before authorisation. Return an empty object `{}` to proceed. |
| `onPostAuthorisation`function | Callback fired when payment succeeds. |
| `onError`function | Callback fired when an error occurs. |


## Step 6: Mount the button to your page

Add a container element to your page where the Google Pay button will be rendered:


```html
<div id="google-pay-container"></div>
```

Then call the `mount()` method to render the button:


```typescript
googlePayButton.mount('google-pay-container');
```

## Step 7: Unmount the component

When your component unmounts (e.g., when navigating away or cleaning up), call the `unmount()` method:


```typescript
return () => {
  googlePayButton.unmount();
};
```

## Step 8: Handle callbacks

### onGetShopper callback

Returns shopper information for transaction processing.


```typescript
onGetShopper: () => Promise.resolve({ 
  id: 'shopper-123',
  email: 'customer@example.com',
  firstName: 'John',
  lastName: 'Doe',
  phoneNumber: '+1-555-0123'
})
```

### onPostAuthorisation callback

Fires when payment succeeds. **CRITICAL: Always verify on your backend before fulfilling orders.**


```typescript
onPostAuthorisation: async (data) => {
  // Verify payment on backend
  const verified = await fetch('/api/verify-payment', {
    method: 'POST',
    body: JSON.stringify({
      systemTransactionId: data.systemTransactionId,
      merchantTransactionId: data.merchantTransactionId
    })
  }).then(r => r.json());
  
  if (verified.success) {
    globalThis.location.href = `/success?orderId=${verified.orderId}`;
  }
}
```

Never trust frontend callbacks for order fulfillment. Always verify payments on your backend using webhooks or the Query Transaction API before fulfilling orders.

## Step 9: Backend verification (CRITICAL)

Frontend callbacks can be manipulated by malicious users. You must verify all payments on your backend before fulfilling orders.

Use the same webhook and API verification patterns described in the [card implementation guide](/guides/checkout/components/web/card/implementation#step-8-backend-verification-critical).

## Complete example

Here's a complete example showing Google Pay integration in a React component:


```typescript
import { PxpCheckout, IntentType } from '@pxpio/web-components-sdk';
import { useEffect, useState } from 'react';

export default function GooglePayPage() {
  const [sessionData, setSessionData] = useState<any>(null);

  const createSession = async () => {
    const createdSession = await fetch('/api/sessions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
          merchant: "MERCHANT-1",
          site: "SITE-1",
          sessionTimeout: 120,
          merchantTransactionId: crypto.randomUUID(),
          transactionMethod: {
            intent: {
              card: "Authorisation"
            }
          },
          amounts: {
            currencyCode: "USD",
            transactionValue: 25.00
          },
          allowTransaction: true
        })

    }).then((response) => response.json());
    setSessionData(createdSession);
  };

  useEffect(() => {
    createSession();
  }, []);

  useEffect(() => {
    if (!sessionData) {
      return;
    }

    const pxpSdk = PxpCheckout.initialize({
      environment: 'test',
      session: sessionData,
      ownerId: 'MECHANT_GROUP_1',
      ownerType: 'MerchantGroup',
      transactionData: {
        currency: 'USD',
        amount: 25,
        entryType: 'Ecom',
        intent: {
          card: IntentType.Authorisation,
        },
        merchantTransactionId: sessionData.merchantTransactionId,
        merchantTransactionDate: () => new Date().toISOString(),
      },
      kountDisabled: false, // OPTIONAL: Set to true to disable Kount fraud detection
      onGetShopper: async () => {
        return {
          id: 'shopper-123',
          email: 'customer@example.com',
          firstName: 'John',
          lastName: 'Doe',
        };
      },
    });

    const googlePayButton = pxpSdk.create('google-pay-button', {
      style: {
        type: 'buy',
        color: 'black',
      },
      paymentDataRequest: {
        allowedPaymentMethods: [{
            type: 'CARD',
            parameters: {
                allowedCardNetworks: ['VISA', 'MASTERCARD', 'AMEX'],
                allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
            },
        }],
        transactionInfo: {
          currencyCode: 'USD',
          countryCode: 'US',
          transactionId: sessionData.merchantTransactionId,
          totalPriceStatus: 'FINAL',
          totalPrice: '25',
          displayItems: [
            {
              label: 'Total',
              type: 'LINE_ITEM',
              price: '25',
              status: 'FINAL'
            }
          ],
          totalPriceLabel: 'Total',
          checkoutOption: 'DEFAULT'
        },
      },
      onPreAuthorisation: async () => {
        return {};
      },
      onPostAuthorisation: async (data: any) => {
        console.log('Google Pay transaction completed:', data.systemTransactionId, data.merchantTransactionId);
        // CRITICAL: Verify on backend before fulfilling order
        await verifyPaymentOnBackend(data);
      },
      onError: (error: any) => {
        console.error('Google Pay failed:', error);
      },
    });

    googlePayButton.mount('google-pay-container');

    return () => {
      googlePayButton.unmount();
    };
  }, [sessionData]);

  return (
    <div>
      <h1>Google Pay</h1>
      <div id="google-pay-container"></div>
    </div>
  );
}
```

## What's next?

Now that you've integrated Google Pay, here are some recommended next steps:

- **[Configuration](/guides/checkout/components/web/google-pay/configuration)**: Learn how to customise the Google Pay button and behavior.
- **[Events](/guides/checkout/components/web/google-pay/events)**: Explore all available callbacks and event handling.
- **[Testing](/guides/checkout/components/web/google-pay/troubleshooting)**: Use test cards and sandbox environment to test your integration.
- **[Configure webhooks](/guides/get-started/about-webhooks)**: Set up server-side webhook handling for reliable payment verification.