AgentMart is an AI procurement copilot for small cafés. It watches stock, compares suppliers, restocks before you run out, and pays with PayPal — one agent, one catalog, one checkout.

What it does

A Blue Bottle Coffee café in San Francisco restocks by talking to an AI agent, driven by a real LLM (Muse Spark Open via Fireworks) over 26 tools. The agent checks inventory (stock on hand, days left at current usage, LOW/OUT alerts), sizes a smart restock from burn rate × (supplier lead time + 7 days of cover) inside a budget, creates a real PayPal Checkout order, and reports the order status after capture. When a product is out of stock, it substitutes the closest same-category in-stock item, explains the swap and the price difference, and can remove it on request.

The agent watches supplier prices: it flags prices that crept up more than 5% in 3 months and prices that dropped more than 5% — a falling price is a buying opportunity — and names the cheaper alternate supplier per line. When prices drop, the agent buys the deals itself within budget: in the demo it buys Bright Cold Brew ×2 + Craft Instant Coffee ×2 for $18.58 and leaves the order CREATED for the buyer to approve. The agent never approves a payment on its own.

The weekly restock can become a real PayPal subscription: the agent sizes the week's box, creates the billing plan and subscription, the merchant approves once, and PayPal bills the box every week. A 14-day forecast shows what runs out and when to order. On the money side, the agent watches overdue invoices and payables and reminds the payer through PayPal (Invoicing remind API, only SENT invoices).

And the agent buys together: several cafés pool one order to unlock a wholesale tier — 5% off at 10+ pooled units, 10% off at 25+ — one PayPal checkout for the pooled quantity, and after capture each café owes only its own share. The demo group "Bay Area Specialty Cafés" pools matcha to 25 units (Tier 2, $36.45 vs $40.50, saves $101.25) and oat milk to 20 units (Tier 1, $5.69 vs $5.99, saves $6.00).

Live evidence (all real PayPal sandbox transactions, one chain)

  • Order 9TU57566KL8726511 — COMPLETED $58.47 (matcha ×1 $40.50 Kyoto Tea Imports + oat-milk ×3 $5.99 Green Valley Farms), capture 6MG60735TC647453D, delivery 2026-11-13
  • Subscription I-RSL132X8L9GB — ACTIVE $58.47/week, next billing 2026-11-16
  • Invoice INV2-T8M3-HFBH-QYMM-FKJT — SENT $58.47, due 2026-12-09
  • Price-drop order 8R690026FK521581R — CREATED $18.58 (left for the buyer to approve)
  • Weekly box saves $1.20 per order vs catalog prices — $62.40 a year for one café

Merchant dashboard

Inventory, supplier prices, orders, payables, forecast, waste, restock plans, subscriptions, group buying, invoices and webhook events — all in AG Grid Community, with low-stock and overstock alerts, creep/drop alerts and a best-buy column, and a running total of what the agent saved.

How we built it

Node.js + Express server, vanilla JS frontend, SQLite persistence. PayPal integration: OAuth client-credentials + Orders API v2 (server-side create/capture), Invoicing API v2, Subscriptions API (Catalog Products → Billing Plans → Subscriptions), and Notifications/Webhooks API — the server self-registers its webhook on boot, verifies every event signature, and routes events (subscription sync, invoice → PAID, order auto-capture on approval). The agent calls Muse Spark Open with tool definitions; a deterministic intent engine over the same tools is the fallback. smart_restock is deliberately one server-side tool call, because open-weight models are weak over long tool loops. Hosted on Render (free tier); GET /health for the health check.

Challenges we ran into

  • Making the agent's actions and the manual UI share exactly one source of truth (cart + orders) so a conversation and a click never diverge — now persisted in SQLite.
  • Open-weight models are weak over long tool loops (5 rounds of search → add never reached checkout in the first live tests). Fix: the sizing math moved into one server-side tool call, so the LLM decides once and the server executes.
  • Fractional quantities: simulated daily usage made stock fractional, and the first smart-restock plan produced a 3.3-unit quantity that PayPal rejected (400). Fix: restock quantities are rounded up to whole units.
  • PayPal Invoicing rejects some payment_term values (NET_7 is invalid) — we use NET_30. Sending an invoice with an explicit invoicer email fails with 422 unless that email is the PayPal account that owns the app — fix: send no invoicer object, PayPal defaults it to the API caller.

Built With

Share this project:

Updates

Submission history