Building the platform's crypto payment rails — a fintech capability at every transaction boundary
A two-year epic threading fiat↔USDT conversion through every transaction boundary on the platform — where a precision slip is a real financial loss.
Situation
The platform needed cryptocurrency deposits and withdrawals alongside fiat — conversion at every transaction boundary, on a platform where some third-party providers couldn't hold crypto at all.
Approach
I drove the payments side for two years as half of a two-engineer pair (alongside the team's assistant lead): wallet protocol integrations (OMNI, ERC-20, TRC-20), USDT deposits and withdrawals, and fiat↔USDT conversion threaded through every transaction boundary. Provider heterogeneity was the judgment call — some providers couldn't hold USDT at all, so I absorbed the difference in one cross-cutting compatibility layer rather than leaking it into every call site — with exact-decimal handling at the wallet edges, where a rounding error becomes a real discrepancy.
Outcome
Crypto rails went live across every payment flow; later currencies reused the same config-driven paths instead of re-opening them.
The design, in code
Representative snippet of the production design — rewritten for publication; not company source.
// On-chain confirmations arrive more than once. Credit is a state
// transition guarded by the current state — a replayed webhook is a no-op.
const NEXT: Record<State, State[]> = {
detected: ['confirmed'],
confirmed: ['credited'],
credited: [], // terminal — a second "confirmed" changes nothing
};
function transition(from: State, to: State): State {
if (!NEXT[from].includes(to)) throw new Error(`illegal ${from}→${to}`);
return to; // illegal jumps throw instead of double-crediting
}
// At a wallet edge a rounding error is a real discrepancy. Never float —
// convert in integer minor units, and absorb provider quirks in one layer.
function toUsdt(fiatMinor: bigint, rate: Rate): bigint {
return (fiatMinor * rate.num) / rate.den; // exact integer math
}
// Some providers can't hold USDT at all — the difference is
// absorbed here, not leaked into every call site.
function settleCurrency(p: Provider): Currency {
return p.supports('USDT') ? 'USDT' : convertAtBoundary(p.fiat);
}