Build with Pay
A production-oriented guide for developers (and AI coding agents building apps for developers) wiring Ᵽay into a real application. Each page is one topic you need to understand before launch, and each builds on the ones before it.
For the API surface of any individual SDK or middleware package, see the per-framework pages under Application Middleware or the fetch() Wrapper. This guide sits one layer above those: it is about how the pieces fit together in production, not about the packages themselves.
The Seven Pages
Choosing Your Integration — Before you pick a middleware package, decide whether you need middleware at all. Five common scenarios and the right integration layer for each: CLI,
createPayFetch, consumer middleware, provider middleware, or pay-gate.Wallet Key Management in Production — Where the wallet private key comes from in each environment: OS keychain for local dev,
PAYSKILL_KEYenv var for Docker, CI, Kubernetes, Vercel, Lambda, Cloud Run. Key rotation walkthrough and the anti-patterns list.Tab Lifecycle in Long-Running Services — Two patterns for tab management (let the SDK auto-open, or persist tab IDs to a database and top up on
tab.low_balance). Tab sizing by call volume and the shutdown decision.Spending Controls & Budgeting — Three layers of spend safety:
maxPerRequest,maxTotal, and application-level per-provider caps via theonPaymentcallback. Monitoring spend via the audit trail,wallet.status(), and webhooks.Error Handling for x402 — Every error class the SDK raises, what causes it, and the recovery pattern that fits. Full catch-all handler in TypeScript and Python.
Going to Production — Seven-item pre-launch checklist tying the earlier pages together. Latency budget table and a six-step pre-launch dry run against a small real-USDC staging wallet.
Choosing Settlement Mode — Tab vs. direct settlement as a provider-side decision. Three worked cost comparisons. When to mix modes per route.
Who This Guide Is For
- Application developers shipping a service that calls paid APIs (consumer side) or charges for paid APIs (provider side)
- AI coding agents generating code for developers who have never touched x402 before
- Operators taking over a Ᵽay-enabled service and needing the production-concerns cheat sheet
It is not for:
- Agent-with-wallet use cases that want to call APIs from a shell or an MCP tool — see the CLI reference and the Claude Desktop quickstart instead
- One-off scripts that call one paid API and exit — see the fetch() Wrapper directly
- Providers who just want a reverse proxy in front of an existing API — see pay-gate
Each of those has a shorter path to "working." This guide is for the cases where the short path is not enough.
Conventions Across the Guide
Every page uses the same conventions so you can skim them predictably:
- Mainnet is the default in every example. Testnet is for internal development and is not advertised here.
Wallet.create()(OS keychain) is the recommended local-dev setup. Production examples useWallet.fromEnv()/Wallet.from_env()to fail loud ifPAYSKILL_KEYis missing.- TypeScript and Python code is shown side-by-side via
::: code-groupblocks where both languages apply. - No silent fallbacks. Every recovery pattern either succeeds visibly or fails visibly. Swallowing a payment error to return default data is called out as an anti-pattern on multiple pages.
- Cross-links between pages are one level deep. Each page links back to the guide index and forward to the next deep dive, but no page assumes you have read every page before it.
Where to Start
If you are starting from scratch, read Choosing Your Integration first to figure out which layer you need. Most readers only end up touching a subset of the pages — for example, a consumer-only Next.js app can skip the provider-facing parts of Settlement Mode and the provider middleware on the overview page.
If you already have a working integration and want to ship it, jump to Going to Production and work backwards through the links to the deep-dive pages it references.
If you are debugging a running integration, the two pages that cover the "why did this error happen" questions are Error Handling for x402 and Tab Lifecycle.