Skip to content

Quick start

Complete the shortest path from a payment reference to an on-chain settlement.

x402 PaySDK turns a payment request into a portable PaymentRef. The same reference can travel through a QR code, link, app deep link, or API response without changing the payment protocol.

Choose your integration

You are buildingStart withResponsibility
Wallet or payer appx402-paysdk/payResolve a ref, verify the offer, request a wallet signature, and submit payment.
Receiver toolx402-paysdk/receiveCreate, inspect, list, and revoke payment references.
Merchant backendx402-paysdk/merchantRegister, manage refs and orders, verify receipts, process notify events, and reconcile.
Gateway operatorRust gateway cratesRun a native service or Cloudflare Worker without custodying payer funds.

Install the payer SDK

Shell
npm install x402-paysdk

Provide a wallet adapter that signs EIP-712 typed data. The SDK prepares the EIP-3009 authorization and never asks for a private key.

TypeScript
import { pay } from 'x402-paysdk/pay';const result = await pay({ refUrl: paymentRef, paymentId: crypto.randomUUID(), wallet: { address: account.address, signTypedData: (typedData) => walletClient.signTypedData(typedData) }});console.log(result.status, result.txHash);

By default, pay() requires a signed offer, discovers the gateway identity, verifies the offer context, requests the wallet signature, submits PAYMENT-SIGNATURE, and returns the settlement and signed receipt.

Understand the successful path

  1. The receiver creates a PaymentRef.
  2. The payer requests /receive/:payTo and receives 402 Payment Required.
  3. The payer SDK verifies the signed offer and exact payment context.
  4. The wallet signs an EIP-3009 authorization for USDC.
  5. The gateway asks the facilitator to verify and settle.
  6. USDC moves directly from payer to receiver on-chain.
  7. The gateway returns the tx hash and, when configured, a signed receipt.

The gateway does not hold payer keys or funds. For financial finality, verify the transaction on-chain rather than relying only on a webhook.

Next steps