Inspiration
Every deal that starts in a DM ends in the same standoff: the buyer won't pay first and the seller won't ship first. Scammers work that standoff from both sides. Fake sellers push Friends and Family or a bank transfer, where PayPal's Purchase Protection doesn't apply. Fake buyers send a "payment received" screenshot, or ask to ship somewhere else, which can cost the seller Seller Protection. In the US, people reported $2.1 billion lost to scams that started on social media in 2025, and shopping scams were the most reported kind (FTC). In the UK, purchase scams were 71% of authorised push payment scam cases in 2025, and 66% of those cases started online (UK Finance).
PayPal's buyer and seller protections have rules, and they apply only when a deal goes through checkout, on clear terms, and the seller ships the right way. Most scam tools guess from a screenshot and don't change how the deal is paid. We wanted to keep the deal on PayPal's path, for both people, from the first message.
What it does
Settle Link turns a chat into one deal link both people confirm. Nobody has to go first.
- Starts in the chat. The Chrome extension reads the open WhatsApp Web chat when the seller clicks, makes the deal, and puts the buyer's link in the reply box. The seller presses Send; the extension never sends anything. Pasting a chat or sharing from Android works too.
- One locked card. Item, price, delivery and dates each quote the message they came from. Unclear terms become questions for both people. Both agree who pays PayPal's fee. The card is locked by its SHA-256 hash, and the PayPal order carries that hash.
- Warnings for both sides, each quoting the message and citing PayPal's own terms: Friends and Family, payment outside PayPal, fake payment proof, "PayPal is holding your money", ship somewhere else, instructions aimed at the AI. The AI only adds caution; it never approves a payment, a shipment or a dispute response.
- The buyer pays the seller's own PayPal account (Partner Referrals; Settle Link never receives money). A payment counts only after a verified webhook and a fresh read of the order match the card. The ship gate then says Ship, Hold or Review, with each rule cited.
- Meet-ups: PayPal holds the money on the buyer's account, and the buyer's scan of the seller's one-time QR code is what releases it.
- Disputes: a case file and an evidence PDF built from the same record; the seller approves the exact request before it is sent, and PayPal decides.
- Signed records: the seller can download the deal's receipt chain, signed with Ed25519, and anyone can check it on
/verifyin a browser or offline, without trusting our server.
Everything runs on the PayPal sandbox; no real money moves. Judge mode gives eight private demo deals running our real code, with PayPal replayed from recorded sandbox runs and labelled on every screen.
How we built it
Next.js 16 on Render with Postgres. All PayPal calls run on the server: Orders v2 (capture and authorize), Payments v2, JS SDK v6, Partner Referrals, verify-webhook-signature, the Disputes API, and order tracking through the APIMatic-generated PayPal TypeScript SDK.
Two AI pieces, neither able to decide. Chats are redacted first. The warning check is our own small model: a MiniLM embedding per message, run on our server with transformers.js, and one logistic-regression classifier per warning, so no chat text goes to an AI provider. The deal reader (gpt-oss-120b on Groq) can only point: at a price or date token, a message ID, a delivery option, or exact words that code checks are really in the message. A term is filled only when code and the reader agree; otherwise both people answer a question. On 115 held-out chats, both readers together filled 1 wrong price (code alone: 4) and 0 wrong deliveries (code alone: 3), at the cost of more questions.
One record. Every decision writes a receipt into a hash chain, and the card's hash rides on the PayPal order. /verify runs one shared check in two places: WebCrypto in the browser and node:crypto offline, and a test confirms they agree on good and tampered records. The seller timeline uses Bryntum Scheduler. The Chrome extension is Manifest V3 with no build step and no dependencies, using activeTab so it reads a chat only after a click. We built with Claude Code and its PayPal, Render, Playwright, code-review and security plugins.
Challenges we ran into
- Who is paying. Whoever makes a deal gets both links, so each link locks to the first device that opens it, and a meet-up hold can only be placed and released from the phone that paid. Automated security reviews pushed us there.
- Getting "paid" right. Client callbacks and captures aren't confirmation. Only a verified webhook plus a fresh read that matches the locked card counts, including for holds and their captures.
- PayPal holds. Reauthorization is allowed only from day 4 to day 29, so meet-up holds are released after PayPal's 3-day guarantee instead of silently stretched.
- Reading WhatsApp Web safely. The extension must know who said what. Reviews found three ways a buyer could pass as the seller (a typed
Seller:line, a fake[time] Seller:stamp, an unsaved contact named like the seller), and a live test showed WhatsApp had dropped the markup we relied on. Sides now come only from WhatsApp's own bubble markup and position. - Using an AI we don't trust. On Groq's free tier, the smaller model and strict schema mode failed about half the time, so we chose the larger model with caps per address, per minute and per day, and judge mode reads from recorded readings instead of calling Groq.
- An idea that didn't work. We tried to make scam memory recognise reworded scripts with a keyed SimHash of MiniLM embeddings. An honest refusal ("I don't take bank transfers, only PayPal") sits as close to the scam it refuses (cosine 0.93) as rewordings of one scam sit to each other (0.84 to 0.96), so no threshold caught rewordings without matching honest messages. We dropped it and said so in the README.
- Our own reviews found our own bugs. Reviews caught a way to drain the shared AI quota without reading anything, and a way to forge a "real" record with the public demo key. Both are fixed and tested.
Accomplishments that we're proud of
- A full meet-up on the live sandbox (hold, QR handover, capture), each step confirmed by verified webhooks.
- A dispute answered with an evidence PDF that PayPal's sandbox accepted.
- Ten "try to fool it" attacks, ten stopped, each by a named rule and a test you can run on
/demo/attacks. - 327 tests with PayPal and the model mocked, plus browser tests of the judge path,
/verifyand the extension's chat readers, run against the deployed app. - A
/proofpage that shows our misses next to a baseline: on the same 115 held-out chats, a general LLM asked "is this a scam?" caught 27 of 39 scam chats (ours: 37) and none of 6 injection chats (ours: 5), but raised fewer false alarms (4 of 69 clean chats; ours: 16). We show that as it is. - A seller can go from a real WhatsApp Web chat to a sent deal link in a few clicks.
What we learned
- PayPal's protections are strong but conditional, and most of the risk lives in the minutes before anyone pays. Small checks tied to PayPal's own records beat a single "is this a scam?" score.
- Let code decide and let the AI point. A model that only adds caution, and whose every pointer code can verify, is much easier to trust than one that decides.
- Measure against a plain baseline. It was humbling and useful: the general LLM is better at not crying wolf, ours is better at catching scams and injection, and a bare yes/no can't tell anyone what to do next.
- Embeddings blur negation, which matters in exactly the sentences scam checks care about.
- A signature shows a record is unchanged since signed, not that the events happened or that we couldn't have lied. We wrote that limit on the page itself.
What's next for Settle Link
- Test with real marketplace sellers and build a consented, redacted real-chat eval before any number on
/proofis used for a live launch. - Live launch needs PayPal's approval for live Partner Referrals, a live webhook, paid hosting and a privacy review.
- Sign real deals' records with a published key and publish chain heads as an outside anchor.
- Scam memory that survives rewording without losing negation, and more countries' protection terms.
- Login with PayPal for buyer identity, a shipping-label photo check, live updates on the deal page, and the extension on the Chrome Web Store.