Skip to main content

Security

The x402 payment system is designed with security as a primary concern. This page covers the security model and best practices.

Security Model

Signature-Based Authorization

All payments are authorized via cryptographic signatures:
SchemeSignature TypeProperties
exactERC-3009Gasless USDC transfer authorization
escrow (USDC)ERC-3009Gasless USDC transfer authorization
escrow (other)Permit2Universal token approval

ERC-3009 Authorization

For USDC payments:
  • Replay protection: Nonces are derived deterministically from payment parameters
  • Time-bounded: validAfter and validBefore constraints
  • Receiver-locked: Authorization tied to specific receiver
  • Gasless: User only signs, facilitator pays gas

Permit2 Authorization

For non-USDC tokens (WETH, DAI, USDT):
  • Universal: Works with any ERC-20 token
  • Time-bounded: deadline constraint
  • Amount-specific: Exact amount authorized
  • Gasless: User only signs, facilitator pays gas

Rate Limiting

All endpoints are rate-limited:
EndpointLimit
/api/verify, /api/settle1000/min per API key
/api/quote100/min per IP
Auth endpoints10/min per IP

Attack Vectors & Mitigations

Replay Attacks

Risk: Attacker replays valid payment signature Mitigations:
  • Each payment has a unique nonce derived from parameters
  • Facilitator tracks settled payments
  • Same signature cannot be settled twice
  • Idempotency built into protocol

Signature Forgery

Risk: Attacker creates fake payment signature Mitigations:
  • EIP-712 typed data prevents signature reuse across contexts
  • Domain separator includes chain ID and contract address
  • Only the wallet owner can produce valid signatures

Man-in-the-Middle

Risk: Attacker intercepts payment between client and server Mitigations:
  • HTTPS required for all communications
  • Payment signature is cryptographically bound to payment parameters
  • Changing any parameter invalidates the signature

Insufficient Balance

Risk: User signs payment but lacks balance at settlement time Mitigations:
  • Facilitator verifies on-chain balance before settling
  • Payment fails gracefully with insufficient_balance error
  • No funds transferred if balance check fails

Best Practices

For Server Operators

  • Store API keys in environment variables
  • Use secrets management (AWS Secrets Manager, Vault)
  • Rotate keys periodically
  • Never commit keys to version control
  • Always verify payment before serving content
  • Don’t trust client-provided payment data
  • Use the facilitator’s verify endpoint
  • Implement retry logic for transient failures
  • Return appropriate error messages
  • Log all payment events for auditing

For Client Applications

  • Use createBalanceSelector to check balances before signing
  • Handle insufficient balance gracefully
  • Show clear error messages to users
  • Only communicate over HTTPS
  • Validate SSL certificates
  • Implement certificate pinning for mobile
  • Show clear payment amounts before signing
  • Display which token will be used
  • Confirm successful payments

Error Codes

CodeMeaningAction
invalid_signatureSignature verification failedEnsure correct signing parameters
insufficient_balanceUser doesn’t have enough tokensCheck balance, try different token
quote_expiredSwap quote expiredRetry to get fresh quote
nonce_already_usedPayment already settledIdempotent - same result returned

Smart Contract Architecture

Contract Addresses

Base Mainnet (Production) Base Sepolia (Testnet)

Contract Security Features

The contracts are built on Base’s Commerce Payments Protocol:
FeatureImplementation
Reentrancy ProtectionReentrancyGuardTransient modifier
Access ControlRole-based sender validation
Amount SafetyOverflow protection, balance verification

View Source Code

Open-source, auditable smart contracts

Auditing

The contracts are based on Base’s Commerce Payments Protocol. Contact us for audit reports.