Skip to content

Nabil201-ctrl/fraud-pulse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

fraud-pulse

Payment risk scoring for demo transactions.

Given a txn + a bit of user context, the engine returns allow, review, or block, plus which rules fired. Python owns the rules. Node owns the HTTP edge so a JS app can call it without rewriting risk logic in JS.

I built this after reading a few fintech fraud writeups and realizing most of the first pass is still: velocity, new device, amount vs baseline, geo hops — not a 50-layer network.


Decision model

Each rule either returns nothing or a hit { rule_id, points, reason }.
Engine sums points (max 100) and maps:

Score Action
0–24 allow
25–54 review
55+ block

Rules currently in scorer/rules.py:

  • high_amount — spend vs user's average
  • velocity_burst — too many txns in the last hour
  • night_owl — big amount in the quiet UTC hours
  • new_device — first time device + non-trivial amount
  • geo_hop — multiple countries in 24h
  • risky_combo — new device + web + high amount stacked

They're independent functions. You can comment one out without the rest collapsing.


System flow

flowchart TD
    subgraph inputs
        APP[Payment app / batch file]
        FILE[transactions.json]
    end

    subgraph node [Node.js api/]
        S[server.js POST /score]
        H[score_file.js]
        B[engine_bridge.js]
        S --> B
        H --> B
    end

    subgraph py [Python scorer/]
        C[cli.py]
        E[engine.py]
        R[rules.py]
        C --> E --> R
    end

    APP --> S
    FILE --> H
    FILE --> C
    B -->|JSON on stdin| C
    E --> D{score}
    D -->|low| ALLOW[allow]
    D -->|mid| REVIEW[review]
    D -->|high| BLOCK[block]
Loading

Folder map

fraud-pulse/
  scorer/
    rules.py      # each rule is a small function
    engine.py     # sum + action mapping
    cli.py        # stdin/file → JSON decisions
  api/
    server.js
    engine_bridge.js
    score_file.js
  sample_data/transactions.json
  tests/

Getting it running

git clone https://github.com/Nabil201-ctrl/fraud-pulse.git
cd fraud-pulse

Python path (fastest to see decisions):

python3 scorer/cli.py -i sample_data/transactions.json

Node helper:

cd api
node score_file.js ../sample_data/transactions.json

HTTP:

cd api
node server.js
# port 3850

curl -s -X POST http://127.0.0.1:3850/score \
  -H 'content-type: application/json' \
  -d @../sample_data/transactions.json

Checks:

python3 -c "
import sys
from pathlib import Path
sys.path.insert(0, str(Path('scorer').resolve()))
sys.path.insert(0, str(Path('tests').resolve()))
from test_engine import test_normal_allow, test_obvious_fraud_blocks
test_normal_allow(); test_obvious_fraud_blocks()
print('ok')
"

What the sample data does

txn rough story expected
t_1001 normal coffee spend allow
t_1002 huge amount, new device, velocity, multi-country block
t_1003 elevated but not insane review

Open the JSON if you want to tweak fields and re-run — that's how I tuned the thresholds.


Design choices I stuck with

  1. Reasons are mandatory. If a rule adds points, it has to say why in plain language. Compliance people hate bare scores.
  2. Context on the payload. The engine doesn't fetch user history; the caller passes user_avg_amount, user_txn_count_1h, etc. Keeps this repo self-contained.
  3. Two languages, one contract. Node never reimplements rules.

Later ideas

  • Pull features from a real event store instead of denormalized fields
  • Slack/webhook on block
  • Time-decay on velocity windows

About

Fintech transaction fraud scoring engine — allow / review / block with explainable rules

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors