Katkat

Design Bakery Chain Card Payments With Tips and Nightly Settlement

OpenAISoftware Engineer · Onsite

Last updated

Design the payment system for a bakery chain's counter terminals, where a card is authorized for the purchase, a tip is added afterward, and each location's transactions are captured together in a nightly settlement batch that must scale as the chain grows.

Design the payment system behind a bakery chain's counter terminals. A customer's card is authorized for the purchase amount at checkout, the customer can add a tip afterward (often on a separate screen once the transaction is already in progress), and each location bundles its day's finalized transactions into one settlement submitted to the card processor once per night. The interviewer's main interest is how nightly settlement scales as the chain grows, and you're expected to speak to both idempotency and reconciliation against the processor along the way.

Assume a standard card-present tip pattern: the swipe places a hold for the purchase price, the tip gets layered on as a separate adjustment once it's known, and the combined total only actually gets pulled from the customer's card when that night's batch for the location goes out. Treat the card network and the processor as black boxes you call into, not components you're designing.

Clarifying Questions

  • Roughly how many locations, terminals, and transactions per day does the chain run, and how large is the nightly window each location's batch must finish within?
  • Does every location share one settlement cutoff, or does each close its own day on its local clock?
  • Until when can a tip still be changed, and what should happen to a tip adjustment that arrives after that location's batch has already been submitted?
  • Does the processor accept a settlement file, batched API calls, or either — and does it support an idempotency key or a batch reference number?
  • Are payouts to each bakery location in scope, or only getting transactions submitted and reconciled?

Part 1 — Authorizing the swipe and attaching a tip

Design the data model and the APIs behind authorizing a card swipe and later attaching a tip to it. Terminal network connections drop constantly, so assume every call gets retried.

Cover in this part:

  • The states a transaction moves through, from authorized to tip-adjusted to captured, and what data each state carries
  • An idempotency scheme for both the authorization call and the tip-adjustment call
  • How a processor timeout on an authorization is handled without risking two holds on the same card

Part 2 — Making the nightly run scale

Once a location's day closes, its completed transactions need to be batched up and sent off for capture. Make this scale as the chain adds locations and transaction volume climbs, staying inside the nightly window, and make sure a crash midway through a run can't cause a transaction to vanish or be charged twice.

Cover in this part:

  • How work is partitioned (by location, by shard, or otherwise) so settlement parallelizes as the chain grows
  • Exactly-once submission per transaction to the processor, including what happens on a worker crash mid-batch
  • Reconciliation: detecting a transaction the processor's report disagrees with, and what a location operator sees when that happens

Hints

Hint 1

A terminal that times out resends the same request — decide what makes two authorization attempts 'the same one' before designing the state machine.

Hint 2

Model the tip adjustment as its own idempotent operation on an existing authorization, not as a brand-new transaction.

Hint 3

Think about settlement as many small, independent units of work (per transaction or per small group) rather than one giant per-location job, so a partial failure only needs to retry the units that actually failed.

Hint 4

Decide what 'done' means for the nightly run as a whole — all locations' batches submitted, or all of them confirmed accepted by the processor — before designing how you detect and recover from failures.

Follow-up questions

  • How would you handle a card declined at capture time, hours after the original authorization succeeded?
  • How would you support a location in a different time zone without processing its batch at the wrong local time?
  • What changes if the chain needs same-day settlement instead of nightly batches?
  • How would you test the reconciliation logic without access to the real processor's settlement report format?