Writing
Try it (3 minutes)
Live demo: https://shopfront-agent.onrender.com (PayPal sandbox; no real money moves)
Sandbox test buyer: [email protected] / 6cXh>ZcZ (also shown with copy buttons under every PayPal button)
- Buy with an agent: open
/shop→ "Find me a handmade blue mug under $40 as a gift" → pay with the PayPal button in the checkout card → Payment complete, webhook verified. - Try to break it: tap Try to hack the price (13 attacks, all blocked), then open
/gauntlet: 31 attacks against a naive shop and against Shopfront, same AI model. - Be the seller:
/studio→ Continue as Juniper Clay Studio → drop a product photo → Dashboard → Report · AG Studio (desktop) → ask the Shop Manager "Are my payments reconciled with PayPal?". - Telegram seller copilot: https://t.me/juniper_clay_copilot_bot?start=judge → Simulate a buyer.
- Your own agent over MCP:
https://shopfront-agent.onrender.com/mcp(Claude: Settings → Connectors → Add custom connector).
Inspiration
AI agents are starting to shop for people, but they can only buy where there is a catalog, a checkout and a payment path built for them. The potter who sells through posts and DMs has none of those. We wanted the smallest seller to be as buyable by an agent as the biggest store, without ever giving a model the power to move money.
What it does
- Photos → a PayPal-backed store. A seller drops product photos (in the web studio or in a Telegram chat). Gemini drafts each listing, marks the fields it filled, flags text in the photo that looks like an instruction, and leaves the price as a guess until the seller confirms it. Publishing mirrors the product into PayPal's catalog.
- Buyable by any agent over MCP. One public MCP endpoint covers every seller. Agents send only product ids and quantities; the server prices the order from the database and opens a PayPal Orders v2 order, paid directly to that seller's PayPal (
payee). - The human approves in PayPal. The agent hands over a link; payment happens only after approval in PayPal (JS SDK v6). The server captures, and a signature-verified webhook confirms it, processed exactly once. If a webhook is late, a per-checkout fallback asks PayPal directly.
- Store-Sync-ready. Every store also answers PayPal's Cart API v1 merchant contract (store-bound JWTs, validation issues with PayPal's resolution codes, authorize at checkout, capture on ship), proven with PayPal's own Cart API client as a test agent.
- The seller runs the shop from chat (Telegram). Order pings; a shipping-label photo becomes tracking on the PayPal order; refunds inside the seller's policy run automatically, others wait for an Approve tap; "what sold this week?" is answered with figures labelled
[db]and[paypal]. Every money action is a single-use button running deterministic code. - A dashboard you can talk to (AG Grid + AG Studio). An AG Grid overview with an Ask bar (the AI changes the view, never the data, with Undo), and a five-page AG Studio report with our own widgets (PayPal reconciliation, Cart API funnel, live wire) and a read-only Shop Manager agent built on Studio's agent framework. Every AI change is listed in a strip tagged AI, with one-step Undo.
- Reconciled with PayPal. Every PayPal capture of the last 30 days is matched against our orders on start-up, daily and after every test suite; the dashboard says "Reconciled with PayPal ✓" or lists the mismatches.
- The Gauntlet. 31 attacks in 7 families (chat injection, injections hidden in product and shipping-label photos, schema smuggling, cross-store keys, replay, refund abuse), run against a naive shop and against Shopfront with the same model. The naive shop ends with real sandbox orders at the attacker's price (never approved); Shopfront blocks 31/31.
- A live wire. Every agent step, MCP call, PayPal request (with request and debug ids) and webhook streams to
/live.
How we built it
- Stack: Next.js (App Router) as one Render free web service, Neon Postgres with Drizzle, TypeScript end to end. Money, pricing, the checkout state machine, the refund policy and every contract live in framework-free packages with unit tests.
- PayPal: a thin typed REST client: OAuth token cached and refreshed server-side,
PayPal-Request-Idon every POST, every debug id logged. Orders v2 (create withpayee, capture, authorize, track), Payments v2 (get capture, refund, void), Webhooks (signature verification), Catalog Products, Transaction Search, Log in with PayPal, JS SDK v6, and the Cart API v1 schema from@paypal/agentic-commerce-spec. Sandbox only. - AI: one router for every model call: cache → per-IP and daily caps → primary → fallback → recorded replay,
temperature: 0, Zod-validated output. Groq does tool calling and chat; Gemini does vision. If both free tiers are down, recorded words are replayed (badged) while every PayPal call stays live. - Testing: every feature ended with acceptance tests run against the deployed app with real sandbox logins, payments, refunds and webhooks, no mocks: 24 suites with 148 checks, plus 211 unit tests. Our books are reconciled with PayPal after every suite. The threat model maps 17 threats to the tests that prove them.
AI tools and how we used them
- Groq (free tier),
openai/gpt-oss-120b: tool calling for the hosted buyer agent, the dashboard Ask bar, the Shop Manager and both sides of the Gauntlet; customer-note wording; refund-reason suggestions (advice only). - Google Gemini (free tier),
gemini-3.5-flash-lite: vision (photo → listing draft, shipping label → tracking number); large AG Studio agent turns; fallback when Groq is rate-limited. - Vercel AI SDK: every model call, through one router with caching, caps, fallback and replay; structured output with Zod.
- Model Context Protocol: our public
/mcpserver, and the MCP client inside our hosted buyer agent. - AG Studio Agent Framework: the Shop Manager agent, with read-only tools only.
- Claude Code + the PayPal AI Toolkit plugin: development. The AI coding agent wrote the code and tests under the owner's direction and rules; who did what, and what the tests caught, is in
docs/development-with-ai.md.
Challenges we ran into
- Making the webhook the source of truth without a polling loop (the free database must sleep): per-checkout fallback timers that survive restarts, monotonic state transitions, duplicate-safe processing, and a sweep for events stored during an outage.
- What PayPal reserves for approved partners: partner onboarding, platform fees and refunding another merchant's capture. We pivoted to
payeerouting, so each seller is paid directly, with refunds for those sellers as a one-tap handoff to their own PayPal, tracked by webhook. - Free-tier AI limits against AG Studio's large agent turns: routing by size, caching, and a replay fallback.
- Prompt injection through images: the vision step treats text in a photo as data; the Gauntlet exists to show the difference next to a naive shop.
- A PayPal button that sometimes didn't open on the first click in the v6
autoflow: an explicit popup with a redirect fallback, tested on 8 fresh pages.
Accomplishments we're proud of
- No model in the system can move money, and the Gauntlet shows why that matters with real sandbox orders.
- Our books reconcile with PayPal's after every test run.
- A seller can run the whole shop from a phone.
What we learned
Agentic commerce works when the model proposes and deterministic code decides the money, and when every claim is checked against PayPal itself (a GET, a verified webhook, Transaction Search) rather than against our own database.
What's next
- Store Sync onboarding, so PayPal itself routes assistants to every Shopfront store (the Cart API contract is already in place).
- Partner onboarding and refunds on behalf of routed sellers, once PayPal approves us as a partner.
- More buyer countries and currencies; disputes with seller-approved evidence.
Built With
- ag-charts
- ag-grid
- ag-studio
- drizzle
- gemini
- groq
- log-in-with-paypal
- mcp
- neon
- next.js
- paypal
- paypal-cart-api
- paypal-catalog
- paypal-js-sdk-v6
- paypal-orders-v2
- paypal-transaction-search
- paypal-webhooks
- playwright
- postgresql
- react
- render
- telegram-bot-api
- typescript
- vercel-ai-sdk
- zod
Log in or sign up for Devpost to join the conversation.