Inspiration

Across rural India, millions of people make things by hand. They are not short of skill — a Kanchipuram silk saree takes six weeks on a pit loom, and the border is worked thread by thread with a second shuttle. What they lack is a way to reach a buyer directly. A trader takes most of the money, and a buyer abroad has no way to tell real handwork from a factory copy.

Underneath both problems sits a third one that nobody designs around: every marketplace expects you to type, in English. Many of these makers can't. The tools that would help them are precisely the tools they cannot use.

So we asked a narrower question. What if she just spoke?

What it does

She speaks. A weaver records a voice note in Tamil — or Hindi, Telugu, Bengali — and Gemini turns it into a structured listing: fabric, colours, motifs, price, weeks on the loom. It writes the English title, description and craft story, and converts rupees to dollars. When something is missing it asks her, in her own language, and she answers by voice. Nothing goes live until it reads the listing back and she says yes.

The co-op vouches for it. Her weavers' cooperative — a real institution across Tamil Nadu — watches the loom footage and confirms the piece is genuinely handwoven. Only then does the gold Verified handwoven badge appear. She cannot grant it to herself, and neither can the AI: the API returns 403 to anyone but the co-op, and refuses outright when there is no loom clip to vouch for.

A buyer pays, and the money splits itself. PayPal Orders v2 handles checkout. PayPal Payouts then sends the weaver her share and the co-op its commission in one batch — $184.50 and $20.50 on a $205 saree — and her phone tells her in Tamil: உங்கள் புடவை விற்பனையானது. ₹16,236 உங்களுக்கு வருகிறது.

An AI can shop it too, but never pay. The same three tools are exposed over MCP, so an agent can search, inspect a piece and prepare a checkout. create_checkout returns paid: false and a link a human must approve.

How we built it

Next.js 16 and TypeScript on Vercel, Postgres on Neon via Prisma 7, Tailwind v4.

PayPal: Orders v2 for checkout, Payouts v1 for the split, Payments v2 for refunds, signature-verified webhooks, and the JS SDK v6 in the browser. Three decisions we'd defend: every write carries a PayPal-Request-Id derived from our own order id, and the fetch helper throws if one is missing, so a retry can never double-pay. Both the capture route and the webhook call one fulfillOrder function that claims the order with a single atomic write, so whichever arrives first does the work and the other is a no-op. And every webhook event is verified with PayPal before we act on it — the endpoint is public, so an unverified body is just a stranger's claim that someone got paid.

AI: Gemini behind one wrapper giving every call a 45-second timeout, a retry, Zod validation, an audit-log row and a typed error the UI can show. The prompt forbids inventing fabric, measurements, prices or certifications, and records conflicts between what she said and what the photos show.

Deliberately not AI: the sale notification is a fixed template per language. "₹16,236 is coming to you" is a financial statement and must not be paraphrased.

Challenges we ran into

The Pay button could not be clicked, and nothing said so. The page looked perfect. We proved it by rendering the identical button twice — in the page shell it mounted and loaded the SDK; one level down inside the data component it sat on "Loading PayPal…" forever. cacheComponents, a Next 16 scaffold default, was stopping client components in that subtree from hydrating.

A real approved payment hit a 404. We hand PayPal a return_url, and when the popup opens as a separate window PayPal redirects there instead of calling onApprove. That route didn't exist. Money was approved and never captured.

Two PayPal APIs, two spellings. Orders v2 wants amount.currency_code; Payouts v1 wants amount.currency. Reusing one helper for both made every payout fail validation.

Indian sandbox accounts can't do this. Checkout returned "this seller doesn't accept payments in your currency" until the app and all four test accounts were recreated as US.

Gemini went down mid-build. Two flash models returned 503 "experiencing high demand". A demo cannot depend on one model being free, so the AI layer now falls through a candidate list.

The AI skipped its best moment. On one run it didn't ask the length question at all. That question — the AI speaking Tamil back to her — is the heart of the demo, so it is now guaranteed in code rather than left to the model.

Every one of these was found by using the thing, not reading it.

Accomplishments that we're proud of

A real sandbox purchase, verified end to end on the deployed site: $85 captured, listing SOLD, $58.50 to the weaver and $6.50 to the co-op — both SUCCEEDED — and the Tamil notification written. Not a mock.

An MCP endpoint where an external agent prepared a genuine $180 PayPal order and got back paid: false.

And the badge that can't be self-granted. It would have been easy to let the weaver tick a box. Making a second party vouch is the difference between a claim and proof.

What we learned

Run it. Every serious bug here was invisible in the code and obvious the moment a human clicked. A silent hydration failure, a 404 that swallowed a payment, a field name that differed between two APIs from the same company.

Also: fail soft, deliberately. When the payouts failed, the order stayed PAID, the error was recorded for the co-op's retry button, and the weaver was still told her piece sold. Money being stuck shouldn't mean she hears nothing.

What's next for Thari

The demo is handloom because a demo should be one thing done completely. The product isn't. Everything after the listing — checkout, the split, payouts, refunds, the notification, the assistant, MCP — already knows nothing about sarees. The verification idea is the part that travels: the badge isn't "we checked a certificate", it's film the making, and have someone who knows the craft vouch for the footage. A potter films the wheel. A Rajasthani bangle-maker films the lac work.

A new craft needs its own attributes and extraction prompt — a schema and a prompt, not a rewrite. Beyond that: real accounts instead of demo roles, a native speaker's pass over the Hindi, Telugu and Bengali strings, and export paperwork per category, since food is not textiles.

Built With

Share this project:

Updates

Submission history