Transaction Fee Calculator — Channel Volume Tiers
Problem statement
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,amountamount 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_volumethat 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
statusis notpayment_completed, output fee0and 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
amountto 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.