Payout Scheduler: Fixed Intervals, Per-Merchant Schedules and Hold Periods

Read the full interview experience this question came from →

Quick Overview

A three-part payments coding exercise: group transactions into payouts on a fixed interval, then on per-merchant schedules with their own first payout day, then with merchant hold periods. It tests boundary rules for same-day transactions, exact handling of money in cents, grouping and a deterministic output order.

Payout Scheduler: Fixed Intervals, Per-Merchant Schedules and Hold Periods

Company: Stripe

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

You are building the payout calculation for a payments platform. Merchants accept transactions, and the platform periodically pays the accumulated money out to them. The interview builds the calculation in three stages, each extending the previous one; implement each stage as a function. Assumed input and output shapes (confirm the exact field names with the interviewer): - A transaction is a record with `id` (string), `amount` (integer number of cents) and `day` (non-negative integer day number). From Part 2 on it also has `merchant`, the name of the merchant it belongs to. - Transactions arrive in no particular order. - Each output row is a record whose fields each part lists. Amounts are converted from cents to dollars and printed with exactly two decimal places, so 1349 cents becomes `"13.49"`. ### Clarifying Questions - In Part 1, is the payout schedule anchored at day 0, so that payouts fall on days `payout_interval`, `2 * payout_interval`, and so on? - In what order should the transaction IDs inside one payout appear: input order or sorted? - When two merchants are paid on the same day, in what order should their rows appear? - Can an amount be negative (a refund), and how should a negative total be printed? - In Part 3, is a payout that falls exactly `hold_days` after the transaction eligible, and when `hold_days` is 0, does a transaction on a payout day still wait for the next payout? - What should happen to a transaction whose merchant is not in the merchant list? ### Part 1 — Fixed-interval payouts Given a list of transactions and an integer `payout_interval`, the platform pays out once every `payout_interval` days. Each transaction is paid on the next payout day after it occurs; a transaction that occurs on a payout day is not part of that day's payout and waits for the next one. Transactions paid on the same day are combined: add up their amounts and record their transaction IDs. Return one row per payout day that has at least one transaction, with fields `day`, `amount` and `transaction_ids`, sorted by payout day. Payout days without transactions are not output. Example, with payouts on multiples of the interval and `payout_interval = 7`: ```text transactions: id amount day t1 1250 2 t2 500 7 t3 99 6 t4 1000 20 output: day amount transaction_ids 7 13.49 [t1, t3] 14 5.00 [t2] 21 10.00 [t4] ``` `t2` occurs on payout day 7, so it waits for day 14. ```hint Skip the calendar You do not need to walk through the days one by one: the payout day of a single transaction can be computed directly from its own day and the interval. ``` ```hint Money as integers Decide when the conversion from cents to dollars should happen, and whether a floating-point number is safe for the running total. ``` #### What This Part Should Cover - The exact rule that maps a transaction's day to its payout day, including the same-day case - Grouping by payout day with an exact integer total and the list of IDs - Formatting cents as dollars with two decimals, and sorting the output ### Part 2 — A schedule per merchant Now there is also a list of merchants. Each merchant has `name`, `first_payout` (the day of its first payout) and `payout_interval`, and each transaction has a `merchant` field. A merchant is paid on days `first_payout`, `first_payout + payout_interval`, `first_payout + 2 * payout_interval`, and so on. Each transaction goes to its own merchant's next payout day after the transaction's day, with the same rule as Part 1 for a transaction that occurs on a payout day. Aggregate by merchant and payout day: transactions of different merchants are never combined, even when they are paid on the same day. Return rows with `day`, `merchant`, `amount` and `transaction_ids`, sorted by payout day. Example (the `hold_days` column is used only in Part 3): ```text merchants: name first_payout payout_interval hold_days acme 3 5 4 bolt 2 3 0 transactions: id amount day merchant p1 1000 1 acme p2 250 3 acme p3 499 3 bolt p4 1 4 bolt Part 2 output: day merchant amount transaction_ids 3 acme 10.00 [p1] 5 bolt 5.00 [p3, p4] 8 acme 2.50 [p2] ``` ```hint Before the first payout Check your payout-day rule on a transaction that occurs before its merchant's first payout, and on one that occurs exactly on it. ``` #### What This Part Should Cover - The next payout day for an arbitrary first payout and interval, computed in constant time - A grouping key that keeps merchants apart, and a deterministic order for rows on the same day - Looking up each transaction's merchant, and what to do with an unknown merchant ### Part 3 — Hold periods Each merchant now also has `hold_days`. After a transaction occurs, it must wait `hold_days` days before it is eligible for a payout. Each transaction goes to the earliest payout day of its merchant on which it is eligible. Aggregation and output are the same as in Part 2. With the merchants and transactions above, the Part 3 output is: ```text day merchant amount transaction_ids 5 bolt 5.00 [p3, p4] 8 acme 12.50 [p1, p2] ``` ```hint Check the zero hold Ask what your rule returns when `hold_days` is 0, and whether that matches Part 2 exactly. ``` #### What This Part Should Cover - The eligibility rule and its boundary, a payout that falls exactly at the end of the hold - Consistency with Part 2 when `hold_days` is 0 - Reusing one schedule function across the stages instead of three diverging copies ### What a Strong Answer Covers - Precise boundary handling: transactions on payout days, before the first payout, and at the end of a hold - Computing payout days arithmetically instead of simulating the calendar, with the resulting complexity - Exact money handling in integer cents and correct two-decimal formatting - A deterministic output order, including ties between merchants on one day and the order of IDs - Code that evolves cleanly from Part 1 to Part 3, with tests that pin the edge cases ### Follow-up Questions - Transactions arrive as a stream, day by day. How would you emit each payout on its payout day without keeping every transaction in memory? - A merchant changes its `payout_interval` from some day on. How does the next-payout calculation change? - Refunds can make a merchant's total for one payout negative. What would you output, and what would you ask the business? - How would you test this code so that the boundary rules cannot silently regress?

Overview: A three-part payments coding exercise: group transactions into payouts on a fixed interval, then on per-merchant schedules with their own first payout day, then with merchant hold periods. It tests boundary rules for same-day transactions, exact handling of money in cents, grouping and a deterministic output order.

Read the full Stripe Software Engineer interview experience this question came from

Stripe logo
Stripe
Oct 25, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
2
0

You are building the payout calculation for a payments platform. Merchants accept transactions, and the platform periodically pays the accumulated money out to them. The interview builds the calculation in three stages, each extending the previous one; implement each stage as a function.

Assumed input and output shapes (confirm the exact field names with the interviewer):

  • A transaction is a record with id (string), amount (integer number of cents) and day (non-negative integer day number). From Part 2 on it also has merchant , the name of the merchant it belongs to.
  • Transactions arrive in no particular order.
  • Each output row is a record whose fields each part lists. Amounts are converted from cents to dollars and printed with exactly two decimal places, so 1349 cents becomes "13.49" .

Clarifying Questions Guidance

  • In Part 1, is the payout schedule anchored at day 0, so that payouts fall on days payout_interval , 2 * payout_interval , and so on?
  • In what order should the transaction IDs inside one payout appear: input order or sorted?
  • When two merchants are paid on the same day, in what order should their rows appear?
  • Can an amount be negative (a refund), and how should a negative total be printed?
  • In Part 3, is a payout that falls exactly hold_days after the transaction eligible, and when hold_days is 0, does a transaction on a payout day still wait for the next payout?
  • What should happen to a transaction whose merchant is not in the merchant list?

Part 1 — Fixed-interval payouts

Given a list of transactions and an integer payout_interval, the platform pays out once every payout_interval days. Each transaction is paid on the next payout day after it occurs; a transaction that occurs on a payout day is not part of that day's payout and waits for the next one. Transactions paid on the same day are combined: add up their amounts and record their transaction IDs. Return one row per payout day that has at least one transaction, with fields day, amount and transaction_ids, sorted by payout day. Payout days without transactions are not output.

Example, with payouts on multiples of the interval and payout_interval = 7:

transactions:
  id   amount  day
  t1   1250    2
  t2    500    7
  t3     99    6
  t4   1000   20

output:
  day  amount  transaction_ids
  7    13.49   [t1, t3]
  14   5.00    [t2]
  21   10.00   [t4]

t2 occurs on payout day 7, so it waits for day 14.

What This Part Should Cover Guidance

  • The exact rule that maps a transaction's day to its payout day, including the same-day case
  • Grouping by payout day with an exact integer total and the list of IDs
  • Formatting cents as dollars with two decimals, and sorting the output

Part 2 — A schedule per merchant

Now there is also a list of merchants. Each merchant has name, first_payout (the day of its first payout) and payout_interval, and each transaction has a merchant field. A merchant is paid on days first_payout, first_payout + payout_interval, first_payout + 2 * payout_interval, and so on. Each transaction goes to its own merchant's next payout day after the transaction's day, with the same rule as Part 1 for a transaction that occurs on a payout day. Aggregate by merchant and payout day: transactions of different merchants are never combined, even when they are paid on the same day. Return rows with day, merchant, amount and transaction_ids, sorted by payout day.

Example (the hold_days column is used only in Part 3):

merchants:
  name  first_payout  payout_interval  hold_days
  acme  3             5                4
  bolt  2             3                0

transactions:
  id   amount  day  merchant
  p1   1000    1    acme
  p2    250    3    acme
  p3    499    3    bolt
  p4      1    4    bolt

Part 2 output:
  day  merchant  amount  transaction_ids
  3    acme      10.00   [p1]
  5    bolt      5.00    [p3, p4]
  8    acme      2.50    [p2]

What This Part Should Cover Guidance

  • The next payout day for an arbitrary first payout and interval, computed in constant time
  • A grouping key that keeps merchants apart, and a deterministic order for rows on the same day
  • Looking up each transaction's merchant, and what to do with an unknown merchant

Part 3 — Hold periods

Each merchant now also has hold_days. After a transaction occurs, it must wait hold_days days before it is eligible for a payout. Each transaction goes to the earliest payout day of its merchant on which it is eligible. Aggregation and output are the same as in Part 2.

With the merchants and transactions above, the Part 3 output is:

  day  merchant  amount  transaction_ids
  5    bolt      5.00    [p3, p4]
  8    acme      12.50   [p1, p2]

What This Part Should Cover Guidance

  • The eligibility rule and its boundary, a payout that falls exactly at the end of the hold
  • Consistency with Part 2 when hold_days is 0
  • Reusing one schedule function across the stages instead of three diverging copies

What a Strong Answer Covers Guidance

  • Precise boundary handling: transactions on payout days, before the first payout, and at the end of a hold
  • Computing payout days arithmetically instead of simulating the calendar, with the resulting complexity
  • Exact money handling in integer cents and correct two-decimal formatting
  • A deterministic output order, including ties between merchants on one day and the order of IDs
  • Code that evolves cleanly from Part 1 to Part 3, with tests that pin the edge cases

Follow-up Questions Guidance

  • Transactions arrive as a stream, day by day. How would you emit each payout on its payout day without keeping every transaction in memory?
  • A merchant changes its payout_interval from some day on. How does the next-payout calculation change?
  • Refunds can make a merchant's total for one payout negative. What would you output, and what would you ask the business?
  • How would you test this code so that the boundary rules cannot silently regress?