Rule-Driven Transaction Fraud Detection
Learn this problemProblem statement
Process a finite ordered batch of rule-configuration and transaction-evaluation operations. Maintain active fraud rules by unique rule ID.
Each operation is a string array in one of these forms:
["UPSERT", ruleId, "AMOUNT_AT_LEAST", value]: create or replace a rule that matches when a transaction amount is at leastvalue.["UPSERT", ruleId, "COUNTRY_IS", value]: create or replace a rule that matches when the country equalsvalue.["UPSERT", ruleId, "MERCHANT_IS", value]: create or replace a rule that matches when the merchant equalsvalue.["DELETE", ruleId]: remove that rule. Deleting an unknown ID has no effect.["EVAL", amount, country, merchant]: evaluate one transaction against the rules active at this point.
An UPSERT with an existing ID replaces the complete old rule before later operations are processed. Country and merchant comparisons are case-sensitive exact string comparisons.
A transaction is fraudulent if at least one active rule matches it. If no active rule matches, it is allowed. Return one boolean for each EVAL operation, in evaluation order: true for fraudulent and false for allowed.
Function
classifyTransactions(operations: String[][]) → boolean[]Examples
Example 1
operations = [["UPSERT","r1","AMOUNT_AT_LEAST","1000"],["UPSERT","r2","COUNTRY_IS","RU"],["EVAL","900","US","books"],["EVAL","1200","US","books"],["EVAL","20","RU","coffee"]]return = [false,true,true]The first transaction matches neither rule. The second reaches the amount threshold, and the third matches the country rule.
Example 2
operations = [["UPSERT","risk","AMOUNT_AT_LEAST","100"],["EVAL","100","US","safe"],["UPSERT","risk","MERCHANT_IS","risky"],["EVAL","100","US","safe"],["EVAL","1","US","risky"],["DELETE","risk"],["EVAL","1","US","risky"]]return = [true,false,true,false]The first evaluation matches the amount rule. Reusing ID risk replaces that rule with a merchant rule. Deleting it leaves no active rules for the final evaluation.
Example 3
operations = [["EVAL","0","US","outlet"],["UPSERT","c","COUNTRY_IS","CA"],["UPSERT","m","MERCHANT_IS","outlet"],["EVAL","0","US","outlet"],["EVAL","0","CA","shop"],["DELETE","missing"],["DELETE","m"],["EVAL","0","US","outlet"]]return = [false,true,true,false]An evaluation before any rule is allowed. The next two evaluations each match one active rule. Deleting an unknown ID changes nothing; deleting rule m makes the final transaction allowed.
Constraints
1 <= operations.length <= 200000- There is at least one
EVALoperation. - Every operation has one of the valid forms described above.
ruleId, country, and merchant are non-empty ASCII strings of length at most40.- Every amount and every
AMOUNT_AT_LEASTvalue is a base-10 integer from0through10^9. - At most
200000rules are active at once. - String comparisons are case-sensitive.
More Stripe problems
- Group Linked Merchant RecordsPHONE SCREEN · Seen Jul 2026
- Invoice / Payment ReconciliationPHONE SCREEN · Seen Jul 2026
- Incident MonitorOA · Seen Jul 2026
- Merchant Fraud Risk ScoringOA · Seen Jul 2026
- WebSocket Load Balancer — Basic Load Balancing (Part 1)OA · Seen Jul 2026
- Deployment Window SchedulerOA · Seen Jul 2026
- Directly Linked UsersOA · Seen Jun 2026
- Fraud Ring SizeOA · Seen Jun 2026