Inspiration

PayPal's agentic commerce lets an AI shopping agent buy from a store through one contract, the Cart API v1 (PayPal's Store Sync merchant contract). Big retailers will implement it. The small sellers who would gain the most, like a handloom shop in Ahmedabad or a family coffee estate in Coorg selling to the US, never will: it means building and running a spec-conformant API, PayPal order management, webhooks and refunds.

Baazar is the Hindi word for marketplace. I'm a developer in India who had never used PayPal before this hackathon (no international card), and I wanted to see whether one person could give every small store that missing piece, for free.

There was a second question: should an AI agent be allowed to take someone's money before anything ships? We decided no.

What it does

AgentBaazar is an open-source "agent-ready in a box" for small stores:

  • Feed in, Cart API out. Upload the product feed a store already keeps for Google Shopping, PayPal or OpenAI (CSV/TSV), and the store gets PayPal's Cart API: create, update and checkout carts, authenticated with PayPal-style JWTs.
  • Errors an agent can fix by itself. Out of stock, price changed, PO box for a fragile item, region not served, missing allergy information: every problem comes back as a spec validation_issue with ranked resolution_options. Each option carries a machine-applicable patch, so the agent fixes the cart without a human reading an error.
  • Paid on ship. At checkout the PayPal payment is authorized, not captured. The buyer is charged only when the merchant ships, which captures the authorization and posts the tracking number to PayPal. Cancelling voids it and puts the stock back.
  • Money that adds up, every time. Coupons and store offers, per-state sales tax, shipping by weight, partial refunds. Every PayPal call is idempotent, so retries never charge or refund twice.
  • PayPal stays the source of truth. Signed webhooks (approvals, captures, refunds, voids, disputes) are verified and reconciled, including events that arrive before our own write.

  • A shopping agent that uses it. At /shop you tell a Gemini-powered agent what you want and your budget. It searches the stores, fixes problems using each store's own options, asks for a discount, and asks you to approve the payment in PayPal; then it places the order. Ask it for a better deal and it asks the store again; the store answers with its own rules (its discounts, one offer per cart, the free-shipping threshold), so no model can haggle past the merchant's policy. Your spending rules are enforced in code, not in the prompt: a higher price, a back-order or removing the last item waits for your yes, and nothing is ever paid above your budget. It also shows real listings from other online shops (via Channel3) for comparison, which it cannot buy because those shops have no agent checkout.

  • A console for the merchant. At /console, an AG Studio dashboard shows agent sales live, a funnel of agent carts from "opened" to "captured on ship", and a Ship button that captures the PayPal payment. An AI analyst builds charts and answers questions about the numbers, and ships, cancels or refunds from a sentence: it only prepares the action, and the merchant confirms it with a button right in the chat.

  • Any AI assistant can shop it too. Every store serves an MCP server (/api/stores/patel-textiles/mcp), so Claude Desktop, Cursor or any MCP client can search, build a cart and check out with no agent platform in between. The assistant still cannot spend on its own: checkout only works after the buyer approves on PayPal's page, and the charge waits for the shipment.

Live demo: https://agentbaazar.onrender.com, with three demo stores on the PayPal sandbox.

How we built it

  • Next.js 16 + TypeScript (strict), one app, deployed on Render's free tier, with Neon Postgres (Drizzle ORM) next to it in the same region.
  • PayPal Server SDK for Orders v2 (authorize intent, PATCH as the cart changes) and Payments v2 (capture on ship, void, partial refunds, package tracking), with PayPal-Request-Id on every money-moving call and retries on 429/5xx.
  • Webhooks verified locally (CRC32 of the raw body + SHA256withRSA against PayPal's certificate, with the certificate URL pinned to PayPal hosts).
  • The Cart API spec is modeled in zod, so the server can never emit a non-conformant cart.
  • The buyer agent is an AI SDK 7 tool loop. PayPal approval is a client-side tool: the chat shows "Approve with PayPal" and hands the result back to the agent once the store confirms the approval with PayPal. Spending rules are AI SDK tool approvals in code.
  • The console is AG Studio 3 with a custom widget (AG Charts), our theme, live data over server-sent events, and a custom agent on Studio's agent framework whose tools build complete widgets in one call. Money actions use Studio's tool display: the agent's tool prepares a capture, void or refund, and a panel under its step in the chat holds the confirm button.
  • The MCP server uses mcp-handler (stateless Streamable HTTP) and calls the same cart services the Cart API routes do.
  • Every model is free. All calls go through a pool of Gemini and Gemma models, because each has its own free quota.
  • 124 tests, including integration tests against a real Postgres branch with an in-memory PayPal that can decline, return the wrong amount, lose its response mid-charge, or let a cart be edited while it is being paid for. pnpm smoke runs the whole flow against the live deployment and the real PayPal sandbox.
  • Total cost: ₹0. Everything runs on free tiers with no credit card.
  • Built with Claude Code. An independent AI reviewer graded each iteration against the Cart API spec and PayPal's integration checklist, from 6.6/10 to 9.0/10.

Challenges we ran into

  • Rounding money. Floating-point tax was off by a cent: 7.25% of \$30.00 is \$2.175, which should round to \$2.18, not \$2.17. All money is now integer cents, and tax uses parts-per-million with half-up rounding, $$\text{tax} = \left\lfloor \frac{c \cdot r_{\text{ppm}} + 500\,000}{10^{6}} \right\rfloor,$$ checked against exact BigInt arithmetic for every amount up to \$1,000.
  • Paying for a cart that is changing. An agent can edit a cart while PayPal is authorizing it. The checkout now claims the cart, cart updates lock it while they touch the PayPal order, and if PayPal ever charges a different amount the payment is voided.
  • "Did PayPal charge or not?" A timeout after PayPal charges is the scariest case. Checkouts hold a lease. A retry first asks PayPal what already happened, then charges with the same idempotency key, so it can never charge twice.
  • Webhooks racing our own writes. A refund's webhook can land before our database write. Refunds are keyed by PayPal's id, and a retried refund asks PayPal again with its original request id.
  • A bug only a real database could find. Our integration tests caught that a declined payment never returned its reserved stock, because of a foreign-key ordering mistake. Unit tests had passed.
  • Free AI quotas are tiny. Gemini 3.8 Flash allows 20 requests a day on the free tier, 3.6 Flash 5 a minute, Gemma 16,000 tokens a minute. AG Studio's built-in agent team sends up to 64 kB of tool schema per call and about ten calls per request, so it simply could not run for free. We built a lean custom agent on Studio's framework instead (two small calls per request), and a model pool that rotates across free models, rests each one for exactly the time the provider says, and waits for the soonest when all are busy.
  • Confirmations inside the chat. AG Studio's chat cannot pause a tool for the user's approval yet. We split each money action in two: the agent's tool only prepares it, and a custom panel under that step in the chat holds the button. The refund's request id is fixed when it is prepared, so a double click, or a click after a reload, refunds once.
  • Agents that skip the question. Asked for a better deal, our agent went straight back to the payment card without answering. Stores now send their offer rules with every answer, and the chat shows them, so the buyer gets an honest answer whatever the model writes.
  • Agents that are too helpful. Our agent once "solved" an out-of-stock blue M by buying a blue S, changing the buyer's size. It now opens the cart with exactly what was asked and lets the store propose the alternative.
  • No international card. Everything was built and tested on US sandbox accounts, created from an Indian PayPal account.

Accomplishments that we're proud of

  • The full flow works on the live deployment against the real PayPal sandbox: out-of-stock fix → coupon → buyer approval → authorization → capture on ship with tracking → partial refund. All four real webhooks arrive and verify.
  • Buyer protection built into the protocol: an agent cannot take money for something that never ships.
  • It is conformant with the Cart API spec (status codes, issue codes, business_context on 422s), and it states openly where it deliberately differs (authorize instead of capture at checkout, configurable per store).

What we learned

  • How PayPal's money actually moves: orders vs authorizations vs captures, why PayPal-Request-Id matters, and why the webhook, not the API response, is the final word.
  • That agents need errors written for machines: a structured fix beats a friendly message.
  • That idempotency and concurrency are where payment systems break, and that a fake PayPal which misbehaves on purpose is the best way to find out.

What's next for AgentBaazar

  • Disputes in the console: answer a PayPal dispute from a sentence, with the order's tracking attached.
  • Sign-in for MCP clients (OAuth), so a buyer's assistant can keep their address and order history.
  • A Cart API conformance kit (pnpm conformance <url>) that any merchant implementing PayPal's Cart API can run against their own server.

Built With

Share this project:

Updates

Submission history