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

# x402 payment acceptance

> Accept USDC on Base from AI agents over the x402 protocol — paid against a public payment session.

Sprintcheckout lets your merchants accept [x402](https://github.com/coinbase/x402) payments: an AI
agent (or any HTTP client) pays a payment session in **USDC on Base**, and the settled payment shows
up in your dashboard like any other order. Sprintcheckout wraps Coinbase's hosted x402 facilitator —
it does not reimplement the protocol and never custodies funds.

<Warning>
  Your `X-SC-ApiKey` is a **secret server credential**. It authorizes creating and updating payment
  sessions on your behalf. **Never** ship it to an agent, a browser, or any buyer-side code. The
  agent only ever needs the **public `sessionId`**.
</Warning>

## How it works

<Steps>
  <Step title="Configure your Base wallet">
    In **Settings → Wallet address**, set the Base wallet that should receive USDC. This existing
    address is what the `402` challenge quotes as `payTo`. No x402-specific configuration is needed.
  </Step>

  <Step title="Create a payment session (server-side)">
    Your backend creates a session with your secret `X-SC-ApiKey` and receives a public `sessionId`.
  </Step>

  <Step title="Hand the agent the public sessionId">
    Give the agent only the `sessionId` — never the API key.
  </Step>

  <Step title="The agent pays over x402">
    The agent requests the x402 endpoint with the public `sessionId`, receives a `402 Payment
            Required` quoting your wallet and the USDC amount, pays on Base, and retries with proof.
  </Step>

  <Step title="Settlement appears in your dashboard">
    On success the payment is settled via Coinbase's facilitator and recorded as a paid order —
    visible in your dashboard transaction list with a BaseScan receipt.
  </Step>
</Steps>

## 1. Merchant — create a payment session

This runs on **your** server, with your secret `X-SC-ApiKey`. The response `sessionId` is the public
identifier the agent will pay.

```bash cURL theme={null}
curl --request POST \
  --url https://api.sprintcheckout.com/api/checkout/v2/payment_session \
  --header 'X-SC-ApiKey: <YOUR_SECRET_API_KEY>' \
  --header 'Content-Type: application/json' \
  --data '{
    "amount": 0.01,
    "currency": "USD",
    "orderType": "TRANSIENT",
    "orderId": "agent-demo-001"
  }'
```

```json Response theme={null}
{
  "sessionId": "a7Xk9mQ2pR",
  "redirectUrl": "https://app.sprintcheckout.com/?uid=a7Xk9mQ2pR"
}
```

<Tip>
  A session created from the dashboard **Points of Sale / payment link** flow works exactly the same
  way — its public `uid` is the `sessionId` the agent pays.
</Tip>

## 2. Agent — pay over x402

The agent uses **only the public `sessionId`** — no secret. A first request returns the challenge:

```bash cURL theme={null}
curl -i https://api.sprintcheckout.com/x402/session/a7Xk9mQ2pR
```

```http 402 Payment Required theme={null}
HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "x402Version": 2,
  "accepts": [
    {
      "scheme": "exact",
      "network": "base",
      "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
      "payTo": "0x986dd13ccab3b637032ebedd30ef8a7fea4d6184",
      "maxAmountRequired": "10000",
      "resource": "/x402/session/a7Xk9mQ2pR",
      "description": "x402 payment for session a7Xk9mQ2pR",
      "mimeType": "application/json",
      "maxTimeoutSeconds": 60,
      "extra": { "name": "USD Coin", "version": "2" }
    }
  ]
}
```

`maxAmountRequired` is in USDC base units (6 decimals — `10000` = `0.01` USDC). `payTo` is the
merchant's Base wallet from Settings. `network` is the x402 network name **`base`** (Base mainnet).
`extra` carries USDC's EIP-712 domain (`name`/`version`) that the agent's wallet signs the gasless
transfer against — `x402-fetch` reads it automatically, so you rarely handle it by hand.

The simplest way to pay is the official [`x402-fetch`](https://github.com/coinbase/x402) wrapper,
which handles the challenge, the on-chain USDC payment on Base, and the retry with the `X-PAYMENT`
proof header automatically:

```ts x402-fetch theme={null}
import { wrapFetchWithPayment } from "x402-fetch";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";

const account = privateKeyToAccount(process.env.AGENT_PRIVATE_KEY as `0x${string}`);
const wallet = createWalletClient({ account, chain: base, transport: http() });

// Wrap fetch so 402s are paid and retried automatically.
const fetchWithPayment = wrapFetchWithPayment(fetch, wallet);

const sessionId = "a7Xk9mQ2pR"; // public id, no API key
const res = await fetchWithPayment(
  `https://api.sprintcheckout.com/x402/session/${sessionId}`
);

console.log(res.status); // 200 once paid
console.log(await res.json());
```

<Note>
  **`x402-fetch` caps spend at 0.1 USDC by default.** To pay more, raise the limit:
  `wrapFetchWithPayment(fetch, wallet, maxValue)` where `maxValue` is in USDC base units
  (e.g. `BigInt(1_000_000)` for 1 USDC). Larger amounts also need the buyer wallet funded with
  enough USDC on Base.
</Note>

<Note>
  **Buyer-chosen (variable) amounts.** If the session was created with an editable amount, the agent
  declares what it will pay with an `?amount=` query parameter (in the session's currency) on **both**
  the initial request and the `X-PAYMENT` retry — e.g. `…/x402/session/{sessionId}?amount=2.50`.
  Without it, the `402` body asks for `?amount=` and echoes the `minAmount` floor.
</Note>

Under the hood the second request carries the proof header and returns the resource:

```bash Retry with proof theme={null}
curl -i https://api.sprintcheckout.com/x402/session/a7Xk9mQ2pR \
  --header 'X-PAYMENT: <base64 payment payload>'
```

```http 200 OK theme={null}
HTTP/1.1 200 OK
X-PAYMENT-RESPONSE: <base64 settlement receipt>

{
  "status": "SUCCESS",
  "paymentSessionId": "6a3a46292b5c6620927c3b9f",
  "payTo": "0x986dd13ccab3b637032ebedd30ef8a7fea4d6184",
  "receipt": "https://basescan.org/tx/0x…"
}
```

`receipt` links the settled transaction on BaseScan; the same order appears in your dashboard
transaction list. The `X-PAYMENT-RESPONSE` header is the facilitator's base64 settlement response.

## Response codes

| Status                     | Meaning                                                                                                                                                 |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200 OK`                   | Paid — the resource is returned. A request against an already-settled session also returns `200` **idempotently** (the session is never charged twice). |
| `404 Not Found`            | Unknown or expired `sessionId`.                                                                                                                         |
| `422 Unprocessable Entity` | The merchant has no Base wallet configured in Settings, so no `payTo` can be quoted.                                                                    |
| `402 Payment Required`     | No payment yet, or the submitted proof is missing / invalid / insufficient — re-pay against the returned challenge.                                     |

<Note>
  x402 settlement uses **mainnet USDC on Base** (network `base`, chain id `8453`). It is not available
  on other chains or tokens. Settlement is performed by Coinbase's hosted CDP facilitator; Sprintcheckout
  never holds funds. The buyer pays no gas — the transfer is a gasless EIP-3009 authorization the
  facilitator submits on-chain.
</Note>
