Katkat

Compute balances with transaction fees and rejections

StripeSoftware Engineer · Onsite

Last updated

This problem tests the ability to manage stateful financial records while enforcing conditional logic, fee structures, and balance validation.

Problem Statement

You are building a ledger system for a payment processor. You need to maintain the balances for multiple user accounts based on a list of incoming transactions.

Each transaction has a sender, recipient, amount, and a fixed fee that is deducted from the sender's balance.

A transaction is successful only if:

  1. The sender has enough funds to cover both the amount and the fee (sender_balance >= amount + fee).
  2. The sender and recipient are not the same account.
  3. The amount and fee are positive integers.

If a transaction is successful, the amount is added to the recipient's balance, and the amount + fee is deducted from the sender's balance. If a transaction fails (e.g., insufficient funds or invalid conditions), the ledger remains unchanged for that transaction.

Implement the function process_transactions(initial_balances, transactions):

  • initial_balances: A dictionary mapping account IDs (strings) to their starting integer balances.
  • transactions: A list of dictionaries, each containing sender, recipient, amount, and fee.
  • Returns: A dictionary containing the final balances of all accounts after processing all transactions in order.

Examples

Input:

balances = {"A": 100, "B": 50}
transactions = [
    {"sender": "A", "recipient": "B", "amount": 30, "fee": 5},
    {"sender": "B", "recipient": "A", "amount": 60, "fee": 5}
]

Output:

{"A": 75, "B": 75}

Explanation: First transaction succeeds (A: 100 - 35 = 65, B: 50 + 30 = 80). Second transaction fails because B only has 80, but needs 65 (60+5).

Constraints

  • Number of accounts: up to 10,000.
  • Number of transactions: up to 100,000.
  • Balances and amounts fit within 64-bit integers.

Hints

Hint 1

Use a hash map (dictionary) to store and update balances in O(1) average time.

Hint 2

Always check the sender's balance before updating any state, and perform the deduction and addition as a single atomic step for each transaction.

Hint 3

Ensure you account for cases where an account ID might appear in a transaction but was not present in the initial_balances input.

Follow-up questions

  • How would you modify your solution to support 'negative' balances if you wanted to allow overdrafts up to a certain limit?
  • If the ledger needs to be audited, how would you store the transaction history to ensure you can reconstruct the state at any point in time?
  • How would you handle high-frequency transactions for the same account to prevent race conditions in a multi-threaded environment?