Problem · Design
Transaction Authorizer with Velocity Rules
Learn this problemProblem statement
Process chronological transaction attempts using per-user merchant-category and velocity rules.
- Each
blockedRulesrow is[userId, mcc]. - Each
transactionsrow is[userId, mcc, amount, timestamp], with positive whole-dollar amount and Unix-second timestamp.
An attempt is DECLINED when its MCC is blocked for that user or when that user's total attempted amount in the interval (timestamp - 3600, timestamp], including the current attempt, exceeds 5000. Otherwise it is APPROVED.
Every attempt contributes to later velocity checks even when it is declined. Return one result per transaction.
Function
authorizeTransactions(blockedRules: String[][], transactions: String[][]) → String[]Examples
Example 1
blockedRules = [["u1","7995"]]transactions = [["u1","5411","3000","0"],["u1","7995","100","10"],["u1","5411","2000","20"],["u1","5411","2000","3620"]]return = ["APPROVED","DECLINED","DECLINED","APPROVED"]The blacklist declines the second attempt; all first three attempts total 5100 by time 20. At time 3620, the earlier attempts are outside the open-left window.
Example 2
blockedRules = []transactions = [["a","1","4000","5"],["b","1","4000","5"],["a","1","1001","6"]]return = ["APPROVED","APPROVED","DECLINED"]Velocity totals are independent per user.
Constraints
0 <= blockedRules.length <= 2000001 <= transactions.length <= 200000- User IDs and MCCs are nonempty strings without spaces.
1 <= amount <= 10^9- Timestamps are nonnegative, fit in signed 64-bit integers, and are globally nondecreasing.