FastPrepTransaction Fraud Report Part 2 — High-Risk Rule Validation

Transaction Fraud Report Part 2 — High-Risk Rule Validation

Stripe logoStripe● EasyNEW GRADPHONE SCREEN
Learn

Problem statement

Four-part sequence: This is Part 2 of one progressive transaction-fraud interview exercise. It retains Part 1 and adds two high-risk rules.

  1. Part 1: Verify Transaction Data Integrity.
  2. Part 2: High-Risk Rule Validation (you are here).
  3. Part 3: User Behavior Matching.
  4. Part 4: Smart Fraud Error Reporting.

Validate transaction integrity, then apply amount and payment-method risk rules.

Input

Each string in transactions is one unquoted CSV row with exactly six comma-separated fields, in this order: transaction_id,user_id,amount,payment_method,country,hour. Trim surrounding whitespace from every field.

For a row whose fields are all non-empty, amount is a valid decimal integer. The inclusive interval [normalMin, normalMax] defines the normal amount range. Membership in blockedMethods is case-sensitive.

Review rules

  1. If any field is empty after trimming, mark the row SUSPICIOUS and do not parse or apply later rules.
  2. Otherwise, mark the row SUSPICIOUS when its amount is outside [normalMin, normalMax] or its payment method occurs in blockedMethods.
  3. Mark every remaining row OK.

Result

Return a two-column string table whose first row is ["transaction_id","status"]. Append one result row per transaction in input order, preserving repeated IDs and an empty ID on an invalid row.

Function

validateHighRiskTransactions(transactions: String[], normalMin: int, normalMax: int, blockedMethods: String[]) → String[][]

Examples

Example 1

transactions = ["tx1,u1,100,card,US,10","tx2,u2,99,card,US,10","tx3,u3,500,cash,US,10","tx4,u4,1500,cash,US,10","tx5,u5,,cash,US,10"]normalMin = 100normalMax = 1000blockedMethods = ["cash"]return = [["transaction_id","status"],["tx1","OK"],["tx2","SUSPICIOUS"],["tx3","SUSPICIOUS"],["tx4","SUSPICIOUS"],["tx5","SUSPICIOUS"]]

tx1 is exactly on the lower inclusive boundary. tx2 is below it. tx3 uses a blocked method. tx4 violates both risk rules. tx5 stops at the missing-field check.

Example 2

transactions = ["edge,u1,100,Card,US,0","blocked,u1,100,card,US,0"]normalMin = 100normalMax = 100blockedMethods = ["card"]return = [["transaction_id","status"],["edge","OK"],["blocked","SUSPICIOUS"]]

The amount endpoints are inclusive. Method matching is case-sensitive, so Card is allowed while card is blocked.

Constraints

  • 1 <= transactions.length <= 10000; every row contains exactly six comma-separated fields and no quoted commas.
  • 0 <= normalMin <= normalMax <= 1000000000.
  • Every non-empty amount is a decimal integer from 0 through 1000000000.
  • 0 <= blockedMethods.length <= 1000; method names are unique.
  • Identifiers, country labels, and method labels contain at most 100 characters.

More Stripe problems

See Stripe hiring insights
public String[][] validateHighRiskTransactions(String[] transactions, int normalMin, int normalMax, String[] blockedMethods) {
    // Write your code here
}
transactions["tx1,u1,100,card,US,10","tx2,u2,99,card,US,10","tx3,u3,500,cash,US,10","tx4,u4,1500,cash,US,10","tx5,u5,,cash,US,10"]
normalMin100
normalMax1000
blockedMethods["cash"]
expected[["transaction_id", "status"], ["tx1", "OK"], ["tx2", "SUSPICIOUS"], ["tx3", "SUSPICIOUS"], ["tx4", "SUSPICIOUS"], ["tx5", "SUSPICIOUS"]]
Checking account…