◆PRISMFraud

09 / 12Prism Systems · FinTech & Banking

Stop card fraud in 15 microseconds, and explain every decision

Real-time transaction risk scoring: exact sliding-window velocity features per card, device and IP, impossible-travel detection, per-card spend z-scores, an analyst rule language with explainable traces, an online logistic model that learns from chargebacks and analyst verdicts, a review queue, and an HTTP scoring API.

Zero dependencies~15 µs per decisionExplainable rules + modelOnline learningSynthetic ground truth
Live simulator

A live card network with fraud attacks in progress

Every dot is an authorisation in an Indian or foreign city. Launch a card-testing bot, an account takeover, a cloned card abroad or a bust-out spree and watch what gets stopped. Work the review queue, drag the thresholds, edit the rules and apply them live.

paused
card authorisations · India + cross-border
Score distribution AUC —
Precision · recall (labelled)
Decision inspector latest flagged
Review queue 0 open
Policy —
Events
Features

What's inside the engine

Real algorithms, not mock-ups. The simulator above runs the exact same code you import.

⏱

Exact sliding windows

Per-card counts and sums over 10 min, 1 h and 24 h, distinct cards per device (24 h) and per IP (1 h), tiny-authorisation bursts per IP. Pruning is O(1) amortised; there is no approximation.

✈

Impossible travel

Haversine distance from the card's last approved location divided by elapsed time. A Mumbai purchase followed by London 20 minutes later is 22,000 km/h.

σ

Spend profile

A Welford running mean and variance of log amounts per card gives a z-score, so ₹40,000 is normal for one customer and extreme for another.

⌘

Rule language

decline, review, approve and score +N rules with and or not in, arithmetic, lists and 5k / 2m suffixes. Errors come with line and column, and a linter catches unknown fields.

◉

Explainable

Every comparison records the value it saw (travel.kmh > 900 ← 22,431), and the model reports its top feature contributions in plain language.

∿

Online model

A 14-feature logistic regression with AdaGrad and L2, class-weighted for rare fraud. Chargebacks and analyst verdicts update it as they arrive.

☰

Review queue

Borderline transactions open a case. Analyst decisions label the transaction, close the case and train the model, and outcome metrics track precision, recall and money saved.

⚡

HTTP API

POST /v1/score (with ?explain), POST /v1/label, case endpoints, GET /v1/metrics and PUT /v1/rules for hot reload.

How it works

From request to result

Look up

The card's profile comes from the feature store the first time it is seen: home country, tier, known devices, spend distribution and last location.

Featurise

Windows for card, device and IP are queried before the transaction is recorded, plus z-score, travel speed, merchant category risk and channel.

Score

The model turns 14 features into a probability (score 0–1000). Rules then run against the same context, and score rules adjust it.

Decide

Decline beats review beats approve. An approve rule can override a model review but never a decline. Thresholds are configurable.

Learn

Chargebacks, confirmed-good labels and analyst verdicts arrive later and update both the outcome metrics and the model weights.

Architecture

System design

Every box is a module in src/. Data flows left to right.

learnINPUTSAuthorisationcard · device · ip · geoFeature storecard profilesFEATURESSliding windowscard · device · ipTravel + z-scorehaversine · WelfordDECISIONOnline modellogistic · AdaGradRule enginePratt parser · traceOUTCOMESDecisionapprove · review · declineReview + labelschargebacks · analysts
Use it

Ship it in your own stack

Zero dependencies. Works in Node.js 18+ and modern browsers.

example.js
import { FraudEngine } from "prism-fraud";

const fraud = new FraudEngine({
  rules: `rule "card-testing" decline when ip.cards_1h >= 4 and amount < 100
          rule "impossible-travel" decline when travel.kmh > 900 and travel.km > 500
          rule "ato" score +180 when device.new and country != card.home and amount > 5k`,
  review: 450, decline: 800,
  profiles: (cardId) => featureStore.get(cardId),   // optional history: devices, spend, last location
});

const r = fraud.score({
  id: "tx-91", t: Date.now() / 1000, card: "card-00042", amount: 64999, mcc: "electronics",
  city: "Lagos", country: "NG", lat: 6.52, lon: 3.38, device: "dev-9", ip: "203.0.113.7", channel: "cnp",
}, { explain: true });

r.decision;   // "decline"
r.score;      // 0..1000
r.by;         // "rule:impossible-travel"
r.reasons;    // [{ kind: "rule", name: "ato", delta: 180 }, { kind: "model", why: "first time this card is used on this device" }]
r.trace;      // every rule, every comparison, every value seen

fraud.label("tx-91", true);          // chargeback -> outcome metrics + online model update
fraud.openCases();                   // review queue
fraud.setRules(src);                 // hot reload
fraud.metrics();                     // { auc, precision, recall, savedAmt, lostAmt, ... }
terminal
$ npx github:krishyaa06/prism-fraud demo
$ npx github:krishyaa06/prism-fraud score examples/tx.json
$ npx github:krishyaa06/prism-fraud simulate --minutes 10
$ npx github:krishyaa06/prism-fraud train --hours 24
$ npx github:krishyaa06/prism-fraud rules examples/rules.fraud
$ npx github:krishyaa06/prism-fraud bench
$ npx github:krishyaa06/prism-fraud serve --port 8787
terminal
# use the CLI without installing
$ npx github:krishyaa06/prism-fraud --help

# or add the engine to your project
$ npm install github:krishyaa06/prism-fraud

# run the simulator locally
$ git clone https://github.com/krishyaa06/prism-fraud.git && cd prism-fraud
$ npx serve .   # then open http://localhost:3000