x402 micropayment, live demo.

Buy a compliance report from StableKYA.com for $0.001 testnet USDC, signed by a Coinbase Smart Wallet and settled on Base Sepolia via the Coinbase CDP x402 facilitator. Watch every stage of the payment lifecycle as it happens.

X402 PAYMENT JOURNEYIntentIdentityDiscoveryNegotiationTransportAuthorizationFacilitationFinality

Your Wallet

The x402 journey begins when you delegate spending authority by connecting a wallet. This demo expects a Coinbase Smart Wallet (an ERC-4337 account-abstraction wallet with a WebAuthn passkey) on Base Sepolia, but any EIP-1193 provider — Coinbase Wallet, MetaMask, Rainbow — will connect. Your wallet's identity, address and chain, becomes the foundation for every compliance check that follows.

YOU ARE HEREIntentIdentityDiscoveryNegotiationTransportAuthorizationFacilitationFinality
L5ApplicationL4MiddlewareL3ExecutionL2ConsensusL1Network▲ STATE TRANSITION▲ Above the STATE TRANSITION line: policy-enforced (off-chain). ▼ At or below: code-enforced (EVM bytecode).Self-Custody EOAWallet UIL5Coinbase Smart WalletYOUR WALLETPasskey UIOFAC / KYTERC-4337L3MPC WalletKYC GateMPC ThresholdL4Hosted / CustodialIdentityGas SponsorL4Agent WalletAgentKitSpend PolicySession KeysL3Code-enforcedPolicy-enforced
The Coinbase Smart Wallet's compliance surface reaches L3 Execution — session keys, spending limits, and transfer hooks are enforced in EVM bytecode by the validateUserOp path of its ERC-4337 account contract, not by an off-chain dashboard. That places it below the STATE line in the diagram above. For the full wallet taxonomy, see StableKYA.com.

The Gate

When any HTTP client — browser, CLI, or AI agent — hits a paywalled resource, the server responds with HTTP 402 Payment Required. The payment requirements are encoded in the response headers. The server doesn't know or care what the client is.

YOU ARE HEREIntentIdentityDiscoveryNegotiationTransportAuthorizationFacilitationFinality
This is what your agent sees when it hits a paywalled resource. The server doesn't know or care whether the client is a browser, a CLI tool, or an autonomous AI agent. The 402 response is the same for all of them.

The Payment

You sign an EIP-3009 transferWithAuthorization against Circle's USDC contract on Base Sepolia — a gasless USDC transfer that the Coinbase CDP x402 facilitator submits on your behalf. OFAC screening (Chainalysis address screening) fires at S6 as a code-enforced gate before the transfer lands on-chain.

YOU ARE HEREIntentIdentityDiscoveryNegotiationTransportAuthorizationFacilitationFinality
Waiting for wallet connection…
OFAC screening fires at S6 as a code-enforced gate. The Coinbase CDP x402 facilitator verifies the EIP-3009 signature, screens the sender address against the Chainalysis sanctioned-address oracle, and only then submits the transferWithAuthorization call to Circle's USDC contract on Base Sepolia. For the full checkpoint taxonomy, see StableKYA.com.

Payment & Delivery

Two events fire in close sequence on two different rails. On the on-chain rail, the Coinbase CDP x402 facilitator drives a transferWithAuthorization call to Circle's USDC contract on Base Sepolia, reaching soft finality in ~2s and inheriting hard finality from Ethereum L1 data availability. On the HTTP rail, the StableKYA Worker responds with 200 OK and the compliance PDF body. The two rails are bound by the x402 protocol into a near-atomic delivery-versus-payment exchange — payment on the left, delivery on the right.

YOU ARE HEREIntentIdentityDiscoveryNegotiationTransportAuthorizationFacilitationFinality
Payment — settled on Base
L5ApplicationL4MiddlewareL3ExecutionL2ConsensusL1Network▲ STATE TRANSITION▲ Above: policy-enforced (off-chain). ▼ At or below: code-enforced (EVM bytecode, unbypassable).Off-chain LedgerAPI ReceiptPSP LedgerL4Base Settlement RailSETTLED VIAHTTP 200 + PDFCoinbase CDPUSDC EIP-3009Base OP-StackEthereum DAL1Ethereum L1 DirectHTTP 200ERC-20 transferEOA txEthereum PoSL2Code-enforcedPolicy-enforced
The Coinbase CDP / Base / USDC rail reaches all the way to L1 Ethereum data availability — every block below the STATE line is enforced in EVM bytecode. Off-chain ledgers never cross the line.
Delivery — resource over HTTP
🔒
LOCKED — PAYMENT REQUIRED

Know Your Agent: Anatomy of an x402 Compliant Transaction

The compliance diagram inside this report maps the transaction you just completed.

The PDF body returned in the 200 OK response is the resource half of the exchange. The compliance diagram inside it maps the transaction you just made.
x402 binds these two events into an atomic delivery-versus-payment exchange — neither side can complete without the other. This is the same DvP property tokenization frameworks have spent a decade trying to engineer for traditional securities settlement, achieved here for a $0.001 PDF download with ~40 lines of Worker code. See AtomicDvP.com for the full thesis.

The Code

The payment flow code — buyer site and publisher Worker — is open source. The server is ~40 lines. The client is ~60.

Server (Worker) — ~40 lines
// stablekya.com/api/report — x402 gate
export default {
  async fetch(request: Request, env: Env) {
    const paymentSig = request.headers
      .get('PAYMENT-SIGNATURE');

    if (!paymentSig) {
      return new Response('Payment Required', {
        status: 402,
        headers: {
          'PAYMENT-REQUIRED': btoa(JSON.stringify({
            accepts: [{
              scheme: 'exact',
              network: 'base-sepolia',
              asset: 'USDC',
              amount: '1000',
              payTo: env.MERCHANT_ADDRESS,
              resource: 'kya-compliance-report-v1',
            }],
          })),
        },
      });
    }

    // Verify payment via facilitator...
    const report = await env.REPORTS
      .get('kya-report-v1.pdf');
    return new Response(report.body, {
      headers: {
        'Content-Type': 'application/pdf',
      },
    });
  },
};
Client (Browser) — ~60 lines
// Stable402.com — x402 buyer flow
async function purchaseReport() {
  // 1. Hit the gate
  const res402 = await fetch(
    'https://stablekya.com/api/report'
  );
  const requirements = JSON.parse(atob(
    res402.headers.get('PAYMENT-REQUIRED')
  )).accepts[0];

  // 2. Sign EIP-3009 authorization
  const signature = await walletClient
    .signTypedData({
      domain: {
        name: 'USDC', version: '2',
        chainId: 84532,
        verifyingContract: USDC,
      },
      types: {
        TransferWithAuthorization: [
          /* from, to, value, ... */
        ],
      },
      message: {
        from: address,
        to: requirements.payTo,
        value: BigInt(requirements.amount),
      },
    });

  // 3. Retry with payment
  const res200 = await fetch(
    'https://stablekya.com/api/report',
    {
      headers: {
        'PAYMENT-SIGNATURE': btoa(
          JSON.stringify({
            x402Version: 2,
            accepted: requirements,
            payload: { signature },
          })
        ),
      },
    }
  );

  // 4. Deliver the PDF
  const pdf = await res200.blob();
  downloadPdf(pdf, 'kya-report.pdf');
}
View on GitHub