Transaction Fee Calculator — Channel Volume Tiers
Reported by candidates from Stripe's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Stripe's January 2026 OA hands you a CSV of payments and asks for a fee per row, with tiers that shift as each merchant's volume grows on a specific channel. Sounds like parsing homework. It's a hash map problem with a binary search tucked inside. With 10^5 rows and 10^5 tiers, you can't rescan the tier list per transaction. Group tiers by provider and country, sort them once, then look up each transaction fast. If the tier logic blanks on you mid-assessment, StealthCoder is the safety net running invisibly on your screen.
The problem
Process a CSV stream of payment transactions and calculate each transaction's fee. Fee tiers depend on the payment provider, buyer country, and the merchant's earlier successful volume for that exact channel. Transaction data csvData contains a header followed by transaction rows in this exact format: id,merchant_id,payment_provider,buyer_country,status,amount amount is a non-negative number of cents. Fields never contain commas. Fee tiers Each row of feeTiers is [payment_provider, buyer_country, min_prior_volume, rate_basis_points, fixed_fee]. For every provider-country pair: There is exactly one row with min_prior_volume = 0. Thresholds are unique, but the rows may be given in any order. The active tier is the row with the greatest min_prior_volume that is at most the merchant's successful volume before the current transaction. Processing rules Maintain volume independently for every (merchant_id, payment_provider, buyer_country) key. If status is not payment_completed, output fee 0 and do not change volume. Otherwise, choose the tier using the volume before the transaction. Calculate floor(amount * rate_basis_points / 10000) + fixed_fee. After calculating the fee, add amount to that channel's volume. Return a String[] whose first row is id,fee, followed by one output row per transaction in input order. Function calculateTieredFees(csvData: String, feeTiers: String[][]) → String[] Examples Example 1 csvData = "id,merchant_id,payment_provider,buyer_country,status,amount\nt1,m1,card,us,payment_completed,6000\nt2,m1,card,us,payment_completed,5000\nt3,m1,card,us,payment_completed,1000\nt4,m1,card,ca,payment_completed,1000" feeTiers = [["card","us","0","300","30"],["card","us","10000","200","20"],["card","ca","0","250","25"]] return = ["id,fee","t1,210","t2,180","t3,40","t4,50"] The first two US card transactions use the base tier. Their combined successful volume becomes 11000, so t3 uses the lower tier. The Canada transaction has a separate channel volume and uses its own base tier. Example 2 csvData = "id,merchant_id,payment_provider,buyer_country,status,amount\na,m1,card,us,payment_completed,10000\nb,m1,card,us,payment_completed,1\nc,m1,card,us,payment_failed,100000\nd,m1,card,us,payment_completed,5000" feeTiers = [["card","us","0","100","10"],["card","us","10000","50","5"]] return = ["id,fee","a,110","b,5","c,0","d,30"] Transaction a raises the prior volume to exactly 10000, so b uses the second tier. The failed transaction pays no fee and does not affect volume; d remains in the second tier. Constraints 1 <= transaction rows <= 10^5. 1 <= feeTiers.length <= 10^5. 0 <= amount, min_prior_volume, fixed_fee <= 10^9. 0 <= rate_basis_points <= 10000. Every transaction's provider-country pair has a valid tier beginning at volume 0. Identifiers contain only ASCII letters, digits, and underscores. All cumulative volumes and fee arithmetic fit in signed 64-bit integers.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is two lookups. First, build a map from (provider, country) to a list of tiers sorted by min_prior_volume. Rows come in any order, so sort them yourself. Second, keep a running volume map keyed by (merchant_id, provider, country). For each completed transaction, binary search the sorted tiers for the greatest threshold at or below the volume before the transaction. Compute floor(amount * bps / 10000) + fixed_fee, then add amount to volume. Order matters: fee first, volume update second. Example 2 tests this, since a pushes volume to exactly 10000 and b must land in the higher tier. Pitfalls: updating volume on failed payments, scanning tiers linearly and timing out, and using 32-bit ints for amount * bps. Use 64-bit. Join keys with a delimiter that can't collide. StealthCoder is your hedge if the edge cases slip while the clock runs.
Drill it cold or hedge it with StealthCoder. Either way, don't walk into the OA hoping you remember the trick.
You can drill Transaction Fee Calculator — Channel Volume Tiers cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made for the candidate who got the OA invite this morning and has 72 hours, not six months.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Stripe's OA.
Stripe reuses patterns across OAs. Made for the candidate who got the OA invite this morning and has 72 hours, not six months. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Transaction Fee Calculator — Channel Volume Tiers FAQ
What's the trick in the Stripe transaction fee calculator?+
Pre-sort tiers per (provider, country) and binary search by prior volume. Keep a separate running volume per (merchant, provider, country). Compute the fee from the volume before the transaction, then add the amount. That's the whole problem once the parsing is done.
How hard is this problem really?+
Medium at most. There's no fancy algorithm, just careful state handling. The difficulty is in details: tiers arrive unsorted, failed payments don't touch volume, and the threshold comparison is inclusive. Get those three right and it's straightforward.
Why can't I just loop over all tiers for each transaction?+
With up to 10^5 transactions and 10^5 tiers, a worst-case linear scan is around 10^10 operations. That times out. Grouping tiers by channel and using binary search brings each lookup down to log of the group size.
What edge cases should I test before submitting?+
Volume exactly equal to a threshold, which should use the higher tier. Failed transactions, which pay 0 and leave volume alone. Zero amounts. Same merchant on different countries or providers. Large amounts times basis points, which need 64-bit math. Also confirm the header row is skipped and output keeps input order.
How do I prepare for this in 48 hours?+
Write the solution once from scratch: CSV split, a map of sorted tier arrays, a binary search for the floor threshold, and a volume map with composite string keys. Run both examples by hand. Practice that pattern, since tiered pricing and rate lookup show up often in payments-style questions.