Guide · AI and GenAI
Fraud Detection System Design for UPI Payments
24 min readUpdated By Saket Bhatnagar
Researched and drafted with AI, reviewed and edited by Saket Bhatnagar.
In short
- Fraud detection system design is how you build the service that decides, in a fraction of a second, whether to allow, warn, hold for review or block each payment. It combines rules, a model and human analysts.
- Rules are fixed if-then checks that catch known patterns instantly. A model is a program trained on past payments that weighs many small signals together, such as payment speed, the device and links between accounts.
- Fraud is rare, and labels, the confirmed fraud-or-genuine answers, arrive days or weeks late. So accuracy misleads, and training may use only what was known at the moment of each payment.
- Set the score cut-offs, called thresholds, from rupee costs rather than 0.5. Weigh a missed fraud against a blocked genuine user, and size the review queue to fit your analysts.
- Beginners can stop after the features section: you will know every part and why it exists. Engineers get the label-delay traps, a tested costs-to-thresholds calculation, capacity-limited review and the feedback loop that hides fraud.
What goes wrong when a payments app relies on a few fraud rules?
Scams slip under the fixed limits while genuine heavy users get blocked. On UPI (Unified Payments Interface), India's system for instant bank-to-bank payments from a phone, money reaches the receiver within seconds. A scammer can move it on before anyone notices.
Picture a common setup. A UPI payments app handles about 30 lakh (3 million) payments a day, mostly small ones for groceries, rent, tea and auto fares. A small risk team owns fraud. The setup is made up, but the problem is real.
The team starts with the naive first try: three fixed rules. Block payments over Rs 50,000 from accounts younger than a week. Block payments to a list of known bad UPI IDs, the addresses people pay to. Block any user who makes more than 10 payments in an hour.
Then one Friday evening, a retired nurse gets a call from someone claiming to be her bank. He says her KYC, the identity check her bank keeps on file, has expired. He talks her through six payments to verify her account, and she enters her own PIN each time.
In nine minutes, Rs 48,000 leaves her account for three UPI IDs created that week. None of the three rules fires. Her account is years old, the new IDs are on no list, and six payments is fewer than ten.
The rules also hurt the wrong people. A flower seller pays 14 growers in the hour before 6 am every day, and the hourly limit blocks her twice a week. Each block means an angry call to support and a seller who starts trying other apps.
So the team needs three things at once. Catch scams like the nurse's, block fewer genuine sellers, and decide fast enough that paying still feels instant. The rest of this guide builds that system.
What is fraud detection system design?
Fraud detection system design is planning the whole service that checks payments for fraud. It covers the data the service reads, the rules and model it runs, the action it takes and how it learns. A few terms carry the rest of this guide.
- Feature: one number or fact about a payment that the model reads. Example: how many payments this user made in the last 10 minutes.
- Score: the model's estimate of how likely a payment is fraud, from 0 to 1. If the model is calibrated, a score of 0.02 means about 2 in 100 such payments really are fraud.
- Label: the confirmed answer for a past payment, fraud or genuine. Labels come from analysts, user complaints and banks.
- Threshold: the score above which you take an action, such as holding a payment for a person to check.
- False positive: a genuine payment treated as fraud, like the flower seller's. False negative: a fraud that got through, like the nurse's payments.
The design has two paths. The fast path decides on each payment while the user waits. The slow path collects labels, retrains the model and watches for change.
What kinds of fraud does a UPI payments app see?
Four kinds matter most for a UPI app: scams where the real user pays, account takeover, mule accounts and offer abuse. Each leaves different traces, so each needs different features.
- Scams where the real user pays. The victim enters her own PIN, as in the opening story. These are the hardest to catch, because the phone, the PIN and the person are all genuine.
- Account takeover. Someone else gets control of the account, for example with a stolen phone or a one-time password (OTP) the user was tricked into sharing. Signs: a new device, changed settings, then quick payments.
- Mule accounts. A mule account receives stolen money and passes it on, so the trail goes cold. Signs: a young account, many unrelated payers, and money leaving soon after it arrives.
- Offer abuse. One person opens many accounts to collect sign-up cashback. Signs: many accounts on one device or one set of details.
The app is not the only line of defence. In a written reply to the Rajya Sabha on 18 March 2025, the Finance Ministry listed safeguards that NPCI (National Payments Corporation of India), which runs UPI, has in place.
They include binding the mobile number to the device, two-factor authentication, and daily transaction limits. NPCI describes the two factors as the registered phone and the UPI PIN. The same reply says NPCI gives banks a fraud monitoring solution, built on machine learning models, that raises alerts and declines transactions.
It adds that RBI, India's central bank, has launched an AI-based tool called MuleHunter to help find mule accounts. That is the picture as of that March 2025 reply, so check NPCI and RBI for later changes. An app's own checks sit on top of these.
How fast does a fraud check need to run on a UPI payment?
It must finish in a small fraction of a second, because it sits inside a payment the user is watching. This team gives the whole check 120 milliseconds (made up), where a millisecond (ms) is one thousandth of a second.
That budget is a design choice, not a standard. An open fraud detection handbook from the Machine Learning Group at ULB, a university in Brussels, notes that high volumes can demand classification in tens of milliseconds.
Here is how the team splits its 120 ms (made up). Every step must fit, or the user waits.
- Read the payment's features from a fast store: 25 ms.
- Run the rules: 5 ms.
- Run the model: 15 ms.
- Pick the action and write it to the log: 5 ms.
- Keep the remaining 70 ms spare for network delays and busy moments.
So the check cannot scan a user's last 30 days of payments while she waits. The numbers it needs are kept ready in an online feature store: a fast store, often in memory, holding the latest features for each user, device and receiver.
Where the model sits in the payment
The ULB handbook describes a card setup in layers. Blocking rules run in real time, while the scoring model runs shortly after the payment is approved. A bad score then lets the bank block the card before more fraud follows.
NPCI calls UPI a real-time payment solution, so money reaches the receiver almost at once and there is little time to act afterwards. This team therefore runs the model inline, before the payment goes to the UPI network.
Here is the fast path. Follow the payment to the UPI network, then find the loop that keeps the stored counts fresh.
The fast path for one payment
Drag to exploreThe risk service has 120 ms (made up) to answer. Notice that the heavy work, refreshing counts, happens off this path in the feature updater.
Diagram connections:
- Payments app to Risk service (Payment request)
- Risk service to Online feature store (Read features)
- Risk service to Rules engine (Check rules)
- Risk service to Fraud model (Score)
- Rules engine to Decision step
- Fraud model to Decision step
- Decision step to UPI network and banks (If allowed)
- Decision step to Payment event stream (Log the outcome)
- Payment event stream to Feature updater
- Feature updater to Online feature store (Update counts)
- Payments app: User taps Pay and enters her UPI PIN
- Risk service: Runs the whole check for one payment
- Online feature store: Latest counts per user, device, receiver
- Rules engine: Hard limits and known bad UPI IDs
- Fraud model: Gives a fraud probability
- Decision step: Allow, warn, review or block
- UPI network and banks: Run their own checks too
- Payment event stream: Every payment and its outcome
- Feature updater: Refreshes counts within seconds
The risk service is the only part the app talks to, so its failure mode is a design decision. This team keeps a small set of hard rules in the payment service itself, the backend that sends each payment to the UPI network. If the risk service times out, those rules run alone, so a risk outage does not stop every payment.
Why use both rules and a machine learning model for fraud detection?
Use both because they are good at different things. Rules give instant, certain answers for patterns you already know. A model weighs many weak signals together and catches patterns no one wrote down.
Think of forest guards protecting a tiger reserve. At the gate, they stop any jeep whose number is on a list of known poacher vehicles. That is a rule: instant, certain and narrow.
Deep inside the forest, an experienced tracker works differently. A fresh tyre mark, a cut fence wire and startled birds mean little alone. Together, they tell him poachers passed this way. That is the model.
Where the picture breaks: the tracker can reason about a trick he has never seen and explain his hunch. A model only knows patterns that appear in its labelled past payments, and a complex model needs extra tools to explain a score.
The team needs both. Rules handle legal limits, known bad UPI IDs and emergencies. When a new scam spreads on a Friday night, the team can add a rule in minutes, while a new model takes days to retrain and test.
Rules have a cost too. Each one is a hard line, so a fraudster who finds it can stay just under it. The team gives every rule an owner and reviews any rule that has caught nothing in three months.
Which features help a model detect payment fraud?
The most useful features describe behaviour over time: how fast money is moving, which device is used, and how accounts link to each other. An amount means little alone, but the sixth payment in nine minutes says a lot.
Velocity features
Velocity features count recent activity in a time window. Examples are payments in the last 10 minutes, rupees sent in the last hour and new receivers this week. The ULB handbook builds similar ones: each customer's number of transactions and average amount over 1, 7 and 30 day windows.
Here is a small velocity counter for one user. It keeps recent payments in a deque, a Python double-ended queue that is quick to add to and remove from at both ends.
from collections import deque
WINDOW_SECONDS = 600 # look back 10 minutes
class VelocityCounter:
def __init__(self):
self.events = deque() # (timestamp, amount), oldest first
def add_and_count(self, ts, amount):
self.events.append((ts, amount))
while self.events and self.events[0][0] <= ts - WINDOW_SECONDS:
self.events.popleft()
total = sum(a for _, a in self.events)
return len(self.events), totalThe while loop is the line that matters. It drops payments that are 10 minutes old or older, so the counts describe only the last 10 minutes. In production, the feature updater keeps these counts in the online store instead of in one program's memory.
To check it, feed in the six payments from the opening story, with times in seconds. You should see 6 payments and Rs 48,000. A payment one day later returns 1 payment, because the window has emptied.
c = VelocityCounter()
payments = [(0, 5000), (100, 9000), (200, 8000), (300, 10000), (420, 7000), (540, 9000)]
for ts, amount in payments:
result = c.add_and_count(ts, amount)
print(result) # (6, 48000)
print(c.add_and_count(86400, 200)) # (1, 200), one day laterDevice features
Device features describe the phone behind the payment. Examples are whether it is new for this user, how many accounts used it this week, and whether its SIM card, which carries the phone number, changed recently. A phone shared by 40 accounts deserves a second look.
Graph features
Graph features describe links between accounts. Picture each UPI ID and each device as a dot, and each payment or login as a line between two dots. That picture is called a graph.
In the opening story, the three receiving IDs were each a few days old. Each had money from over 20 unrelated payers in two days, and two of them shared one phone. A graph feature turns those links into one number.
Examples are distinct payers to this receiver in the last day, and whether it shares a device with a confirmed mule account. These heavy features are refreshed in the background every few minutes, not computed during the payment.
How do you train a fraud model when fraud is rare and labels arrive late?
Train on months of past labelled payments, split by time, and judge the model with precision and recall instead of accuracy. Use only labels that would have been known when each payment happened.
Class imbalance
Class imbalance means one class is far rarer than the other. In this app, about 1 payment in 5,000 is fraud (made up). The ULB handbook says fraud is typically well under 1% of transactions in real-world datasets.
This breaks accuracy. A model that calls every payment genuine is right 99.98% of the time and catches nothing. So the team measures two things instead. Precision is the share of flagged payments that were really fraud, and recall is the share of all fraud that got flagged.
There are three common fixes. Give fraud examples more weight in training, keep all the fraud but only a sample of genuine payments, or create synthetic fraud examples. SMOTE, published in 2002, places new rare examples on the line between a real one and a nearby rare neighbour.
Each fix pushes the scores up, so a model trained on a half-fraud sample thinks fraud is common. Elkan's 2001 paper argues that, for standard Bayesian and decision tree learning methods, rebalancing has little effect on the classifier that is learned. So it recommends training on the data as given, then deciding from the probabilities and the costs.
If you do reweight or resample, recalibrate before using the scores with costs. Recalibrating means refitting the link from score to real fraud rate on recent, unsampled payments.
Delayed labels
Labels arrive late. An analyst may confirm a held payment within an hour, but a victim may complain days later. The ULB handbook notes that fraud is often discovered only after a fraud investigation or a customer complaint.
Late labels set two traps. First, last week's payments look clean only because their complaints have not arrived yet. So the team trains only on payments at least 30 days old, when most of its labels are in (made up).
Second, features built from labels, such as a receiver's past fraud rate, must count only labels known at payment time. The ULB handbook shifts its per-terminal risk windows back by a one-week delay period for this reason. In card payments, a terminal is a shop's card machine.
Split the data by time too. Train on older weeks and test on the newest ones, never on a random mix, which lets the model learn from payments made after the ones it is tested on. The handbook's model comparison leaves a 7-day gap between each training and test window.
How do you set the fraud score threshold for blocking a payment?
Set it from costs: work out the expected cost of each action at each score, and pick the cheapest. A cut-off of 0.5 is wrong for this app, because a missed fraud costs far more than a wrongly blocked payment.
A cost matrix is a table of what each action costs when the payment is fraud and when it is genuine. The team builds this one from support costs, past losses and how many blocked users later left.
| Action | If the payment is fraud | If the payment is genuine |
|---|---|---|
| Allow | Lose about Rs 6,000 | Nothing |
| Warn the user | Stops 3 scams in 10, so Rs 4,200 lost on average | Rs 2 of annoyance |
| Hold for review | Rs 30 of analyst time, misses 1 in 10, so Rs 630 | Rs 30 of analyst time plus Rs 20 for the wait |
| Block | Nothing lost | Rs 300: a support call and a user who may leave |
The code below turns that table into a decision. Here p is the model's fraud probability for one payment, from 0 to 1. Each entry in expected_costs is one row of the table, with the fraud column weighted by p and the genuine column by 1 minus p.
FRAUD_LOSS = 6000 # average loss when a fraud goes through
BLOCK_GOOD = 300 # cost of blocking a genuine payment
REVIEW_COST = 30 # analyst time for one case
REVIEW_WAIT = 20 # cost of making a genuine user wait
def expected_costs(p):
return {
"allow": p * FRAUD_LOSS,
"warn": (1 - p) * 2 + p * FRAUD_LOSS * 0.7,
"review": REVIEW_COST + (1 - p) * REVIEW_WAIT + p * FRAUD_LOSS * 0.1,
"block": (1 - p) * BLOCK_GOOD,
}
def decide(p):
costs = expected_costs(p)
return min(costs, key=costs.get)Run decide on four scores to check it. You should see allow, warn, review and block, in that order.
print([decide(p) for p in (0.0005, 0.005, 0.02, 0.5)])
# ['allow', 'warn', 'review', 'block']Scanning every score from 0 to 1 gives four bands. Allow below about 0.11%, warn up to 1.3%, review up to 28.4%, and block above that. These cut-offs are low because the costs are lopsided.
The simplest case shows why. With only allow or block, blocking wins once the expected fraud loss, p times Rs 6,000, is bigger than the expected blocking cost, 1 minus p times Rs 300. The break-even is 300 divided by 6,300, about 4.8%.
Every number here is only as good as the scores, so the model must be calibrated. Here is the full decision for one payment. Rules come first, because a hard rule ends the check at once.
How the app picks an action
Drag to exploreBands come from the cost matrix (made up). Notice that review starts at a 1.3% fraud chance; change a cost and every band moves.
Diagram connections:
- New payment to Did a hard rule fire?
- Did a hard rule fire? to Block and tell the user (Yes)
- Did a hard rule fire? to Model gives a fraud score (No)
- Model gives a fraud score to Allow (Under 0.11%)
- Model gives a fraud score to Show a scam warning (0.11% to 1.3%)
- Model gives a fraud score to Hold for analyst review (1.3% to 28.4%)
- Model gives a fraud score to Block and tell the user (Over 28.4%)
- New payment: Features already loaded
- Did a hard rule fire?: Known bad ID or over a limit
- Model gives a fraud score: A calibrated probability
- Allow: Most payments end here
- Show a scam warning: Two seconds for a genuine user
- Hold for analyst review: An analyst calls the user
- Block and tell the user: Reason kept in the logs only
When analysts run out of time
The review band has a capacity limit. On a normal day it would hold about 6,000 payments, but the team's eight analysts can check about 1,200 (made up). So the team holds only the 1,200 with the largest expected saving: how much cheaper review is than the best action without review. The rest get that next-best action: with the table's costs, a warning below about 6.6% and a block above it.
Review saves the most near 6.6%, about Rs 190 a payment, and almost nothing near 28.4%, where a block costs about the same. In real use, a fraud's loss is closer to the payment amount than to one fixed average. So rank by expected saving, not by score alone. A 5% chance on Rs 40,000 puts Rs 2,000 at risk, while a 10% chance on Rs 500 puts Rs 50 at risk.
The ULB handbook measures this limit with precision top-k. Here k is the most alerts investigators can check in a day, and the metric is the share of the top k that were really fraud, computed daily.
How do you keep a fraud detection model working when fraudsters adapt?
Assume the model will decay, and build the slow path to notice and fix it: fresh labels, regular retraining, drift monitors and rules that change in minutes. The ULB handbook lists this as concept drift: transaction and fraud patterns change over time.
Here is how it plays out. After the model starts catching six-payment bursts, scammers switch to two payments a day over a week. Alerts fall, and the drop looks like good news until complaints arrive weeks later.
Drift means the data the model sees in real use no longer looks like its training data. The team watches for it at three levels, because labels alone arrive too slowly.
- Inputs: compare this week's feature values with the training data, such as the share of payments from new devices.
- Outputs: the mix of scores, and how many payments land in each band, every hour.
- Outcomes: the fraud share among reviewed cases, known within hours, and confirmed losses, known over weeks.
Here is the slow path. Start at live decisions and follow the two label routes, one fast and one slow, into retraining.
The slow path: labels, drift and retraining
Drag to exploreNotice the two label routes: analyst verdicts arrive in hours, complaints in weeks. Blocked payments feed neither, which is why random samples go to review.
Diagram connections:
- Live decisions to Analyst verdicts (Held and sampled)
- Live decisions to User and bank reports (Allowed payments)
- Analyst verdicts to Label table
- User and bank reports to Label table
- Live decisions to Drift monitor (Scores and features)
- Drift monitor to Scheduled retraining (Early retrain on alarm)
- Label table to Scheduled retraining
- Scheduled retraining to Shadow test
- Shadow test to Live decisions (Promote if better)
- Live decisions: Fast path output for every payment
- Analyst verdicts: Held cases plus random samples
- User and bank reports: Slow labels, days to weeks
- Label table: Fraud or genuine, with the date known
- Drift monitor: Features, score mix, band sizes
- Scheduled retraining: Trains on payments 30+ days old
- Shadow test: New model scores, old one decides
The feedback loop that hides fraud
A blocked payment rarely gets a confirmed label, because nobody learns what would have happened. If the next model trains only on labelled payments, it learns little about the cases the old model blocked.
To keep some labels there, the team sends a small random share of would-be blocks to analyst review instead, plus a random sample of allowed payments. A new model first runs in shadow mode, scoring live payments without deciding, until it beats the current one on the newest payments whose labels are in.
Keep reasons out of user messages. If the app says a payment was blocked as the fourth in ten minutes, fraudsters learn to send three. The reason goes to the logs and to analysts only.
How do you explain fraud detection system design in a system design interview?
Start from the payment and its time limit, then build outwards: the fast path, the features, the decision, and the slow path that learns. The steps below are a frame you can say out loud in about ten minutes.
Ask the questions that shape the design
Fraud types, payments per second, the latency budget, and the actions: allow, warn, review or block.
Draw the fast path
App, risk service, online feature store, rules, model and decision step. Say what happens on a timeout.
Pick features by fraud type
Velocity for sudden bursts, device features for account takeover, and graph features for mule accounts.
Explain rules plus a model
Rules for known patterns and emergencies, the model for many weak signals combined. Rules run first.
Handle rare and late labels
Split by time, measure precision and recall, and train only on payments old enough to have labels.
Set thresholds from costs
Show a cost matrix, turn it into score bands, and fit the review band to analyst capacity.
Close with the slow path
Drift monitors, a random review sample, shadow tests, retraining, and how fraudsters will react.
Questions people ask
- What is the best machine learning model for fraud detection?
- There is no single best model for every dataset. On the ULB handbook's simulated card data, XGBoost scored highest on average precision and on precision among the top 100 cards per day. Random forest came second. XGBoost is a library for gradient-boosted trees: many small decision trees whose answers are added up. Whatever you choose must fit your latency budget and give calibrated probabilities.
- Why is accuracy a bad metric for fraud detection?
- Accuracy hides fraud because fraud is so rare. If 1 payment in 5,000 is fraud, a model that never flags anything is 99.98% accurate and useless. Use precision, recall and the rupee cost of each kind of mistake instead, measured on the newest labelled data.
- How fast does real-time fraud detection need to be?
- It depends on where the check sits. The ULB handbook notes that classification in tens of milliseconds may be needed at high volumes. In its card setup, blocking rules run in real time and the model runs shortly after approval. An inline UPI check must fit the whole decision inside its budget, so features are prepared ahead in a fast store.
- What is a money mule account?
- A money mule account receives stolen money and quickly passes it on, so the trail is harder to follow. Common signs are a young account, many unrelated payers and money leaving soon after it arrives. A March 2025 government reply says RBI has launched an AI-based tool called MuleHunter to help find such accounts.
- Should you use SMOTE for fraud detection?
- You can, but test it against simpler options first. SMOTE creates synthetic fraud examples between nearby real ones, which can help some models. It also pushes the scores up, so recalibrate them on real, unsampled data before setting cost-based thresholds.
- How often should you retrain a fraud model?
- Retrain on a regular schedule, such as weekly or monthly, and earlier when a drift monitor fires. The right rhythm depends on how fast your fraud changes and how quickly labels arrive. Always test a new model on the newest fully labelled payments, and run it in shadow mode before it decides anything.
Sources and further reading
- Reproducible Machine Learning for Credit Card Fraud Detection, Practical Handbook (ULB Machine Learning Group): Machine learning for credit card fraud detection (latency, class imbalance, concept drift)
- Same handbook: Credit card fraud detection system (rule and model layers, investigators)
- Same handbook: Baseline feature transformation (1, 7 and 30 day windows, one-week delay period)
- Same handbook: Precision top-k metrics
- Same handbook: Model selection (XGBoost, random forest, logistic regression, decision tree)
- The Foundations of Cost-Sensitive Learning (Elkan, IJCAI 2001), abstract page
- SMOTE: Synthetic Minority Over-sampling Technique (Chawla et al., Journal of Artificial Intelligence Research, 2002)
- NPCI: UPI Product Booklet (real-time payments, phone and UPI PIN as the two factors)
- PIB, Ministry of Finance: Rajya Sabha reply on cyber security in the financial sector (18 March 2025)