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

# Pay

> Accept exact-output payments with the focused Pay component

## Overview

Pay mode implements exact-output payment flows where you specify the precise amount the recipient receives. The user pays whatever is required from their available tokens across all chains.

**Trade type**: `EXACT_OUTPUT` — fixed destination amount, variable input amount.

## Quick start

```tsx theme={null}
import { Pay } from '0xtrails/widget'

<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xYourAddress",
    token: "USDC",
    chain: "base",
    amount: "50",
  }}
  onPaymentSuccess={({ sessionId }) => markOrderPaid(sessionId)}
/>
```

That is the minimum. Every other prop is optional.

## Props

### Required

| Prop           | Type               | Description                                                  |
| -------------- | ------------------ | ------------------------------------------------------------ |
| `apiKey`       | `string`           | Trails API key                                               |
| `to.recipient` | `string`           | Wallet or contract address that receives the payment         |
| `to.currency`  | `string`           | Token symbol or address (e.g. `"USDC"`, `"ETH"`)             |
| `to.chain`     | `ChainIdentifier`  | Destination chain — name (`"base"`), chain ID, or viem Chain |
| `to.amount`    | `string \| number` | Exact amount recipient receives in human-readable units      |

### Source selection (optional)

Pre-select where the user pays from by adding a `from` object. Omit to let the user choose.

```tsx theme={null}
<Pay
  apiKey="YOUR_API_KEY"
  to={{ recipient: "0x...", token: "USDC", chain: "base", amount: "50" }}
  from={{ token: "ETH", chain: "ethereum" }}
/>
```

To control the payment method, set `paymentMethod`:

| Value                 | Method                                 |
| --------------------- | -------------------------------------- |
| `"CONNECTED_WALLET"`  | Connected wallet (default)             |
| `"CRYPTO_TRANSFER"`   | QR code / address deposit              |
| `"CREDIT_DEBIT_CARD"` | Fiat on-ramp                           |
| `"EXCHANGE"`          | CEX transfer (Coinbase, Binance, etc.) |

### Destination options

| Prop              | Type              | Description                                                            |
| ----------------- | ----------------- | ---------------------------------------------------------------------- |
| `to.calldata`     | `string`          | ABI-encoded calldata to execute on the destination chain after payment |
| `to.defaultChain` | `ChainIdentifier` | Default chain — user can change                                        |
| `to.defaultToken` | `string`          | Default token — user can change                                        |

### Shared options

All focused components share these optional props:

| Prop                | Type                          | Description                                           |
| ------------------- | ----------------------------- | ----------------------------------------------------- |
| `payMessage`        | `string`                      | Custom message shown during the payment flow          |
| `appMetadata`       | `AppMetadata`                 | App name, URL, and logo for wallet connection dialogs |
| `dev`               | `DevConfig`                   | Debug flags and internal URL overrides                |
| `theme`             | `"light" \| "dark" \| "auto"` | Widget color theme                                    |
| `renderInline`      | `boolean`                     | Render inline instead of as a modal                   |
| `buttonText`        | `string`                      | Custom CTA text                                       |
| `slippageTolerance` | `number \| string`            | Slippage tolerance (e.g. `0.005` for 0.5%)            |
| `swapProvider`      | `RouteProvider`               | Preferred same-chain swap provider                    |
| `bridgeProvider`    | `RouteProvider`               | Preferred bridge provider                             |

### Lifecycle callbacks

| Callback           | Signature                        | When it fires                   |
| ------------------ | -------------------------------- | ------------------------------- |
| `onPaymentStart`   | `({ sessionId }) => void`        | User initiates the payment flow |
| `onPaymentSuccess` | `({ sessionId }) => void`        | Payment completes successfully  |
| `onPaymentError`   | `({ sessionId, error }) => void` | Payment encounters an error     |

## Examples

### Stablecoin payment

Accept 25 USDC on Polygon from any token on any chain:

```tsx theme={null}
import { Pay } from '0xtrails/widget'

<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xYourMerchantAddress",
    token: "USDC",
    chain: "polygon",
    amount: "25",
  }}
  onPaymentSuccess={({ sessionId }) => {
    updateOrderStatus(orderId, "paid", sessionId)
  }}
>
  <button>Pay $25</button>
</Pay>
```

### Pre-select payment source

Lock the user to pay from ETH on Ethereum:

```tsx theme={null}
<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0x...",
    token: "USDC",
    chain: "base",
    amount: "50",
  }}
  from={{
    token: "ETH",
    chain: "ethereum",
  }}
  onPaymentSuccess={({ sessionId }) => console.log("paid", sessionId)}
/>
```

### QR code / crypto transfer

Let the user pay by sending to an address directly:

```tsx theme={null}
<Pay
  apiKey="YOUR_API_KEY"
  paymentMethod="CRYPTO_TRANSFER"
  to={{
    recipient: "0x...",
    token: "USDC",
    chain: "base",
    amount: "50",
  }}
/>
```

### Fiat on-ramp

Let the user pay with a credit card:

```tsx theme={null}
<Pay
  apiKey="YOUR_API_KEY"
  paymentMethod="CREDIT_DEBIT_CARD"
  to={{
    recipient: "0x...",
    token: "USDC",
    chain: "base",
    amount: "50",
  }}
/>
```

### Payment with contract execution

Execute a function on the destination chain with the payment:

```tsx theme={null}
import { Pay } from '0xtrails/widget'
import { encodeFunctionData } from 'viem'

const mintCalldata = encodeFunctionData({
  abi: [{
    name: 'mint',
    type: 'function',
    stateMutability: 'payable',
    inputs: [{ name: 'to', type: 'address' }],
    outputs: [],
  }],
  functionName: 'mint',
  args: ['0xRecipientAddress'],
})

<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0xNFT_CONTRACT",
    token: "ETH",
    chain: "arbitrum",
    amount: "0.00002",
    calldata: mintCalldata,
  }}
  onPaymentSuccess={({ sessionId }) => console.log("minted", sessionId)}
>
  <button>Mint NFT</button>
</Pay>
```

### App branding and event handling

```tsx theme={null}
<Pay
  apiKey="YOUR_API_KEY"
  to={{
    recipient: "0x...",
    token: "USDC",
    chain: "base",
    amount: "50",
  }}
  payMessage="Payment for Order #4821"
  appMetadata={{
    name: "My Store",
    url: "https://mystore.com",
    imageUrl: "https://mystore.com/logo.png",
  }}
  onPaymentStart={({ sessionId }) => console.log("started", sessionId)}
  onPaymentSuccess={({ sessionId }) => markOrderPaid(sessionId)}
  onPaymentError={({ error }) => console.error("failed", error)}
/>
```

## See also

* [Pay use cases](/use-cases/pay) — merchant integration, NFT purchases, x402
* [Configuration reference](/sdk/configuration) — full prop list
* [Quote providers](/sdk/quote-providers) — CCTP, Relay, and more
