The happy path is the easy part
Charging a customer once, successfully, on a good connection is straightforward.
The engineering effort belongs in what happens when the network drops between
the charge and the confirmation, when a provider retries a callback four times,
when a customer taps pay twice, and when a refund is issued for an order that
was partly delivered.
How we design money movement
- Record intent first. A transaction exists in the system before it exists
at the provider, so nothing is untraceable.
- Make every operation idempotent. Keyed so a retry returns the original
outcome rather than performing the action again.
- Treat callbacks as unreliable. Deduplicated, verified, and reconciled
against a polled status check rather than trusted on arrival.
- Derive balances from entries. Double-entry postings with balances
calculated, so a wrong balance can be explained rather than just corrected.
- Reconcile daily, automatically. With an exception queue that a person can
clear in minutes.
Testing the failure paths
Payment flows are tested in provider sandboxes against scripted failures:
timeouts, duplicate callbacks, partial refunds, settlement mismatches and
provider outages. If a failure mode has not been exercised before launch, it
will be exercised in production instead.