Inspiration

Where we live, in Pakistan, a huge number of small businesses run entirely on WhatsApp. A woman stitching embroidered cushion covers at home shares photos in chats, takes orders by voice note, and gets paid by whoever she trusts.

At the same time, shopping is moving to AI agents. People ask an assistant to find 40 cushion covers for an office and let it buy. Those agents buy from big stores with clean catalogs and checkout APIs, so the sellers we know best are about to become invisible to the next generation of shoppers. On her own, a home maker also cannot take an order of 40, bargain with an AI buyer, or ask a stranger to trust her with the money first.

So we asked: what if the smallest sellers could join the agent economy together, as one supplier, and be paid the moment they ship?

What it does

OpenStall pools makers who only use WhatsApp into one collective supplier that AI agents buy from through an MCP storefront. Three steps: list, split, and pay on proof.

  1. A stall from a chat. A maker sends a photo and a voice note in Urdu. The voice note becomes text, her photo and words become a draft listing, and OpenStall asks her, in her language, one short question at a time for what is missing: her price, how many a week, delivery days, her city, then her limits (the lowest price she would take, the fewest days she needs). Her "ہاں" (yes) publishes it. A real WhatsApp chat on our hosted demo: a maker sends Start and gets OpenStall's welcome in Urdu, delivered and read.
  2. A buyer's AI agent asks for 40 cushion covers at most $30 each, through the MCP storefront (search, product and trust cards, request_quote).
  3. Seller agents bid within each maker's limits. Each maker's agent proposes a price and a sentence to the buyer's agent. Code checks every price against her floor and the buyer's maximum, and a refused price goes back to her agent with the reason (up to 3 rounds), so no buyer's words can talk a price below her floor.
  4. Plain code splits the order across makers: 12 from Amina, 11 from Priya, 10 from Lucía and 7 from Grace, $815.00, explained in two sentences whose every number code checks against the plan.
  5. A person approves one PayPal checkout that only reserves the money: one PayPal order with intent AUTHORIZE. No agent tool can approve, capture, refund or pay out.
  6. Each maker is told on her phone, in her language (Urdu, Hindi, Spanish or English), with the numbers from the order itself.
  7. Pay on proof. A maker photographs her courier receipt. The model reads the courier and the tracking number, she confirms, and only then is her share captured from the one authorization and paid out on her rail. Her tracking goes on the PayPal order, so the buyer sees it at PayPal.
  8. The order heals itself. A maker who cannot deliver says so. On her yes her share is released, never charged, and the other makers' agents are asked for her units as a top up order.
  9. Signed trust passports. Every delivery updates a maker's record (orders delivered, how many arrived on time, disputes), signed with Ed25519, which any agent can verify. Change one number and the signature fails, shown live in the browser. (Its photo originality score is seeded demo data for now: no image check runs yet.)
  10. Demand Radar. Searches that found nothing are grouped and sent back as tips in her language: "23 agents searched for ceramic mugs this week. Nobody sells them." (seeded demo searches, marked so).

How we built it

PayPal: pay on proof on the payouts path.

  • Orders v2, intent AUTHORIZE: one order for the whole collective order, each maker's share an item. Approving only reserves the money.
  • Payments v2: a partial capture of each maker's share when she proves she shipped (final_capture on the last), and a void of whatever is left when a share is released.
  • Payouts: each maker paid on her rail. Venmo for a US maker (simulated in the sandbox, which refuses Venmo payouts). A maker in Pakistan, where Payouts does not reach, is paid to her bank through Hyperwallet (simulated and labelled so: no Hyperwallet account is connected).
  • Order tracking: her courier and tracking number on her capture, with PayPal's carrier codes (OTHER with a name for Pakistani couriers).
  • Webhooks: every event checked with PayPal's webhook signature verification and applied exactly once.
  • Disputes: a buyer's "never arrived" dispute answered with the maker's proof of shipping (built and tested; not yet run on the sandbox, where a dispute needs the sandbox buyer to open one).
  • PayPal's JS SDK buttons on each maker's stall page, and Venmo at the approval for a buyer in the US (simulated in test mode; PayPal offers Venmo only to a US business account, which our sandbox app is not).
  • PayPal's own MCP server (@paypal/mcp): an ops agent reads each order, its disputes and its tracking back from PayPal and checks them against OpenStall's records, offered only the tools that read. On the sandbox it listed 28 tools, and a real order's status, amount and disputes agreed.
  • Every write PayPal can deduplicate carries an idempotency key from our own ids, and none is resent blindly. A lost answer is read back from PayPal, and tracking, which PayPal does not deduplicate, is checked against the order's trackers before it is sent.

Proven on PayPal's real sandbox: one authorization, several partial captures with tracking on each, a final capture, a void, a payout, PayPal answering a resent capture with the first one, and OpenStall's own Approve flow from start to finish.

APIMatic's PayPal Context Plugin. Every Orders and Payments call goes through APIMatic's PayPal Python SDK (2.29, pinned by commit). Claude Code wrote the integration with APIMatic's PayPal Context Plugin installed, following the plugin's process: the contract sheet (paypal-plan.md) first, with every SDK signature, model, enum, error union and the retry policy looked up, not recalled; then the code, strict type checks, and tests that fake PayPal at the SDK's own transport seam. An APIMatic cross check runs with the tests and on /status: every SDK call has its row in the sheet, passes exactly the keywords its row says and exists in the installed SDK by its own signatures, and the sheet, the pin and the installed SDK are one commit.

AI.

  • Claude Sonnet 5.5 (Anthropic): the seller agents that negotiate within each maker's limits; the buyer's AI agent that chooses the MCP storefront's tools itself; the listing reader (vision: her photos and words into a listing); the courier receipt reader (vision); the plan explained in words; and the PayPal ops agent. Code checks every number they produce.
  • ElevenLabs Scribe v2: a maker's voice notes into text, word for word in her language, with her known language as a hint (spoken Urdu and Hindi sound alike).
  • ElevenLabs Eleven v4 Turbo: answers to a voice note, spoken back in her language.
  • OpenAI Whisper: an optional second speech to text provider.

Run for real on November 9: the five makers' agents made five valid offers in one round, each with her own sentence; the split's explanation passed the number check; the buyer's AI agent chose search, quote, draft order and checkout by itself in 12 seconds; the listing reader took $18.00 and 4 a week only from Amina's own Urdu words; and the ops agent answered from eight PayPal calls, all of them reads.

Where code decides, not the model: every price against her limits, the split (cheapest valid offers first, each maker up to what she can make by the deadline), every number in a sentence the model writes, every message to a maker (templates in her language), and every movement of money. Test mode runs fixed stand ins for every model, labelled as such.

AG Grid. Seven AG Grid tables (Community, one shared theme in light and dark): on /demo, every seller agent's proposal with the code check's verdict, live, and the allocator's plan; on /dashboard, orders (top ups marked), each maker's payout and rail, every parcel's tracking (on PayPal, delivered, on time), the trust passports with each signature checked, and Demand Radar's groups of searches that found nothing, all following the live event feed.

Render. The hosted demo runs on Render from the repository's blueprint: the web app, the API and Postgres, on PayPal's sandbox, with Claude, ElevenLabs and WhatsApp (through Whapi) for real.

The rest. FastAPI, SQLAlchemy and Postgres; Next.js, React, TypeScript and Tailwind; the MCP Python SDK; Playwright, Vitest and pytest.

Safety. No MCP tool moves money: a test calls every tool with a payment gateway that fails if anything reaches it. Try to break it on /demo runs ten real attacks through the code they target (a price talked down to $1.00, a capture tool through MCP, a smaller total from the browser, a forged PayPal webhook, an unapproved reservation, payment before proof, one courier receipt used to be paid twice, a flood of MCP calls, a tampered trust card, and a refund through PayPal's MCP server); each is refused and recorded. Rate limits for each client and for everyone together cap what real AI costs, and a secret scan checks every file and the git history.

Challenges we ran into

  • One checkout, many makers. PayPal refuses intent AUTHORIZE with several purchase units, so an order with several payees could not reserve the money. We moved to the payouts path: one order with one purchase unit, a partial capture for each maker on its one authorization, then Payouts on her rail, and proved every step on the sandbox.
  • Making AI negotiation safe. Models write persuasive offers and are bad at respecting numbers. The model writes the words; code checks every price, and a refused one goes back with the reason.
  • Messy real world input. Voice notes mix Urdu and English, and spoken Urdu is often heard as Hindi. We pass her known language as a hint, keep the transcript word for word, and ask a short question instead of guessing.
  • Money that must never move twice. Every PayPal write is claimed in our database before it is sent, keyed by what it is for, with PayPal's idempotency keys from our own ids. A lost answer is read back, never resent.
  • A photo is not proof. AI can make a convincing courier receipt, and our own demo receipt is one. Today the model only reads the courier and tracking number off the photo, the maker confirms them, and one tracking number can pay only one share. The buyer stays safe: the tracking is on the PayPal order, and in a "not received" dispute PayPal checks it, refunds the buyer if it never moved, and the lost dispute lowers the maker's signed trust score. But OpenStall would already have paid her, so the photo cannot stay the proof (see What's next).

Accomplishments that we're proud of

  • Pay on proof for each maker inside one PayPal hold, proven on PayPal's real sandbox.
  • An order that heals itself when a maker drops out, without charging the buyer for her share.
  • Signed trust passports checked live in the browser with Web Crypto.
  • A hosted demo where a real WhatsApp message is answered in Urdu.
  • About 1,690 Python tests, 335 component tests and 119 browser tests, including the whole story, all thirteen steps, played twice in a row, and an accessibility check of every page in light and dark mode.

What we learned

  • The hard part of agentic commerce is trust and control, not the model: limits that code enforces, a person's one approval, and money that moves only on proof.
  • PayPal's authorize then capture flow is a natural fit for collective orders: the buyer pays once, and each maker is paid when she ships.
  • Designing for sellers who will never install an app kept everything inside the chat they already use.

What's next for OpenStall Collective

  • The courier's scan releases the money, not the photo. OpenStall books each parcel through the courier's booking API, so the tracking number comes from the courier, and her share is captured on the courier's own pickup scan. Where she books it herself, her number is checked with the courier's tracking (it exists, was booked after the order, goes from her city to the buyer's, and has been scanned) before anything is captured.
  • Paid on shipping is earned. A maker with no record is paid on delivery, or part at pickup and the rest on delivery. A signed record of delivered orders without lost disputes earns pay on shipping, and payouts go only to verified PayPal or bank accounts.
  • Real pilots with makers in Lahore, more languages reviewed by native speakers, Hyperwallet connected for Pakistan, and buyer agents commissioning products that do not exist yet, with PayPal holding the money until the work ships.

Try it

Built With

Share this project:

Updates

Submission history