Design Currency Conversion

Medium35 min
1 / 30
understanding6 min read

Problem Statement & Context

Problem Statement & Context

Problem Statement & Context

Design a currency conversion platform for global commerce. The problem it solves: a shopper sees a price in USD, pays in EUR, and must never get a surprise total at capture time. The platform ingests authoritative FX rates, applies merchant spread rules, and returns deterministic quotes that checkout, tax, and settlement can replay hours later — during a refund, the system must reproduce the exact total the shopper saw.

The reproducibility invariant

The single invariant that defines the whole design: the same inputs — amount, currencies, policy version, snapshot id — must always produce the identical minor-unit result. This is what lets a refund six hours after purchase repay the exact amount captured, and what lets a finance team audit a total months later. Every architectural decision (immutable snapshots, integer math, versioned policies) exists to protect that invariant. Money math that is not reproducible is not auditable, and an unauditable payment system is unacceptable.

How the real systems draw the line

Ground the design in how the platforms actually separate the concerns: Stripe exposes multi-currency presentment on PaymentIntents (what the shopper is charged) separately from settlement (what the merchant books); PayPal separates transaction currency from settlement currency in its merchant reports; Adyen itemizes the FX markup explicitly in its settlement detail files. The lesson in all three: presentment currency and settlement currency are distinct, and the conversion between them must be pinned, itemized, and reproducible — not recomputed at today's rate whenever someone asks.

Key Highlights

  • A currency conversion platform ingests authoritative FX rates, applies merchant spread, and returns deterministic quotes that checkout/tax/settlement can replay hours later (a refund must reproduce the exact total the shopper saw)
  • The defining invariant: the same inputs (amount, currencies, policy version, snapshot id) always produce the identical minor-unit result — money math that isn't reproducible isn't auditable
  • Real systems separate presentment currency (what the shopper is charged) from settlement currency (what the merchant books) — Stripe PaymentIntents, PayPal reports, Adyen amount vs merchantSettlementAmount
  • The conversion between presentment and settlement must be pinned, itemized, and reproducible — never recomputed at today's rate
Say this
For Problem Statement & Context, mention versioned FX snapshots and why refunds must reference the original lock.
Whiteboard tip
Draw presentment vs settlement currencies before APIs when discussing problem.

Section Rescue Kit

Buzzwords to use:

ISO-4217Mid-Market Rate

Safe statements:

  • "If pressed on Problem Statement & Context, I will state assumptions then choose a default."
  • "I can compare PSP FX versus in-house rates with trade-offs."
Design Currency Conversion - System Design | WinJob | WinJob