Inspiration

I see this problem in my own university. People hand fake payment receipts to food vendors and small businesses and walk away, and as a business owner myself, that scares me. A screenshot is easy to fake, and most sellers have no quick way to check it. I built Guardian so anyone can verify a claimed payment against the real record instead of trusting an image. We don't use PayPal at my college, but the problem is the same everywhere, and if this helps people anywhere in the world, that's a win.

The Subscription Radar came from watching the podcast Financial Audit by Caleb Hammer. A common thread in the people who ended up in debt was that they couldn't budget, and their subscriptions piled up. Many said they didn't know how to cancel something, or didn't even know they were subscribed. So I added a tool that surfaces repeat charges before they quietly drain an account.

Every time money moves online there's a small worry attached: did they really pay me, is it safe to pay this person, what is still charging my account? Guardian is one AI agent that answers all three using real PayPal data.

What it does

PayPal Guardian has three modules:

  • Verification Shield: paste a payment claim and a PayPal order ID. The backend fetches the real order, and the AI compares it to the claim and returns Verified or Flagged with its reasoning. An order that was approved but never captured gets flagged, even if the amount matches.
  • Pre-Payment Trust Score: enter a PayPal email plus any signals you know (account age, prior transactions, both optional). The AI returns a 0 to 100 risk score, a risk level and a recommendation.
  • Subscription Radar: scans the last 90 days of PayPal transaction history, groups repeat charges by merchant, amount and currency, and labels the rhythm (monthly, weekly, yearly) with the next expected charge date. It spots subscription-like patterns from PayPal activity. It doesn't read PayPal billing agreements.

How we built it

I started with the PayPal sandbox. I connected using OAuth2 and wrote a seed script that creates four orders in different states: unpaid, approved but not captured, and two captured. That gave me real data for every case I wanted to catch.

The Verification Shield follows one rule: the AI never judges a claim alone. The backend pulls the real order from PayPal first, then the model compares it to the claim and returns Verified or Flagged with its reasoning. Keeping the model limited to retrieved facts stops it from inventing anything.

The Trust Score takes whatever signals the user knows, like account age and prior transactions, and returns a 0 to 100 risk score with a recommendation. Both signals are optional, so it still works when you know little about the person.

For Subscription Radar, I pull 90 days of transaction history in three 30 day chunks, group repeat charges by merchant, amount and currency, and label them monthly, weekly or yearly based on the gaps between charges.

Last, I added a webhook receiver with signature verification so PayPal events reach the backend, and a React dashboard with one card per module. I built it solo, using Claude as a pair programmer for debugging and iteration.

Challenges we ran into

  • Transaction Search only accepts a 31 day window, so the 90 day scan is split into three chunked requests.
  • Sandbox transaction history can lag by a few hours, so Subscription Radar can look empty right after seeding. Transaction Search also has to be enabled on the app before it returns anything.
  • Telling a real subscription from two similar payments needed more than matching amounts, so Radar also checks the gap between charges to label them monthly, weekly or yearly.
  • The default Groq model wasn't available on my key, so the model is now configurable with GROQ_MODEL.
  • FastAPI 500 errors carry no CORS headers, so the browser only showed "Failed to fetch". I wrapped the PayPal and AI calls so failures return clean 502 errors with readable messages.
  • Sandbox orders can't be captured until a buyer approves them, so I wrote a seed script that creates orders in different states and walks through approval and capture.
  • Webhooks needed a public URL, so I tunnelled with ngrok. A missing path on the webhook URL meant PayPal's events hit / and returned 404 until I fixed it.
  • Port clashes with other local projects, a PayPal developer site that blocked my normal browser session, and Vite build errors from a malformed font link all cost debugging time.
  • Browser autofill turned the dark input fields white, which needed a CSS fix.

Accomplishments that we're proud of

  • The AI never judges a claim in isolation. Every verdict is grounded in the real PayPal order.
  • It catches the tricky case where a payment was approved but never captured.
  • It correctly flags unpaid orders, verifies completed ones and scores a brand new account as high risk, all against live PayPal sandbox data.
  • Webhook events are verified using PayPal's signature verification API.
  • Anyone can run the full demo from the README in a few minutes using seeded sandbox data.
  • Fully open source under the MIT license, with a clean, responsive UI.
  • Built solo with the aid of Claude, from backend to UI to docs.

What we learned

Giving the AI retrieved facts instead of free text makes its output far more trustworthy. I also learned how much payment logic depends on order state (created, approved, captured), not just amounts, and how PayPal sandbox quirks like history lag and window limits shape the design.

What's next for PayPal Guardian

  • Persistent storage instead of in-memory results.
  • Reading real PayPal billing agreements in Subscription Radar for exact subscription details.
  • A browser extension that checks a payment claim while you chat with a buyer or seller.
  • Restricted CORS and production hardening before any real deployment.

Built With

  • claude
  • fastapi
  • gpt-oss-120b
  • groq
  • httpx
  • lucide
  • ngrok
  • paypal-orders-api
  • paypal-rest-api
  • paypal-transaction-search
  • paypal-webhooks
  • pydantic
  • python
  • radix-ui
  • react
  • shadcn-ui
  • tailwindcss
  • typescript
  • vite
Share this project:

Updates

Submission history