PayGate402
Turning HTTP's forgotten 402 Payment Required status code into a real, working protocol for wallet-native API micropayments.
Inspiration
Every API monetization model today forces the same trade-off: subscriptions that overcharge low-usage developers, or manually-issued API keys with no native metering or settlement. Meanwhile, HTTP has had a status code sitting unused in the spec since the 90s — 402 Payment Required — designed for exactly this problem and never implemented by anyone. With wallets, signatures, and on-chain settlement now a normal part of the developer toolkit, we wanted to find out what it would actually take to make 402 real: not a mocked "pay $5/mo" banner, but a genuine challenge/verify/settle handshake backed by a signed transaction. We also kept coming back to agent-to-agent commerce — if AI agents are going to call paid APIs on a user's behalf, they need a payment primitive that doesn't involve a human filling out a credit card form. 402 plus a wallet is that primitive.
What it does
PayGate402 is a developer wallet dashboard built around the x402 protocol:
- Wallet-native auth — no email or password. Connect an EVM wallet (MetaMask or any
window.ethereumprovider), sign a Sign-In-With-Ethereum (SIWE) message, and that wallet address is your account. - API marketplace — browse a real seeded catalog of APIs with pricing, category, provider, docs links, and live success-rate/latency stats computed from actual logged usage.
- HTTP 402 Playground — walks through the full protocol handshake end-to-end:
- Client requests a protected endpoint
- Server responds
402with aPAYMENT-REQUIREDheader - Wallet signs a payment-authorization message (real ECDSA signature)
- Server verifies the signature against its own stored challenge
- Client settles on-chain via a deployed Solidity contract (
ethers.js) - Server verifies the settlement before granting access
- Credits ledger — buying credits calls
purchaseCredits()on the deployed contract directly; the resulting transaction (hash, block, gas fee) is persisted to Postgres. - Receipts — every settlement produces a verifiable receipt (wallets, credits, ETH amount, gas fee, tx hash, block number, Etherscan link) with JSON export and search/filter.
- Usage analytics — calls over time, credits consumed, ETH spent, latency, success rate, and top APIs, all computed from real logged data.
- Account assistant — a deterministic Q&A assistant that answers questions about your own credits/receipts/usage by querying your real account data, with no external LLM call and no fabricated numbers.
How we built it
- Framework: Next.js 15 (App Router), React 19, TypeScript
- Styling: Tailwind CSS
- State: Zustand (auth/notifications/chat) + TanStack Query
- Database: PostgreSQL (Supabase) via Prisma ORM — modeling
User,Wallet,Api,Transaction,Receipt,UsageLog,CreditLedger - Auth: Sign-In-With-Ethereum (EIP-191
personal_sign), signature recovery viaethers.verifyMessage, JWT sessions (jose) inhttpOnlycookies, middleware-enforced route protection - Blockchain:
ethers.jsv6 against a hand-written Solidity contract (X402PaymentLedger.sol) deployed to Sepolia via Remix - Charts: Recharts
- Validation: Zod
- Testing: Vitest
The architecture keeps every wallet touchpoint isolated in a single provider (blockchain/providers/Web3Provider), with domain logic split into one service per concern (wallet, payment, receipt, credit, marketplace, analytics, chat, policy, user, SIWE) so the 402 handshake, signature verification, and settlement logic could each be tested independently of the UI.
Challenges we ran into
- Making the 402 handshake actually protocol-correct, not just a UI illusion — the server has to generate and store a real challenge, verify a real signature against it, and independently verify the on-chain settlement before granting access, with no shortcuts on any of those three steps.
- Preventing double-settlement — a wallet resubmitting the same signed payload had to be rejected via a duplicate-settlement cache with TTL behavior, which needed its own dedicated test coverage.
- Being honest about the demo boundary — deciding early which parts had to be real (auth, signatures, on-chain settlement, all persisted numbers) versus which could be simulated (the actual third-party API behind the paywall, the ETH/credit conversion rate) so the demo doesn't quietly fudge the parts that matter most to trust.
- Wallet-as-identity edge cases — no email/password means no "forgot password" safety net; nonce issuance had to be strictly single-use to prevent replay, and every downstream feature (receipts, analytics, credits) had to be correctly scoped to wallet address with no cross-account leakage.
Accomplishments that we're proud of
- A
402flow where every step is real: real status code, real header encoding, real wallet signature, real server-side verification, real on-chain transaction with a real gas fee and Etherscan-visible hash. - Zero fabricated data anywhere in Receipts, Wallet, or Analytics — every number is a live Postgres query against rows written by actual settlements.
- Contract-calling actions (credit purchase, settlement) fail closed: if
NEXT_PUBLIC_CONTRACT_ADDRESSisn't configured, those actions are disabled in the UI rather than silently no-oping. - A deterministic account assistant that answers real questions about a user's own data without needing (or risking) an external LLM call.
What we learned
- HTTP 402 is genuinely implementable as a protocol, not just a status code — the missing piece was never the spec, it was a settlement layer with fast, cheap, verifiable transactions, which wallets + testnets now provide.
- Treating "wallet address" as the entire identity model radically simplifies auth (no password resets, no email verification, no session hijacking via credential stuffing) but pushes all the safety guarantees onto signature and nonce handling — that surface needs to be airtight, not just functional.
- Being explicit about what's simulated (in the README, in the UI) builds more trust than pretending the whole thing is production-grade — reviewers and users react well to a clear "real vs. simulated" boundary.
What's next for PayGate402
- Multi-chain support — extend beyond Sepolia/EVM to other chains and non-EVM wallets (e.g. Solana).
- A live price oracle — replace the fixed ETH/credit demo peg with a real-time feed.
- A real gateway to third-party APIs — let providers register actual live endpoints behind the 402 paywall instead of the current simulated "API execution" step.
- Multi-tenant organizations — team accounts and shared billing on top of the current single-wallet-per-account model.
- Agent-to-agent payments — expose the 402 flow as a drop-in SDK so autonomous agents (not just humans clicking through a dashboard) can discover, pay for, and consume metered APIs programmatically.
Built With
- etherjs
- metamask
- nextjs
- postgresql
- prisma
- react
- solidity
- supabase
- tailwindcss
- tanstack
- typescript
- web3
- x402
- zustand
Log in or sign up for Devpost to join the conversation.