This is a classic "Stateful Stream Processing" problem at Stripe. It evaluates how a candidate handles time-series data, designs efficient data structures for state queries, and translates business rules into code logic.
Problem Description
Part 1: Authorization Requests
Stripe processes payment requests on behalf of merchants. Initially, the policy is permissive: all requests are APPROVED. You need to process a stream of requests arriving chronologically and output a formatted log.
Input Format:
timestamp, unique_id, amount, card_number, merchant
Example:
5,R1,5.60,4242424242424242,bobs_burgers
10,R2,500.00,4242111111111111,a_corp
Output:
<timestamp> <id> <amount> APPROVE
Part 2: Fraud Rules Stream
To mitigate risk, a "Fraud Rules" stream is introduced.
Rule Format:
time, field, value
Meaning:
1, merchant, bobs_burgers: From t=1 onwards, all transactions frombobs_burgersare fraudulent.20, card_number, 4242...: From t=20 onwards, all transactions with this card are fraudulent.
Characteristics:
- Rules are permanently effective once active.
- Rules are not retroactive (only affect transactions at or after the rule's timestamp).
Task: Implement a system that ingests both the "Transaction Stream" and "Rules Stream". For each transaction, if it matches any active fraud rule at that moment, output REJECT; otherwise, APPROVE.
oavoservice Solution Analysis
The challenge lies in merging two streams and efficient state lookups.
1. Data Structure Choice
Since rules target specific fields (like merchant or card_number), we need fast lookups.
- Recommended:
HashMap<Field, HashMap<Value, ActiveTime>>. - Example:
rules["merchant"]["bobs_burgers"] = 1. This meansbobs_burgersis banned starting at t=1.
2. Decision Logic
For each transaction (at time T_trans):
- Check if the transaction's
merchantis in the rule map. If yes, andRule_StartTime <= T_trans, REJECT. - Check if the
card_numberis in the rule map. If yes, andRule_StartTime <= T_trans, REJECT. - Otherwise, APPROVE.
3. Handling Stream Order
In an interview, inputs might be two separate lists.
- If given two lists, you might need to merge them by timestamp or iterate through transactions while advancing a pointer in the rules list.
- Since the problem guarantees chronological order, maintaining a global Rule Set state is sufficient.
Code Snippet (Python)
class FraudDetector:
def __init__(self):
# Store start time for each rule
# key: field_name, value: { field_value: start_time }
self.rules = {
"merchant": {},
"card_number": {}
}
def add_rule(self, time, field, value):
# If multiple rules exist for the same entity, keep the earliest one?
if value not in self.rules[field]:
self.rules[field][value] = int(time)
def check_transaction(self, time, merchant, card_num):
# Check Merchant
if merchant in self.rules["merchant"]:
if self.rules["merchant"][merchant] <= time:
return "REJECT"
# Check Card Number
if card_num in self.rules["card_number"]:
if self.rules["card_number"][card_num] <= time:
return "REJECT"
return "APPROVE"
Want the Full Solution & Test Cases?
oavoservice maintains the most comprehensive database of Stripe interview questions with verified Standard Solutions. Our VO support service doesn't just give answers—we teach you how to demonstrate your system design thinking to interviewers.
- Optimization: Techniques to improve performance from O(N) to O(1).
- Code Quality: Industry-standard naming and modularization.
Contact Us to secure your Stripe Offer.