Inspiration

This was my first time working with PayPal's APIs, and I wanted to build something that mattered more than a demo gimmick — a real control sitting at the exact point money leaves an account. Invoice fraud is one of those problems that's boring until it isn't: one urgent-sounding email with a slightly wrong bank detail, and the money's gone. I wanted a system that catches that before the payment fires, not after.

What it does

ScamShield takes an invoice — payee, amount, and the message text — and runs it through a rule engine combined with retrieval-based pattern matching against a curated corpus of known scam signatures. No LLM involved; the whole pipeline is deterministic, so every verdict is explainable and reproducible. It returns one of three calls: pay, hold, or block.

Only a pay verdict can trigger an actual payment, and even then it's routed through PayPal's sandbox environment — live payments are never possible. A block verdict automatically fires a Zapier webhook alert. Every decision lands in an AG Grid history table, with holds and blocks surfaced separately in a Bryntum review queue so a human can step in.

How we built it

We started with the rule engine — urgency language, unknown payees, over-limit amounts, name mismatches — since that gives fast, explainable wins on its own. On top of that we layered the retrieval piece: a BM25 search over a scam-pattern corpus, backed by Elastic when configured, with a local fallback so the whole thing still runs with zero external dependencies. The two signals combine into a single deterministic verdict, with the stricter signal always winning.

The PayPal integration came next: OAuth2 client-credentials flow into /v2/checkout/orders, gated hard behind the verdict — /pay returns a 403 for anything that hasn't been marked pay. We documented the API contract in OpenAPI so it could be imported straight into Postman and APIMatic, and shipped a render.yaml blueprint so the whole thing deploys in one click.

Challenges we ran into

Neither of us had touched the PayPal API before, so getting the sandbox OAuth flow right — and keeping credentials out of the repo entirely — took real care. Balancing the rule engine against the retrieval score was its own problem: too rule-heavy and it misses novel scams, too retrieval-heavy and it loses explainability. We tuned the aggregator until the stricter-verdict-wins logic gave clean, defensible results across our test set.

Accomplishments that we're proud of

100% accuracy (20/20) on our test dataset — 10 scam cases correctly held or blocked, 10 legit invoices correctly paid — fully offline and deterministic. The whole system runs with zero paid APIs and zero secrets in code.

What we learned

How to work with PayPal's sandbox API end to end, how to build a RAG-style retrieval system without reaching for an LLM, and how much design work goes into making an automated decision both safe and explainable.

What's next for ScamShield

Expanding the scam-pattern corpus, adding payee identity verification as a first-class signal instead of an optional enrichment step, and exploring a lightweight model to flag genuinely novel fraud patterns the rule engine and retrieval layer both miss.

Share this project:

Updates

Submission history