---
name: gate-dex-x402
version: "2026.4.3-1"
updated: "2026-04-03"
description: "Gate Wallet x402 payment module. Handles HTTP 402 Payment Required responses using the wallet. Use when the user wants to pay for a resource that returns 402, call an API with x402 payment, or fetch a URL that requires payment. Supports four payment schemes: EVM exact (EIP-3009), EVM upto (Permit2), Solana exact (SPL), and Solana upto (SPL). Auto-signs and retries with PAYMENT-SIGNATURE."
---

# Gate DEX x402 Payment

> x402 payment module — pay for APIs that return `402 Payment Required` using the wallet. One tool: `dex_tx_x402_fetch` — send `url` plus optional `method` / `body` / `headers`; on 402 with x402 `accepts`, the MCP server selects a payment scheme, signs, and retries with `PAYMENT-SIGNATURE`.

## Check-in before x402 (mandatory)

**Order is fixed:** complete terminal **`tx-checkin`** in [tx-checkin.md](./tx-checkin.md) **before** calling **`dex_tx_x402_fetch`**. This is the same gate as for `dex_wallet_sign_message` / internal payment signing: **do not** call `dex_tx_x402_fetch` first to discover 402 or to see whether the gateway demands check-in.

1. Confirm payment intent with the user when needed (see **Execution Flow**).
2. Run **`tx-checkin`** with **`-intent` / `-intent-file`**, **`-message`**, or **`-body-file`** as required by the gateway for x402 flows (align `message` / intent with what will be signed for payment — follow backend / [tx-checkin.md](./tx-checkin.md) **Check-in `message` 规则**).
3. On success, read **`checkin_token`** from stdout JSON.
4. Call **`dex_tx_x402_fetch`** with **`checkin_token`** set to that value (tool parameter), plus `url` / `method` / `body` / `headers` / `mcp_token` as usual.

If check-in fails, **abort** — do not proceed to `dex_tx_x402_fetch`.

## Applicable Scenarios

Use when the user wants to pay for a 402 resource or call an API that requires x402 payment:
- Explicit payment language: "pay for this API", "402 payment", "x402 pay", "payment required"
- Fetch-and-pay: "call this URL and pay if 402", "pay and fetch", "x402 fetch"
- URL that returns 402: user provides a URL (e.g., flight order, gated API, premium content)
- Access-gated resources: "fetch this paid endpoint", "pay for access", "unlock this resource"
- Retry after 402: "that URL returned 402, can you pay for it?"

## Capability Boundaries

- Supports: Fetching URLs with automatic x402 payment, EVM exact (EIP-3009), EVM upto (Permit2), Solana exact (SPL), Solana upto (SPL)
- Supported chains: Any EIP-155 EVM chain (eth, base, bsc, etc.) and Solana mainnet/devnet
- Does **not** support: Token transfers (-> [transfer.md](./transfer.md)), token swaps (-> `gate-dex-trade`), DApp interactions (-> [dapp.md](./dapp.md)), market data queries (-> `gate-dex-market`)

**Prerequisites**: MCP Server connected (see parent SKILL.md). User must be logged in (`mcp_token`). Wallet must have an EVM address and/or Solana address for the chain the 402 server accepts.

**Signing / check-in**: Parent [SKILL.md](../SKILL.md) requires terminal [tx-checkin.md](./tx-checkin.md) **before** every `dex_tx_x402_fetch` call in the payment flow. `dex_tx_x402_fetch` signs inside the MCP server; the agent **must** obtain **`checkin_token`** from successful check-in stdout and pass it into the tool (see **Check-in before x402** above). Never use an initial `dex_tx_x402_fetch` call as a substitute for check-in.

---

## MCP Tools

### 1. `dex_tx_x402_fetch` — Request URL with Automatic x402 Payment

Send an HTTP request to the given URL. If the server responds with 402 Payment Required, pay via x402 using the current user's wallet (EVM: EIP-3009 exact, Permit2 upto; Solana: SPL exact/upto), retry automatically, and return the final response or an error.

| Field | Description |
|-------|-------------|
| **Parameters** | `{ url, method?, body?, headers?, mcp_token?, checkin_token? }` — **`checkin_token`** required when the MCP tool defines it and the gateway verifies GV check-in for payment signing (always supply after successful terminal check-in per this doc). |
| **Returns** | `{ status_code, body, headers? }` of the **final** response after any 402 -> pay -> retry |

#### Parameter Details

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `url` | string | Yes | Full request URL (e.g., `https://webws.gate.io:443/flight/order`) |
| `method` | string | No | HTTP method; default `GET` |
| `body` | string | No | Request body (e.g., JSON string for POST) |
| `headers` | string | No | JSON object of headers, e.g., `{"Content-Type":"application/json"}` |
| `mcp_token` | string | No | Auth token; optional if Authorization header is set by client |
| `checkin_token` | string | When required by gateway / tool | From successful terminal **tx-checkin** stdout JSON; **always** run check-in **before** this tool (see **Check-in before x402**). |

#### Call Example (POST with JSON body)

```text
CallMcpTool(
  server="<wallet-mcp-server>",
  toolName="dex_tx_x402_fetch",
  arguments={
    url: "https://example.com/api/order",
    method: "POST",
    body: "{\"flightId\":\"FL001\",\"uid\":\"100\"}",
    headers: "{\"Content-Type\":\"application/json\"}",
    checkin_token: "<from_tx_checkin_stdout>"
  }
)
```

#### Response Example (success after 402 -> pay -> 200)

```json
{
  "status_code": 200,
  "body": "{\"code\":\"0\",\"message\":\"success\",\"data\":{\"orderId\":\"ORD-xxx\",\"status\":\"PAID\",\"orderAmount\":\"0.02\",\"network\":\"eth\",\"asset\":\"0xA0b8...\",\"payTo\":\"0x...\"}}",
  "headers": { "Content-Type": ["application/json"] }
}
```

Agent behavior: Parse `body` and show user **orderId**, **status** (PAID), **amount**, **chain/network**. If `status_code` is not 2xx, show error from body or status.

---

## Supported Payment Types

| Type | Chain / Token | Note |
|------|---------------|------|
| **EVM exact** | Any EIP-155 chain (eth, base, etc.) + EIP-3009 token (e.g., USDC) | User must have EVM address and token balance |
| **EVM upto** | Same chains + ERC-20 via **Permit2** + x402 upto proxy | `amount` = **maximum** authorized; 402 `accepts[].extra` must include `facilitator` (EVM address that will call `settle`). User needs one-time ERC-20 `approve(Permit2)` if not already approved. |
| **Solana exact** | Solana mainnet/devnet + SPL token | User must have Solana address and token balance |
| **Solana upto** | Same as Solana exact at signing time | Client signs SPL transfer for **max** `amount`; facilitator settles actual usage per server (spec still evolving). |

### Payment Scheme Selection Priority

The server's 402 response lists **accepts** (e.g., `scheme`, `network`, `asset`, `payTo`, `amount`, `extra`). The tool selects in order:

**Solana exact -> EVM exact -> Solana upto -> EVM upto**

matching the user's wallet addresses and token balances, then builds the payment payload and retries with `PAYMENT-SIGNATURE`.

### Transaction Recording

When payment succeeds, the backend may write a row to `wallet_transactions` (e.g., `business_type='x402_payment'`). No extra user action is needed.

---

## Execution Flow

```
Step 0: MCP Server connection detection (once per session)
  |
Step 1: Authentication check
  |- No mcp_token -> Route to auth.md
  +- Valid token  -> Continue
  |
Step 2: Confirm payment intent
  |- If user only pastes a URL without explicit payment language,
  |  confirm: "This URL may require payment (402). Proceed?"
  +- If user explicitly says "pay" / "x402" / "402" -> proceed directly
  |
Step 2b: Terminal tx-checkin (mandatory before fetch)
  |- Run tx-checkin per tx-checkin.md (-intent / -message / -body-file as required for x402)
  |- On success, capture checkin_token from stdout JSON
  +- On failure -> abort; do not call dex_tx_x402_fetch
  |
Step 3: Call dex_tx_x402_fetch({ url, method?, body?, headers?, mcp_token?, checkin_token })
  |
Step 4: Server response handling
  |- 200/2xx (no 402) -> Return response to user (no payment occurred)
  |- 402 with x402 payload -> Tool auto-pays and retries:
  |   |- Selects payment scheme in priority order:
  |   |  Solana exact -> EVM exact -> Solana upto -> EVM upto
  |   |- For exact: builds EIP-3009 signature (EVM) or SPL transfer (Solana)
  |   |- For upto: builds Permit2 signature (EVM) or SPL max-transfer (Solana)
  |   |  (EVM upto requires `facilitator` in accepts[].extra)
  |   |- Signs payment, retries with PAYMENT-SIGNATURE header
  |   +- Returns final response (usually 200 + order/PAID status)
  |
Step 5: Display result
  |- Parse body for orderId, status (PAID), amount, chain/network
  +- If not 2xx, show error from body or status
```

---

## Conversation Examples

**Example 1 (Happy Path): Pay for a gated API — GET request**
User: "Call https://example.com/api/order and pay if needed"
Agent:
1. Verify `mcp_token` is valid.
2. Run terminal **tx-checkin** per [tx-checkin.md](./tx-checkin.md); capture **`checkin_token`** from stdout.
3. Call `dex_tx_x402_fetch({ url: "https://example.com/api/order", mcp_token, checkin_token })`.
4. If 402 -> tool auto-pays -> display final response (orderId, status, amount paid).

**Example 2 (Happy Path): POST with JSON body**
User: "Submit a flight order to https://webws.gate.io/flight/order with body {flightId: FL001}"
Agent:
1. Verify `mcp_token` is valid.
2. Run terminal **tx-checkin**; capture **`checkin_token`**.
3. Call `dex_tx_x402_fetch({ url: "...", method: "POST", body: "{\"flightId\":\"FL001\"}", headers: "{\"Content-Type\":\"application/json\"}", checkin_token })`.
4. Display result including payment details if 402 occurred.

**Example 3 (Happy Path): No payment needed — public API**
User: "Fetch https://example.com/public-api"
Agent:
1. Run terminal **tx-checkin**; capture **`checkin_token`** (required before the tool even if no 402).
2. Call `dex_tx_x402_fetch({ url: "...", checkin_token })`.
3. Server returns 200 -> display response directly (no payment occurred).

**Example 4 (Happy Path): Explicit x402 payment**
User: "Use x402 to pay for https://premium.api.io/data"
Agent:
1. User explicitly says "x402" — proceed directly without additional confirmation.
2. Run terminal **tx-checkin**; capture **`checkin_token`**.
3. Call `dex_tx_x402_fetch({ url: "...", mcp_token, checkin_token })`.
4. Display payment result.

**Example 5 (Edge Case): URL pasted without explicit payment intent**
User: "https://example.com/paid-endpoint"
Agent:
1. User only pasted a URL without saying "pay."
2. Confirm: "This URL may require payment (HTTP 402). Would you like me to fetch it and pay if needed?"
3. On user confirmation -> run **tx-checkin**, then `dex_tx_x402_fetch` with **`checkin_token`**.

**Example 6 (Edge Case): Insufficient balance for payment**
User: "Pay for https://example.com/api/premium"
Agent:
1. Run **tx-checkin**, then call `dex_tx_x402_fetch` with **`checkin_token`**.
2. Tool returns error: "Request or payment failed: insufficient USDC balance."
3. Display: "Payment failed — insufficient USDC balance. The resource requires 0.50 USDC but your wallet has 0.10 USDC. Please top up and retry."

**Example 7 (Edge Case): 402 without x402 protocol**
User: "Fetch this URL: https://legacy-api.com/resource"
Agent:
1. Run **tx-checkin**, then call `dex_tx_x402_fetch` with **`checkin_token`**.
2. Server returns 402 but without x402 payload.
3. Display: "The server returned 402 Payment Required but does not follow the x402 protocol. Automatic payment is not possible."

**Example 8 (Edge Case): Retry a previously paid request**
User: "Call that same URL again"
Agent:
1. Warn: "Retrying may result in a duplicate payment if the server doesn't deduplicate by order ID. Proceed?"
2. On confirmation -> **tx-checkin** again, then call `dex_tx_x402_fetch` with new **`checkin_token`**.

**Example 9 (Edge Case): Custom headers needed**
User: "Call https://api.io/order with header Authorization: Bearer mytoken123"
Agent:
1. Run **tx-checkin**; capture **`checkin_token`**.
2. Call `dex_tx_x402_fetch({ url: "...", headers: "{\"Authorization\":\"Bearer mytoken123\"}", checkin_token })`.
3. Display result.

**Example 10 (Edge Case): EVM upto payment with Permit2**
User: "Pay for https://premium.api.io/data — the server uses Permit2 upto"
Agent:
1. Verify `mcp_token` is valid.
2. Run **tx-checkin**; capture **`checkin_token`**.
3. Call `dex_tx_x402_fetch({ url: "...", mcp_token, checkin_token })`.
4. Tool selects EVM upto scheme (if `facilitator` is present in `accepts[].extra`), builds Permit2 signature, retries.
5. If user has not approved the Permit2 contract for the token, tool returns a Permit2 allowance error — guide user to approve Permit2 first via [dapp.md](./dapp.md).
6. After approval, **tx-checkin** again and retry `dex_tx_x402_fetch` with a fresh **`checkin_token`**.

**Example 11 (Edge Case): Permit2 approval needed before upto payment**
User: "That payment failed with a Permit2 allowance error"
Agent:
1. The token has not been approved for the Permit2 contract.
2. Guide user: "You need to approve the Permit2 contract for this token first. Would you like me to help with that?"
3. On confirmation, route to [dapp.md](./dapp.md) for ERC-20 `approve(Permit2)`.
4. After approval, run **tx-checkin** again and retry `dex_tx_x402_fetch` with **`checkin_token`**.

**Example 12 (Edge Case): Server missing facilitator for upto**
User: "Pay for https://api.io/resource"
Agent:
1. Run **tx-checkin**, then call `dex_tx_x402_fetch` with **`checkin_token`**.
2. Tool returns error about missing `facilitator` in `accepts[].extra`.
3. Display: "The server requires upto payment but did not include a facilitator address in its 402 response. This is a server-side configuration issue. Please contact the API provider."

**Example 13 (Boundary Case): Not this module — direct transfer**
User: "Send 1 USDC to 0xABC..."
Agent: Route to [transfer.md](./transfer.md) — this is a direct transfer, not an x402 payment.

**Example 14 (Boundary Case): Not this module — DApp interaction**
User: "Approve USDC for Uniswap Router"
Agent: Route to [dapp.md](./dapp.md) — this is an ERC20 approval / DApp interaction, not an x402 payment.

**Example 15 (Boundary Case): Not this module — market data**
User: "What is USDC price?"
Agent: Route to `gate-dex-market` — this is a market data query.

**Example 16 (Boundary Case): Not this module — swap**
User: "Exchange my USDC for ETH"
Agent: Route to `gate-dex-trade` — this is a token swap, not an x402 payment.

---

## Post-Payment Suggestions

After a successful x402 payment, **proactively display next actions**:

```
✅ Payment complete! Resource content retrieved successfully.
Amount paid: {amount} {token} on {chain}.
Order ID: {orderId} | Status: {status}

You can:
- Check your updated balance
- View the payment transaction details
- Access another paid resource
- Transfer or swap tokens
```

### Follow-up Routing Table

| User Follow-up Intent | Route Target |
|------------------------|--------------|
| Check balance / transaction history | [asset-query.md](./asset-query.md) |
| Login / token expired | [auth.md](./auth.md) |
| Transfer / send tokens | [transfer.md](./transfer.md) |
| Swap tokens | `gate-dex-trade` |
| DApp interaction | [dapp.md](./dapp.md) |
| Use CLI commands | [cli.md](./cli.md) |
| View token prices or market data | `gate-dex-market` |

---

## Error Handling

| Scenario | Handling |
|----------|----------|
| No `mcp_token` or auth failed | Route to [auth.md](./auth.md) for login |
| "Failed to retrieve EVM or Solana address" | Tell user to bind EVM or Solana address for the wallet |
| "no supported payment option" / unsupported scheme | The 402 `accepts` are not compatible with the user's wallet; inform user |
| EVM upto error about `facilitator` | Resource server must include `facilitator` address in `accepts[].extra`; inform user the server configuration is incomplete |
| EVM upto / Permit2 "allowance" or precondition errors | User may need to approve the canonical Permit2 contract once for that token; guide to [dapp.md](./dapp.md) for ERC-20 `approve(Permit2)` |
| "Request or payment failed: ..." | Display error message; may indicate insufficient balance, wrong chain, or server error |
| `status_code` 4xx/5xx in final response | Display status and body to user (e.g., 415 = suggest correct `Content-Type`) |
| Timeout / DNS error calling target URL | Prompt user to verify the URL is correct and reachable |
| 402 response without x402 payload | Inform user the server returned 402 but does not follow x402 protocol; cannot auto-pay |

---

## Security Rules

1. **Check-in first**: Never call `dex_tx_x402_fetch` before a successful terminal **tx-checkin** in the same flow; never use the fetch tool to probe whether check-in is required.
2. **Confirm intent**: If the user only pastes a URL without explicit payment language, confirm they want to pay if the server asks for payment (402). Never auto-pay without user awareness.
3. **Token confidentiality**: Never log or display `mcp_token` in full. Use placeholders like `<mcp_token>`.
4. **Amount transparency**: If the 402 response or final 200 body includes amount/asset, display them so the user knows what was (or will be) paid. For **upto** schemes, clarify that the amount is the **maximum** authorized — actual settlement may be less.
5. **Idempotency warning**: Same URL/body can be retried; duplicate payments may occur if the server does not deduplicate by id/orderId. Warn the user before retrying a previously paid request.
6. **No data fabrication**: Report all responses truthfully. Never invent payment results, amounts, or order IDs.
7. **URL validation**: Only send requests to user-provided URLs. Never construct or modify payment URLs autonomously.
8. **Permit2 awareness**: For EVM upto payments, the user may need a one-time ERC-20 `approve(Permit2)`. If the tool reports allowance errors, guide the user through the approval — do not silently skip.
