> ## Documentation Index
> Fetch the complete documentation index at: https://dev.moonpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Pay

> Details on working with the [Google Pay](/platform/guides/pay-with-google-pay) frame.

## URL

```html theme={null}
https://blocks.moonpay.com/platform/v1/google-pay
```

## Requirements

### Size

The frame container **height must be 44px**. Width is flexible; the Google Pay button inside the frame uses 100% of the container width.

### Permissions

The `payment` [permission policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Permissions-Policy#iframes) is required.

When using a sandboxed iframe, include `allow-scripts`, `allow-popups`, `allow-same-origin`, and `allow-forms`. See [Google Pay inside sandboxed iframe for PCI DSS v4 compliance](https://developers.googleblog.com/google-pay-inside-sandboxed-iframe-for-pci-dss-v4-compliance/) for details.

```tsx Example theme={null}
<iframe
  src="https://blocks.moonpay.com/platform/v1/google-pay"
  allow="payment"
/>
```

## Initialization parameters

| Property                | Type     | Required | Description                                                                                                                                                                                    |
| ----------------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `clientToken`           | `string` | ✅        | The [client token](/platform/guides/api-and-sdk-credentials#client-token) returned from the [connect flow](/platform/guides/connect-a-customer).                                               |
| `channelId`             | `string` | ✅        | A unique identifier for the frame generated on your client. This value is attached to each `postMessage` payload to help identify messages.<br /><br />The format of this string is up to you. |
| `signature`             | `string` | ✅        | The quote `signature` from the quote endpoint. Pass `signature` as returned.                                                                                                                   |
| `externalTransactionId` | `string` |          | Your own identifier for the transaction. Stored and associated with the MoonPay transaction for correlation.                                                                                   |
| `theme`                 | `string` |          | Pass `dark` or `light` to force a specific appearance. If you omit this, the frame uses the user's system appearance.                                                                          |

## Events

All events are dispatched using the message pattern described in the [frames protocol](/platform/frames/overview#frames-protocol#messages). Below are the event payloads specific to the Google Pay frame.

### Outbound events

<Badge size="md" className="px-2" color="purple">
  frame->parent
</Badge>

These events are sent from this frame to the parent window.

#### `handshake`

The frame requests that you open a message channel.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "handshake"
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type HandshakeEvent = Message<{
    kind: "handshake";
  }>;
  ```
</CodeGroup>

#### `ready`

The frame finished loading and the UI is fully rendered. You can use this to coordinate UI transitions if needed.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "ready"
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type ReadyEvent = Message<{
    kind: "ready";
  }>;
  ```
</CodeGroup>

#### `complete`

The transaction is complete. Use the transaction ID to track status updates (for example, by polling or via webhooks).

<CodeGroup>
  ```json Example (success) theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "complete",
    "payload": {
      "transaction": {
        "id": "txn_01",
        "status": "pending"
      }
    }
  }
  ```

  ```json Example (fail) theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "complete",
    "payload": {
      "transaction": {
        "status": "failed",
        "failureReason": "Your payment was declined by your bank.",
        "failureCode": "authorizationDeclined"
      }
    }
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  enum TransactionStatus {
    /** The transaction has successfully completed. The payment has been made and the crypto has been transferred. **/
    completed = "completed",
    /** The payment has been completed and the crypto transfer is underway. **/
    pending = "pending",
    /** The transaction has failed. No payment was applied and the crypto was not transferred. **/
    failed = "failed",
  }

  type FailureCode =
    | "transactionNotAllowed"
    | "validationError"
    | "serviceUnavailable"
    | "authorizationDeclined"
    | "unknown";

  type Transaction =
    | {
        /** The MoonPay identifier for this transaction. **/
        id: string;
        /** The status of the transaction. **/
        status: TransactionStatus.completed | TransactionStatus.pending;
      }
    | {
        status: TransactionStatus.failed;
        /** A stable, machine-readable code identifying the failure category. Branch on this value for programmatic handling. May be omitted when the frame cannot classify the failure. **/
        failureCode?: FailureCode;
        /** A developer-friendly error message detailing the reason for the transaction failure. **/
        failureReason: string;
      };

  type GooglePayCompleteEvent = Message<{
    kind: "complete";
    payload: {
      transaction: Transaction;
    };
  }>;
  ```
</CodeGroup>

##### Failure codes

When a `complete` event has `status: "failed"`, the `failureCode` field indicates the failure category. Use this value — not `failureReason` — for programmatic branching. `failureReason` is a human-readable fallback suitable for display when you do not have custom copy for a given code.

<Note>
  `failureCode` is optional. When the frame cannot classify a failure, it sends
  `failureReason` alone — fall back to showing that message to the customer.
</Note>

| `failureCode`           | Default `failureReason`                              | When it fires                                                                                     | Recommended handling                                                                                       |
| ----------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `transactionNotAllowed` | "This transaction is not allowed for your account."  | Payment method or account is not eligible (for example, region restriction or KYC limit).         | Show the `failureReason` and guide the customer to resolve the issue or choose a different payment method. |
| `validationError`       | "The transaction request was invalid."               | Request failed validation (unsupported currency, missing parameters).                             | Check the quote parameters and retry with corrected values.                                                |
| `serviceUnavailable`    | "Service temporarily unavailable. Please try again." | Upstream payment service is degraded or returned a 5xx response.                                  | Retry with exponential back-off.                                                                           |
| `authorizationDeclined` | "Your payment was declined by your bank."            | The issuer or gateway rejected the authorization.                                                 | Prompt the customer to try a different card.                                                               |
| `unknown`               | "An unexpected error occurred."                      | Any unexpected or unclassified error, including thrown authorization exceptions and fraud blocks. | Show the `failureReason` to the customer and retry.                                                        |

<Tip>
  Quote expiry is reported through the [`error`](#error) event with `code:
      "quoteExpired"`, not through `complete`. Listen for both events to cover all
  failure paths.
</Tip>

#### `challenge`

Verification is required before the transaction can proceed. Render the
[challenge frame](/platform/frames/challenge) at the provided URL. Do not
construct the URL yourself — use it as-is.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "challenge",
    "payload": {
      "kind": "frame",
      "url": "https://blocks.moonpay.com/platform/v1/challenge?challengeToken=..."
    }
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type GooglePayChallengeEvent = Message<{
    kind: "challenge";
    payload: {
      kind: string;
      /** Fully-formed URL to pass directly as the challenge frame src. */
      url: string;
    };
  }>;
  ```
</CodeGroup>

#### `error`

This event dispatches errors that occur in the flow and, if available, provides steps for recovery.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "error",
    "payload": {
      "code": "configurationError",
      "message": "The frame configuration is invalid."
    }
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type GooglePayError = Message<{
    kind: "error";
    payload: {
      code:
        | "configurationError"
        | "quoteExpired"
        | "invalidQuote"
        | "googlePayUnavailable"
        | "generic";
      /** A developer-facing error message with details on recovery or documentation. This message is not intended to be rendered in UI. */
      message: string;
    };
  }>;
  ```
</CodeGroup>

| Code                   | Description                                                          |
| ---------------------- | -------------------------------------------------------------------- |
| `configurationError`   | The frame configuration is invalid. Check initialization parameters. |
| `quoteExpired`         | The quote has expired. Fetch a new quote and send it via `setQuote`. |
| `invalidQuote`         | The quote signature is invalid or malformed.                         |
| `googlePayUnavailable` | Google Pay is not available in the current environment or browser.   |
| `generic`              | An unexpected error occurred.                                        |

### Inbound events

<Badge size="md" className="px-2">
  parent->frame
</Badge>

These events are sent from the parent window to this frame.

#### `ack`

Acknowledge the [handshake](#handshake).

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "ack"
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type AckEvent = Message<{
    kind: "ack";
  }>;
  ```
</CodeGroup>

#### `setQuote`

Provide a new quote to the frame. Pass `signature` as returned by the quote endpoint. Upon receiving this event, the frame disables the Google Pay button until the quote is revalidated.

<CodeGroup>
  ```json Example theme={null}
  {
    "version": 2,
    "meta": { "channelId": "ch_1" },
    "kind": "setQuote",
    "payload": {
      "quote": {
        "signature": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
      }
    }
  }
  ```

  ```ts twoslash TypeScript definition theme={null}
  type Message<T> = T & {
    version: 2;
    meta: { channelId: string };
  };

  type SetQuoteEvent = Message<{
    kind: "setQuote";
    payload: {
      quote: {
        /** The signature from a valid quote. **/
        signature: string;
      };
    };
  }>;
  ```
</CodeGroup>
