// Case study · Fintech / payments
Payout engine
A payout flow that pushed money out across providers with the same reliability guarantees as taking it in — commit, confirm, reconcile, never double-pay.
The problem
Paying money out is the inbound flow in reverse, with the same real-money stakes: different provider payout methods, asynchronous confirmations, and a hard requirement that a payout is never lost or sent twice.
The approach
Modeled payouts as their own flow actions in the gateway — payout methods per provider, a payout commit processor that drives each payout to a confirmed terminal state, and payout transactions tracked and reconciled alongside the request.
The decision & trade-off
Reused the same flow-action and commit machinery as payments rather than a separate payout subsystem — one mental model and one reconciliation path, at the cost of generalizing the abstraction to cover both directions of money movement.
Architecture
Payout request → payout flow action → provider payout method → commit processor → confirmed transaction, with idempotent commits so retries never double-pay.
Outcome
Payouts across multiple providers under the same guarantees, states and reconciliation as inbound payments.
What I'd do differently
Surface payout-provider health earlier so routing could steer around a degraded payout rail the way it does for inbound charges.
Architecture diagram
Stack
- PHP
- Symfony
- PostgreSQL
- Queues
Have a similar problem?
Tell me about it — I reply within a day.