Inspiration
Small sellers, like a marble craftsman in Agra selling to a buyer in Ohio, agree everything in chat: the size, the colour, "each piece is handmade, so the pattern varies", the price and the delivery date. Then they send a PayPal invoice that says "6 coasters". When a dispute comes, the agreed details aren't anywhere PayPal can see, and the seller has to dig through hundreds of messages and guess what PayPal wants. Most of these disputes start before the sale, with terms that were never written down.
What it does
Before the sale: prevent the dispute
- The seller pastes the chat, uploads screenshots, or imports a WhatsApp export, in any language. The AI extracts items, specs, quantities, prices, ship-to, the delivery date and what the buyer accepted.
- A dispute-risk check flags vague specs, variation the buyer never accepted, unrealistic delivery dates and missing prices, and drafts a clarifying message for the buyer.
- The seller edits and confirms. Then the agreed terms are written into the PayPal invoice itself, in each item's description and in the terms field. When the buyer pays, PayPal holds its own record of what they agreed to.
After the sale: run the order
- A verified PayPal webhook marks the order paid.
- An AI assistant built on the official PayPal MCP server answers questions and adds tracking. Every write waits for the seller's Confirm, and refunds, cancellations and accepting claims are blocked.
When a dispute arrives: answer it with evidence
- The dispute is matched to its order. ProofPay builds an evidence pack in code from the order's records: paid terms, payment, tracking, and days since payment compared with the seller's own delivery time to that country.
- The AI analyses the claim with a playbook per PayPal reason code, cites a record for each point, rates the case and drafts the response.
- Code checks the AI: invented citations are removed, and a "not received" claim with no tracking can never be rated strong. ProofPay reads which evidence types PayPal is requesting and sends the seller's response and proof document as the right type. It never accepts or refunds on its own.
How we built it
- Java 21 and Spring Boot 4, with Spring Data JPA and server-rendered Thymeleaf pages
- OpenAI (gpt-5.5) with strict, forced function calling, so every AI answer is validated JSON. Screenshots are read as images
- PayPal REST APIs: OAuth, Invoicing v2, webhook signature verification and Disputes v1
- PayPal MCP server (
@paypal/mcp), run over stdio through the MCP Java SDK, with a tool allowlist and a human Confirm gate - PostgreSQL on Neon, Docker on Render, and JUnit tests running in mock mode
The core design rule: the AI reads and writes, code checks the facts, and the seller decides. Prices must appear in the chat. Delivery risk is computed by code from each seller's delivery windows. Dispute evidence is built from records, never by the AI.
Challenges we ran into
- Dispute states. A new dispute starts as an inquiry, where PayPal doesn't accept evidence. Sending it returned
ACTION_NOT_ALLOWED_IN_CURRENT_DISPUTE_STATE. ProofPay now enables Send only when PayPal offers theprovide_evidenceaction. - Evidence types. PayPal refused a tracking number alone with
EVIDENCE_TYPE_IS_NOT_ALLOWED, even though it was a listed type. We found that each dispute carries its own list of requested evidence. ProofPay now reads that list, attaches a document, and tries the next requested type if one is refused. - Sandbox realities. An India-based seller can't invoice an Indian buyer in INR (
INR_FOREIGN_CURRENCY_BLOCKED), and the sandbox has no real courier, so the seller sets the courier status. - MCP and OpenAI. The MCP tool schemas don't fit OpenAI's strict mode, so the assistant uses non-strict tools behind an allowlist.
Accomplishments that we're proud of
- The full path runs on real PayPal sandbox data: chat → terms on the invoice → webhook payment → tracking via MCP → dispute matched → evidence accepted by PayPal.
- Every AI decision that matters is checked by code, and every action that changes PayPal waits for the seller.
What we learned
PayPal's dispute process is driven by state and by what PayPal requests on each dispute, not by a fixed table. An agent has to read what the platform is asking for at that moment.
What's next
- Replying to buyers at the inquiry stage, which often ends a dispute early
- A buyer confirmation link before payment
- Changing terms on a sent invoice
- Direct WhatsApp integration
- Talking to more sellers to tune the risk checks
Built With
- docker
- java
- mcp
- neon
- openai
- paypal
- paypal-mcp
- postgresql
- render
- spring-boot