Inspiration

Small online shops lose money to fraud in quiet, boring ways: a card tester firing quick tiny orders, a customer double-clicking Pay and getting charged twice, one huge order from a stranger that turns into a chargeback. Big platforms have fraud teams for this; a one-person shop on PayPal usually doesn't. We wanted a second look that happens before the money moves, not after.

What it does

PayDawg is a payment guard dog that sits between a shop and PayPal. Every payment is sniffed before it is charged and gets one of three verdicts, with plain-language reasons:

  • Wag: looks normal, so it is charged.
  • Growl: something is off (a much bigger order than usual, a sudden burst of payments across the shop), so the money is only authorized and held. The merchant reviews it and clicks Capture or Void.
  • Bark: an exact duplicate, or one customer firing payments too fast (a card-testing pattern), so it is blocked and nothing is charged. The buyer only sees "Woof! Dawg says no.", never the rules that caught them.

Dawg keeps a Notebook for each shop and learns its normal (usual basket, busy hours, normal pace) only from payments that were really captured. A busy evening shop isn't treated like an attack, and an attacker can't quickly teach Dawg that fraud is normal. An optional AI model can add a second opinion and ask for a review, but it can never block or charge on its own: a human always makes the call on held money.

To show it working we built Leash & Larder, a demo pet shop whose checkout runs through PayDawg and the PayPal Sandbox; a merchant dashboard where Dawg reacts live; and a simulator that streams realistic (simulated) orders with the occasional fraud mixed in.

How we built it

  • Backend: Python 3.11 and FastAPI, with Pydantic validation, SQLite storage and httpx for outside calls.
  • PayPal: the REST Orders v2 API on the PayPal Sandbox. A Wag is a CAPTURE order, charged once the buyer approves. A Growl is an AUTHORIZE order: the money is authorized and held until the merchant clicks Capture or Void. A Bark is never authorized or captured, so no money moves. Orders are created with a PayPal-Request-Id so retries can't double-charge, and the OAuth token is reused across calls.
  • Screening: deterministic hard rules (duplicate window, per-customer velocity, a review ceiling for very large payments) plus a soft risk score, judged against what Dawg's Notebook has learned about the shop.
  • Optional AI: a local Llama 3.2 model through Ollama (or any JSON HTTP model) can raise a payment to review, but never block one. If the model is slow or answers nonsense, the rules decide alone.
  • Front end: the dashboard and the pet shop in plain HTML, CSS and JavaScript with no framework. Dawg is an inline SVG with his own yips, growls and barks, made with the Web Audio API.
  • Testing: 210 automated tests (pytest), including a fake PayPal and a fake Ollama, run on GitHub Actions, plus end-to-end runs on the real PayPal Sandbox.
  • AI coding assistants: Claude (Anthropic), for code, tests and review.

Challenges we ran into

  • Authorize now, capture later. Holding money for review meant getting PayPal's AUTHORIZE flow exactly right: which intent to use, where the authorization ID lives in the response, and how to capture or void it later without double-charging.
  • Double-clicks, refreshes and two tabs. Payments are full of races: a buyer refreshing the return page, a merchant clicking Capture twice, Capture and Void at the same moment. Every money step now claims the payment first, so it can only happen once.
  • Fixed thresholds didn't fit real shops. Our first rules flagged a busy shop as an attack and an evening order as suspicious. Dawg now learns each shop's normal, with limits so one big order or a quick burst can't stretch it.
  • AI that helps but can't hurt. Models time out or answer nonsense, so the AI is advisory only: it can ask for a review, never block, and the rules decide alone when it fails.
  • Testing money flows without moving money. We built a fake PayPal and a fake Ollama for automated tests, ran the real Sandbox end to end, and even cut the Wi-Fi mid-payment to check the failure page.

Accomplishments that we're proud of

  • The full PayPal Sandbox lifecycle works end to end: charged, held then captured, held then voided, and blocked, with no money moving on a block.
  • Nothing is charged twice: double-clicks, retries, page refreshes and second tabs are all safe.
  • 210 automated tests on GitHub Actions.
  • Merchants get plain-language reasons, while buyers never see them, so fraudsters can't learn the rules.
  • A demo is a real purchase in a real-looking shop, not a button press, and Dawg makes risk readable at a glance.

What we learned

  • Payments are mostly edge cases: retries, timeouts, double-clicks, and money that is held but not yet charged.
  • Authorize-then-capture is a simple, powerful way to review before charging.
  • Rules first, AI second: rules are explainable and testable, and an AI should add context, not have the final say over someone's money.
  • Learning a shop's normal beats fixed numbers, but the learning itself has to be protected from being gamed.

What's next for PayDawg

  • Learning from outcomes: merchant decisions on held payments and chargebacks feeding back into Dawg's Notebook.
  • Accounts for many merchants, each with their own console and login.
  • More payment rails (UPI is a simulated stub today), plus webhooks and refunds tested against the live Sandbox.
  • A drop-in plug-in for common shop platforms.

Built With

Share this project:

Updates

Submission history