Inspiration

AI agents are starting to buy things on their own, like a web search or a summary of a long document. Those purchases cost a cent or less, and card rails can't carry them. At PayPal's US rate of \$0.49 + 3.49% per charge, a one-cent API call costs almost fifty times its price in fees.

HTTP has had a status code for this since the 1990s, 402 Payment Required, and the x402 protocol finally gives it a payment flow. What it lacked was a way to settle on a payment network people already use. A bar tab gave us the model: run up small charges all night, then pay once.

What it does

Tab402 lets AI agents pay for APIs per call and settles the total on PayPal.

A seller pastes their OpenAPI spec, and Claude Sonnet 5.5 proposes a price for each route. The seller adjusts and confirms, and Tab402 gives them a few lines of gate config for their server. The routes then appear in a public directory where agents look for services.

An agent connects to Tab402's MCP server, finds the seller, and calls the API. The seller answers 402 Payment Required with a quote. The agent signs a voucher with its own key, retries, and gets the result. The charge goes on the agent's tab and shows up in the buyer's receipts within seconds. Routes can be priced per call or metered, so a chat is charged what it actually cost.

The buyer stays in control. A spending policy sets daily budgets, a per-call maximum, allow and block lists, and an approval threshold. Agents can hand out sub-budgets with their own capped key. Anything unusual, like a first-time seller or a sudden price spike, goes to a spend guard where Claude Haiku 4.5 approves, denies, or asks the buyer. Purchases that need a human send a push notification and an email, and the buyer approves with a passkey.

Money moves through PayPal three times:

  1. The buyer saves a PayPal wallet once with Vault v3, so later charges need no popup.
  2. Tab402 charges the whole tab with one merchant-initiated Orders v2 capture, when it reaches \$10 or after 24 hours. New buyers top up a prepaid balance first, and move to post-paid after three successful charges.
  3. PayPal Payouts pays each seller their net balance, after PayPal's fees and Tab402's 2%.

Every charge moves through three states, earned, collected and paid out, and both sides can see them. Sellers get a revenue dashboard built with AG Studio, with an AI panel that answers questions like "why did revenue change today?" from their own data.

For $n$ one-cent calls, the PayPal fees compare like this:

$$\text{per call: } n \times (\$0.49 + 3.49\% \times \$0.01) \qquad \text{one tab: } \$0.49 + 3.49\% \times (n \times \$0.01)$$

At 1,000 calls that is about \$490 in fees charged one by one, against \$0.84 as a single \$10 tab.

How we built it

Tab402 is a TypeScript monorepo (pnpm and Turborepo) with seven deployable parts:

  • api (Hono): the x402 facilitator. It issues quotes, verifies vouchers, settles charges, runs the spend guard, and receives PayPal webhooks.
  • mcp-buyer: a remote MCP server (Streamable HTTP) with seven tools, OAuth 2.1 sign-in, dynamic client registration and PKCE, so Claude Code connects with one URL.
  • web (Next.js 16): sign-in with Better Auth and passkeys, the wallet, policy, approvals, receipts, an agent playground, seller onboarding and AG Studio dashboards. It installs as a PWA for push notifications.
  • worker (pg-boss): captures, top-ups, payouts, webhook processing, Web Push, and approval emails over Gmail SMTP.
  • workflows: on Render, tab settlement and seller payouts run as Render Workflows, started every 15 minutes by a Render Cron Job.
  • demo-sellers: a sample paid API behind the Tab402 gate, with summarize and chat routes backed by Claude.
  • Postgres 18 holds a double-entry ledger in integer micro-dollars.

Sellers add one Hono middleware (tab402Gate), or call the facilitator client from any other framework. Agents use a small SDK that handles the 402 handshake and signs vouchers with a P-256 key. Everything runs from one Render Blueprint.

The test suite covers the ledger, the guard, the PayPal adapters, a full end-to-end payment flow against a real database, and browser tests in Playwright that use Chrome's virtual authenticator for passkeys.

Challenges we ran into

PayPal moves whole cents

Agents spend fractions of one. A metered chat can cost \$0.0004. We kept every amount in micro-dollars and carry the sub-cent remainder of each capture forward to the buyer's next one, so the ledger always balances to the micro-dollar.

Saving a wallet without a purchase

Charging later with no popup needs a Vault token saved up front, through the JS SDK v6 save flow, and then merchant-initiated captures against that vault id. The sandbox adds its own surprises: log in with the merchant's own business account and it sends you to card sign-up instead of saving the wallet.

Webhooks we could trust

The PayPal webhook simulator sends events whose signatures fail verification, so we test with real sandbox events. With a webhook id set, as on the hosted site, the API rejects any event that fails PayPal's verification.

Keeping an approval safe outside the app

We wanted approvals to reach the buyer by push and email, but a link in an email works for anyone who has the email, and mail scanners open every link they see. Approving still needs a passkey. The email's Decline link works without signing in, since declining can only stop money moving, and it only takes effect after a click on the page it opens.

Re-running onboarding on a live API

An early version let a second onboarding run overwrite routes that were already live, which switched a fixed-price route to metered and broke real calls. Onboarding now lists every change to a live route and asks before applying it, and it never flips a route's pricing mode.

Accomplishments that we're proud of

  • A real x402 flow, from a 402 response to a signed voucher to a PayPal capture and a seller payout, running live on Render.
  • An agent in Claude Code can find a service, pay for it and stay inside the buyer's budget, with no payment code in the agent.
  • One PayPal charge replaces hundreds of card fees, and the landing page lets you drag a slider to see the difference.
  • Passkey approvals that work from a push notification, an email, or an MCP client's approval link.
  • Seller onboarding that turns an OpenAPI spec into priced, gated routes in about a minute.

What we learned

The hard part of micropayments is settlement. Signing a voucher takes milliseconds; deciding when to charge, how to handle a declined capture, and when a seller can safely be paid takes most of the code.

We also learned how much an agent needs to be told. When a payment was refused, the first version only said guard_denied, and the agent could only tell the user that it failed. Now the error names the rule, such as "would exceed this sub-budget", and the agent can explain what to change.

MCP's OAuth support also made setup simple. A buyer adds one URL to Claude Code, signs in in the browser, and the agent has a budget.

What's next for Tab402

  • Live PayPal credentials, and PayPal's own fee schedule for each seller's country instead of the US rate.
  • Seller SDKs for Express, Fastify and Python, alongside the Hono gate.
  • Refunds and disputes that agents can open from MCP.
  • Email from a sending domain, and Gmail's in-inbox action buttons once the sender is registered.
  • Spending reports a buyer's finance team can export to their accounting system.

Built With

Share this project:

Updates

Submission history