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:| Scheme | Signature Type | Properties |
|---|---|---|
| exact | ERC-3009 | Gasless USDC transfer authorization |
| escrow (USDC) | ERC-3009 | Gasless USDC transfer authorization |
| escrow (other) | Permit2 | Universal token approval |
ERC-3009 Authorization
For USDC payments:- Replay protection: Nonces are derived deterministically from payment parameters
- Time-bounded:
validAfterandvalidBeforeconstraints - 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:
deadlineconstraint - Amount-specific: Exact amount authorized
- Gasless: User only signs, facilitator pays gas
Rate Limiting
All endpoints are rate-limited:| Endpoint | Limit |
|---|---|
/api/verify, /api/settle | 1000/min per API key |
/api/quote | 100/min per IP |
| Auth endpoints | 10/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_balanceerror - No funds transferred if balance check fails
Best Practices
For Server Operators
Secure API Key Storage
Secure API Key Storage
- Store API keys in environment variables
- Use secrets management (AWS Secrets Manager, Vault)
- Rotate keys periodically
- Never commit keys to version control
Verify Before Serving
Verify Before Serving
- Always verify payment before serving content
- Don’t trust client-provided payment data
- Use the facilitator’s verify endpoint
Handle Failures Gracefully
Handle Failures Gracefully
- Implement retry logic for transient failures
- Return appropriate error messages
- Log all payment events for auditing
For Client Applications
Balance Checking
Balance Checking
- Use
createBalanceSelectorto check balances before signing - Handle insufficient balance gracefully
- Show clear error messages to users
HTTPS Enforcement
HTTPS Enforcement
- Only communicate over HTTPS
- Validate SSL certificates
- Implement certificate pinning for mobile
User Communication
User Communication
- Show clear payment amounts before signing
- Display which token will be used
- Confirm successful payments
Error Codes
| Code | Meaning | Action |
|---|---|---|
invalid_signature | Signature verification failed | Ensure correct signing parameters |
insufficient_balance | User doesn’t have enough tokens | Check balance, try different token |
quote_expired | Swap quote expired | Retry to get fresh quote |
nonce_already_used | Payment already settled | Idempotent - same result returned |
Smart Contract Architecture
Contract Addresses
Base Mainnet (Production)| Contract | Address |
|---|---|
| AuthCaptureEscrow | 0xA969a17210C80EC60FFEA6b03F4E5624B9Fb92A8 |
| ERC3009PaymentCollector | 0x1f609D30a829a73Cd08FA822C312F85C9eAE1c42 |
| Permit2PaymentCollector | 0x4abafB47f9d7F6A397D0F1F6fa866F1DC568E07D |
| SwapCollector | 0xd06E9a72a12840C682C6F95B50d04cfD0F6F3292 |
| USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 |
| Contract | Address |
|---|---|
| AuthCaptureEscrow | 0xd4840109f8c62D3dD48Bc813eAc1fFCe200bF0Ab |
| ERC3009PaymentCollector | 0x95e266fD447F0d0C557a826ae1f9fB2df1828e3C |
| Permit2PaymentCollector | 0x9099d8AA2694c5A64dFB6421FE64Cf3BdE3464CB |
| SwapCollector | 0x84d9B8a09207a8D2085beAB71D3Dc27a71D2a466 |
| USDC | 0x036CbD53842c5426634e7929541eC2318f3dCF7e |
Contract Security Features
The contracts are built on Base’s Commerce Payments Protocol:| Feature | Implementation |
|---|---|
| Reentrancy Protection | ReentrancyGuardTransient modifier |
| Access Control | Role-based sender validation |
| Amount Safety | Overflow 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.