How We Built a Bakery for Robots
When we set out to build a service that lets AI agents buy cookies for humans, we had one design principle: make it boringly simple. No microservices. No message queues. No Kubernetes. Just a Next.js app that accepts money and ships cookies.
The Stack
Here's the full ingredient list:
- Next.js 15 (App Router) — server-side API routes, static marketing pages, zero client-side JavaScript for the landing page
- x402 middleware (
@x402/next) — wraps our payment endpoint, handles the 402 flow automatically - Goody API — fulfillment partner that actually sends the cookies
- Prisma + PostgreSQL — tracks order lifecycle from payment to delivery
- Vercel — deployment, edge functions, the whole deal
The Payment Endpoint
The core of the service is a single API route: POST /api/send-cookie. It's wrapped with withX402() middleware that intercepts unpaid requests and returns a 402 with payment instructions. Once the agent pays and re-submits with a receipt, the middleware lets the request through to our handler.
Inside the handler, we validate the request body with Zod, check the idempotency key against Postgres (no double-ordering!), and kick off the fulfillment pipeline.
The Fulfillment Pipeline
Order states flow through a simple state machine:
payment_verified— the x402 middleware confirmed paymentfulfillment_started— we've called the Goody APIfulfillment_succeeded— Goody accepted the orderfulfillment_failed— something went wrong (payment isn't settled)
Every state transition is recorded in Postgres with timestamps. The GET /api/orders/:id endpoint lets agents check on their order status, with a best-effort live refresh from Goody's API.
What We Didn't Build
No user accounts. No login system. No admin dashboard. No webhook handlers. The x402 protocol eliminates the need for user accounts entirely — the payment is the authentication. And Goody handles fulfillment status through their own systems.
The result is roughly 1,200 lines of TypeScript that handle payments, validation, fulfillment, and order tracking. Sometimes the best architecture is the one with the fewest boxes on the diagram.