FastPrepTransaction Fee Calculator — Channel Volume Tiers

Transaction Fee Calculator — Channel Volume Tiers

Stripe logoStripe● MediumNEW GRADPHONE SCREEN
Learn

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,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

  1. Maintain volume independently for every (merchant_id, payment_provider, buyer_country) key.
  2. If status is not payment_completed, output fee 0 and do not change volume.
  3. Otherwise, choose the tier using the volume before the transaction.
  4. Calculate floor(amount * rate_basis_points / 10000) + fixed_fee.
  5. 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.

More Stripe problems

See Stripe hiring insights
public String[] calculateTieredFees(String csvData, String[][] feeTiers) {
  // Write your code here
}
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"]]
expected["id,fee", "t1,210", "t2,180", "t3,40", "t4,50"]
Checking account…