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

# Google Pay Mobile

> Learn how to enable Google Pay for token checkout and onramp flows using Crossmint's mobile SDKs

<Info>
  **This guide is for mobile apps only.** For web applications, Google Pay works automatically when enabled via the `payment.fiat.allowedMethods.googlePay` prop—no additional setup required. See [Payment Methods](/payments/embedded/guides/payment-methods) for web configuration.
</Info>

This guide covers how to enable Google Pay for token checkout and onramp flows in **React Native** and **Android native (Kotlin)** applications. Mobile apps require additional native configuration that web apps don't need.

## Overview

Crossmint's mobile SDKs provide pre-built checkout components that support Google Pay out of the box. When properly configured, users see the native Android Google Pay sheet, providing seamless access to payment credentials stored in Google Wallet without leaving your app.

### Mobile vs Web

| Platform                   | Setup Required         | Guide                                                        |
| -------------------------- | ---------------------- | ------------------------------------------------------------ |
| Web (React, Next.js, etc.) | Enable via props only  | [Payment Methods](/payments/embedded/guides/payment-methods) |
| React Native (Expo)        | Expo plugin + rebuild  | This guide                                                   |
| React Native (Bare)        | Manual Android config  | This guide                                                   |
| Android Native (Kotlin)    | AndroidManifest config | This guide                                                   |

### Supported Use Cases

* Token purchases (buy tokens with fiat)
* Stablecoin onramp (USDC, etc.)
* NFT checkout

## Mobile SDK Integration

<Tabs>
  <Tab title="React Native">
    ### Prerequisites

    Before starting, ensure you have:

    * React Native project with Expo or bare workflow
    * Crossmint account with API keys (staging and/or production)
    * Android device or emulator with Google Play Services

    <Steps>
      <Step title="Install Dependencies">
        ```shell theme={null}
        pnpm add @crossmint/client-sdk-react-native-ui
        ```

        The SDK includes `react-native-webview` as a dependency. If you need to install it separately, ensure version **13.15.0 or higher**:

        ```shell theme={null}
        pnpm add react-native-webview@^13.15.0
        ```
      </Step>

      <Step title="Configure the Expo Plugin">
        Update your `app.json` to enable Google Pay:

        ```json theme={null}
        {
          "expo": {
            "plugins": [
              [
                "@crossmint/client-sdk-react-native-ui",
                {
                  "enableGooglePay": true
                }
              ]
            ]
          }
        }
        ```

        <Warning>
          This plugin modifies native Android permissions required for Google Pay. The app must be rebuilt after adding this configuration.
        </Warning>
      </Step>

      <Step title="Rebuild Your App">
        Hot reload cannot apply the permission changes. You must rebuild:

        ```shell theme={null}
        npx expo run:android
        ```

        Or for bare React Native:

        ```shell theme={null}
        npx react-native run-android
        ```
      </Step>

      <Step title="Implement the Checkout Component">
        Use `CrossmintEmbeddedCheckout` for token purchases:

        ```javascript theme={null}
        import {
          CrossmintEmbeddedCheckout,
          CrossmintProvider,
        } from "@crossmint/client-sdk-react-native-ui";

        export default function CheckoutScreen() {
          return (
            <CrossmintProvider apiKey="your_client_side_api_key">
              <CrossmintEmbeddedCheckout
                recipient={{
                  walletAddress: "YOUR_WALLET_ADDRESS",
                }}
                payment={{
                  crypto: { enabled: false },
                  fiat: {
                    enabled: true,
                    allowedMethods: {
                      card: true,
                      applePay: false,
                      googlePay: true,
                    },
                  },
                }}
                lineItems={{
                  tokenLocator: "solana:TOKEN_ADDRESS",
                  executionParameters: {
                    mode: "exact-in",
                    amount: "1",
                    maxSlippageBps: "500",
                  },
                }}
              />
            </CrossmintProvider>
          );
        }
        ```

        <Note>
          For staging/testing, use the XMEME test token:

          ```javascript theme={null}
          tokenLocator: "solana:7EivYFyNfgGj8xbUymR7J4LuxUHLKRzpLaERHLvi7Dgu"
          ```
        </Note>
      </Step>

      <Step title="Customize Appearance (Optional)">
        Hide destination and email inputs for a cleaner UI:

        ```javascript theme={null}
        <CrossmintEmbeddedCheckout
          // ... other props
          appearance={{
            rules: {
              DestinationInput: { display: "hidden" },
              ReceiptEmailInput: { display: "hidden" },
            },
            variables: {
              colors: {
                backgroundPrimary: "#000000",
                textPrimary: "#ffffff",
              },
            },
          }}
        />
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Android Native (Kotlin)">
    <Note>
      The Kotlin SDK is currently in **Beta**. It provides the same checkout functionality with native Jetpack Compose components.
    </Note>

    ### Prerequisites

    * Minimum Android SDK version 24 (Android 7.0)
    * Jetpack Compose
    * Crossmint account with API keys

    <Steps>
      <Step title="Add the SDK Dependency">
        In your app-level `build.gradle.kts`:

        ```kotlin theme={null}
        dependencies {
            implementation("com.crossmint:crossmint-sdk-android:0.0.9")
        }
        ```
      </Step>

      <Step title="Configure AndroidManifest.xml">
        Add the required query intents to enable Google Pay functionality:

        ```xml theme={null}
        <manifest xmlns:android="http://schemas.android.com/apk/res/android">
            <queries>
                <intent>
                    <action android:name="org.chromium.intent.action.PAY"/>
                </intent>
                <intent>
                    <action android:name="org.chromium.intent.action.IS_READY_TO_PAY"/>
                </intent>
                <intent>
                    <action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS"/>
                </intent>
            </queries>
        </manifest>
        ```
      </Step>

      <Step title="Create Orders Server-Side">
        <Warning>
          **Security requirement:** Order creation must happen on your backend to protect your API key.
        </Warning>

        <CodeGroup>
          ```bash cURL theme={null}
          curl --location 'https://staging.crossmint.com/api/2022-06-09/orders' \
          --header 'x-api-key: YOUR_SERVER_API_KEY' \
          --header 'Content-Type: application/json' \
          --data-raw '{
              "recipient": {
                  "walletAddress": "YOUR_WALLET_ADDRESS"
              },
              "payment": {
                  "receiptEmail": "user@example.com",
                  "method": "card"
              },
              "lineItems": {
                  "tokenLocator": "solana:TOKEN_ADDRESS",
                  "executionParameters": {
                      "mode": "exact-in",
                      "amount": "1"
                  }
              }
          }'
          ```

          ```javascript Node.js theme={null}
          const url = 'https://staging.crossmint.com/api/2022-06-09/orders';

          const payload = {
              recipient: {
                  walletAddress: "YOUR_WALLET_ADDRESS"
              },
              payment: {
                  receiptEmail: "user@example.com",
                  method: "card"
              },
              lineItems: {
                  tokenLocator: "solana:TOKEN_ADDRESS",
                  executionParameters: {
                      mode: "exact-in",
                      amount: "1"
                  }
              }
          };

          const options = {
              method: 'POST',
              headers: {
                  'x-api-key': 'YOUR_SERVER_API_KEY',
                  'Content-Type': 'application/json'
              },
              body: JSON.stringify(payload)
          };

          const response = await fetch(url, options);
          const data = await response.json();
          console.log(data);
          ```

          ```python Python theme={null}
          import requests

          url = "https://staging.crossmint.com/api/2022-06-09/orders"

          payload = {
              "recipient": {
                  "walletAddress": "YOUR_WALLET_ADDRESS"
              },
              "payment": {
                  "receiptEmail": "user@example.com",
                  "method": "card"
              },
              "lineItems": {
                  "tokenLocator": "solana:TOKEN_ADDRESS",
                  "executionParameters": {
                      "mode": "exact-in",
                      "amount": "1"
                  }
              }
          }

          headers = {
              "x-api-key": "YOUR_SERVER_API_KEY",
              "Content-Type": "application/json"
          }

          response = requests.post(url, json=payload, headers=headers)
          print(response.json())
          ```
        </CodeGroup>

        The response includes `orderId` and `clientSecret` needed for the checkout component.
      </Step>

      <Step title="Implement the Checkout Component">
        ```kotlin theme={null}
        import com.crossmint.kotlin.checkout.CheckoutEnvironment
        import com.crossmint.kotlin.checkout.CrossmintEmbeddedCheckout
        import com.crossmint.kotlin.checkout.models.*

        @Composable
        fun CheckoutScreen(orderId: String, clientSecret: String) {
            CrossmintEmbeddedCheckout(
                orderId = orderId,
                clientSecret = clientSecret,
                payment = CheckoutPayment(
                    crypto = CheckoutCryptoPayment(enabled = false),
                    fiat = CheckoutFiatPayment(
                        enabled = true,
                        allowedMethods = CheckoutAllowedMethods(
                            googlePay = true,
                            applePay = false,
                            card = true
                        )
                    )
                ),
                appearance = CheckoutAppearance(
                    rules = CheckoutAppearanceRules(
                        destinationInput = CheckoutDestinationInputRule(display = "hidden"),
                        receiptEmailInput = CheckoutReceiptEmailInputRule(display = "hidden")
                    )
                ),
                environment = CheckoutEnvironment.STAGING,
                modifier = Modifier.fillMaxSize()
            )
        }
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

## Google Pay Production Approval

Google Pay works immediately in **staging** environments. For **production**, Google requires explicit approval of your app.

<AccordionGroup>
  <Accordion title="Step 1: Create Your Business Profile">
    1. Navigate to the [Google Pay & Wallet Console](https://pay.google.com/business/console)
    2. Select "Merchant" as your business type
    3. Complete all business profile information
    4. Navigate to **Google Pay API** and click "Get Started"
    5. Accept the Google Pay API Terms of Service
    6. Note your **Merchant ID** (top-right corner after completion)
  </Accordion>

  <Accordion title="Step 2: Submit Your Android App for Approval">
    In the Google Pay & Wallet Console:

    1. Navigate to **Google Pay API** then **Integrations** then **Integrate with your Android app**
    2. Locate your Android application and click "Manage"
    3. Select your integration type (typically "Gateway")
    4. Upload screenshots of your TEST Google Pay integration
    5. Click "Save" then "Submit for approval"

    **Required Screenshots:**

    * Product/item selection showing Google Pay option
    * Cart or checkout view with payment options
    * Google Pay payment sheet with card selection
    * Confirmation or receipt screen
  </Accordion>

  <Accordion title="Step 3: Go Live">
    After Google approval (typically \~1 business day):

    1. Sign your APK with a **release key** (debug keys don't work in production)
    2. Update environment settings:
       * Kotlin: `environment = CheckoutEnvironment.PRODUCTION`
       * React Native: Use production API key
    3. Publish your app to Google Play Store
  </Accordion>
</AccordionGroup>

## SDK Version Requirements

| Component                                        | Minimum Version |
| ------------------------------------------------ | --------------- |
| `@crossmint/client-sdk-react-native-ui`          | Latest          |
| `react-native-webview` (if installed separately) | 13.15.0         |
| `com.crossmint:crossmint-sdk-android`            | Latest          |
| Google Play Services (user device)               | 25.18.30        |

## Troubleshooting

<AccordionGroup>
  <Accordion title="Google Pay button doesn't appear">
    1. **Plugin not configured:** Verify `enableGooglePay: true` in `app.json` plugins
    2. **App not rebuilt:** Run `npx expo run:android` after adding the plugin
    3. **Environment mismatch:** Staging works without approval; production requires it
    4. **Payment method disabled:** Check `googlePay: true` in `allowedMethods`
  </Accordion>

  <Accordion title="PaymentRequest API is not supported error">
    1. **AndroidManifest missing queries:** Add all three Chromium intent queries
    2. **Native rebuild required:** Hot reload cannot apply permission changes
    3. **Device requirements:** User needs Google Play Services 25.18.30+ and WebView 137+
  </Accordion>

  <Accordion title="Order status stuck on undefined">
    1. Check that your API key is valid for the environment (staging vs production)
    2. Verify the `tokenLocator` is correct and available
    3. Ensure the quote hasn't expired (quotes have time limits)
  </Accordion>

  <Accordion title="Token checkout errors">
    **"Token purchase is only available in production":** Some tokens only work in production. Use the XMEME test token for staging: `7EivYFyNfgGj8xbUymR7J4LuxUHLKRzpLaERHLvi7Dgu`
  </Accordion>
</AccordionGroup>

## Testing Guidance

<Tabs>
  <Tab title="Staging Environment">
    * Use staging API keys from your Crossmint console
    * Google Pay functions immediately after proper configuration
    * Use XMEME test token for token testing
    * Test with real Google accounts and saved payment methods
  </Tab>

  <Tab title="Production Environment">
    * Requires completed Google approval process
    * Sign APK with release key
    * Use production API keys
    * Real charges may occur - test with small amounts
  </Tab>
</Tabs>

## Useful Resources

<CardGroup cols={2}>
  <Card title="React Native Token Quickstart" icon="mobile" iconType="duotone" href="/payments/embedded/quickstarts/credit-card-memecoin-react-native">
    Get started with token checkout in React Native
  </Card>

  <Card title="Google Pay & Wallet Console" icon="wallet" iconType="duotone" href="https://pay.google.com/business/console">
    Manage your Google Pay merchant account
  </Card>

  <Card title="Checkout Expo Demo" icon="github" iconType="duotone" href="https://github.com/Crossmint/checkout-expo-demo">
    Example React Native Expo project with checkout
  </Card>

  <Card title="Kotlin Checkout SDK" icon="github" iconType="duotone" href="https://github.com/Crossmint/crossmint-kotlin-checkout">
    Example Android Kotlin project with checkout
  </Card>
</CardGroup>
