-
-
"Which case should I deal with first?" Chris Park's, due in 2 days.
-
Win the disputes you should win. Settle the rest.
-
Sam's case: fight. USPS delivered to the address on the PayPal payment, so Seller Protection covers it.
-
Approved, and Sam closed the case: $86 kept, with no PayPal fee.
-
This order would ship to an address PayPal doesn't know, which voids Seller Protection, so Truce drafts a kind note first.
-
The AI: NVIDIA Nemotron on Nebius Token Factory, routed by difficulty.
-
The inbox keeps score: money at risk, what's due this week, and what's kept.
-
"What would happen if I fought this one instead?" Likely a loss, plus PayPal's $15 fee.
-
Shop health: what's kept, fees avoided, and the claims ratio against PayPal's 1.5% line.
-
On PayPal's sandbox: a real dispute, answered through PayPal's Disputes API.
-
The bell: every buyer's answer, and PayPal ruling in the shop's favor.
-
The reply to Sam, checked sentence by sentence against the evidence.
-
Priya's case: settle. A $10 offer costs less than a claim.
Inspiration
For a small online shop, one PayPal dispute can cost more than the order. Lose a claim and PayPal keeps a $15 fee on top of the refund. Once claims pass 1.5% of sales, every claim costs $30, even the ones you win. The seller usually has ten days to answer, and Seller Protection only helps if the order went to the address on the PayPal payment, with the right proof. Small sellers rarely know these rules, so they refund cases they would have won and fight cases they were always going to lose. I wanted an agent that knows PayPal's rules, does the reading, the arithmetic and the writing, and leaves the decision with the seller.
What it does
Truce handles a shop's PayPal disputes from start to finish:
- Syncs the disputes from PayPal, live, every night, and on every webhook.
- Reads each case. It gathers the evidence: the order and the PayPal payment, the tracking, the listing as the buyer saw it, the shop's policies, the messages, the buyer's photos and similar past cases. It checks Seller Protection rule by rule.
- Prices every move. For fight, settle and refund it works out the expected loss, the worst case, PayPal's dispute fee, and whether the move counts toward the claims ratio.
- Recommends one, with reasons. Every reason cites its evidence (E1, E2…). If it doesn't pick the cheapest move, it has to say why.
- Drafts the reply and checks it. The draft is a message, an offer, a refund note or the evidence for PayPal's reviewer. Every factual sentence is checked against the evidence before the seller sees it.
- Answers through PayPal on approval. One tap sends it through the Disputes API: a message, a partial-refund offer, a refund, or proof of fulfillment with a PDF of the order and every scan.
Around that:
- Prevention. Before an order ships, Truce compares the label with the address on the PayPal payment. A different address voids Seller Protection, so Truce drafts a kind note asking the buyer to update it in PayPal first.
- Ask Truce, each shop's home, is a chat with eight tools: "Which case should I deal with first?", "Why did we lose the mug dispute?". Told "Refund Chris and say sorry", it prepares the refund as a card the seller approves.
- Shop health shows what Truce has kept, the fees avoided, the claims ratio against PayPal's line, and the patterns behind the shop's disputes, with how to prevent them.
To try it, sign up and open the sample shop, Wick & Ember: your own copy, with about 240 orders and five open disputes that each need a different move. Or connect your own PayPal REST app, sandbox or live.
How it uses PayPal
PayPal is the core, not a checkout button. Truce talks to each seller's own PayPal REST app:
| Feature | PayPal |
|---|---|
| Connect a shop | OAuth client credentials with the seller's own app. The token's scopes say what Truce can do (disputes, Transaction Search, tracking); the secret is sealed with AES-256-GCM |
| Sync disputes | Customer Disputes v1, listing and fetching the ones that changed; each shop's CUSTOMER.DISPUTE.* webhook, accepted only after verify-webhook-signature |
| The evidence | Payments v2 captures (Seller Protection status, the order), Orders v2 (items, the address on the payment, trackers) and shipping trackers |
| The claims ratio | Transaction Search: the last 90 days of sales |
| Answer | send-message, make-offer, accept-claim, provide-evidence (multipart, with a PDF) and provide-supporting-info, each checked first against the dispute's own links and allowed_response_options |
| Prevent | The address on the PayPal payment checked against the label before shipping, and tracking added to the PayPal order |
| Demo storefront | Orders v2 with PayPal checkout buttons, taking real sandbox payments |
Fees, deadlines, the claims ratio and Seller Protection come from PayPal's published rules, as tested code.
How I built it, and the AI tools
NVIDIA Nemotron on Nebius Token Factory, routed by difficulty, through the stock openai SDK with my own tool loop:
| Step | Model | Why |
|---|---|---|
| Triage, gather (with tools), weigh the evidence | Nemotron 3.5 Lightning | Fast and cheap: about 0.5 s a call |
| Read the buyer's photos | Nemotron 3.5 Super VL, thinking on | Reads a ruler or a crack in a photo |
| Draft, and the Ask Truce chat | Nemotron 3.5 Super VL | Good writing, sees the photos, quick tool use |
| Decide fight, settle or refund | Nemotron 3 Ultra, thinking on | The hardest judgement |
| Check every sentence of the draft | Nemotron 3 Ultra | A strict reader |
| Find similar past cases | Qwen3 Embedding 8B | Embeddings, cached |
- Tavily reads the listing and the shop's policies from the shop's own website, as evidence that cites its page.
- Structured answers come back as forced tool calls with zod schemas, validated across fields: every cited evidence ID must exist, and a move other than the cheapest needs a reason.
- The models never do the arithmetic. Code computes each move's cost and hands it over; the model has to argue from it. Code also checks every amount and tracking number in a draft.
- Safe by design. Buyer text reaches the models fenced as untrusted data. Nothing a model writes reaches the buyer or PayPal without the seller's tap.
- Everything streams: each analysis step, each tool call, the draft as it's written, and the cost of every call. A whole case costs about 1.3¢.
- Stack: Next.js 16 and React 19 on Google Cloud Run, Firebase Authentication, Firestore, Cloud Scheduler for the nightly check, and Secret Manager. Over 400 tests.
Challenges I ran into
- The PayPal sandbox. Sandbox disputes are opened by hand from a buyer account and reach the API about seven minutes later, already as claims. The unauthorized reason code is spelt
UNAUTHORISED, and the sandbox-onlyadjudicatecall answeredACTION_NOT_ALLOWED_IN_CURRENT_DISPUTE_STATE. The sample shop simulates PayPal's side so anyone can see a whole case play out. - Answering the right way. Each dispute only allows certain answers at each stage, so every approval maps to exactly one call, checked against the dispute's own
linksandallowed_response_optionsfirst. - Keeping the numbers exact. A model can't be trusted with fees and deadlines, so every figure comes from code.
Accomplishments that I'm proud of
- A complete product: sign-up, onboarding with a real PayPal connection, a sample shop anyone can try, approvals that go through PayPal's API, prevention before shipping, the overnight check, chat and shop health.
- The right call on all five sample cases, each a different move: fight with tracking, settle for $10, fight with proof for PayPal, refund by the shop's own policy, and refund when there's no proof of delivery.
- About 1.3¢ a case, so Truce can charge a flat price instead of a cut of what it wins.
What I learned
PayPal's rules reward preparation: the right address and the right tracking at shipping time decide most disputes before they start. And an agent becomes trustworthy once it can't touch the numbers and can't act without approval.
What's next for Truce
One-click PayPal connect (partner onboarding), carrier tracking APIs for real scan data, email notifications, and billing at a flat price: never a cut of what the seller wins.
Built With
- cloud-firestore
- cloud-scheduler
- firebase-authentication
- google-cloud-run
- nebius-token-factory
- next.js
- nvidia-nemotron
- paypal
- paypal-checkout
- paypal-disputes-api
- paypal-orders-api
- paypal-rest-api
- qwen3-embedding
- react
- secret-manager
- tailwind-css
- tavily
- typescript
- vitest
- zod

Log in or sign up for Devpost to join the conversation.