Payment gateway
Payment operations, normalised once
Every processor implements the same handful of ideas with different names, different state machines and different failure modes. The gateway module exists so that a platform learns those ideas once rather than once per integration.
State of the work
- Operations callable
- None. No endpoint exists.
- Processors connected
- None, in production or otherwise.
- Design fixed
- Idempotency on every mutation; accepted and settled never collapse.
- Sequence
- Follows the vault. A gateway with nothing to reference is not useful.
Intended operations
These are the operations the module is designed around. None is currently callable.
authorize
Reserve funds against a payment method without moving them. The step that makes a guarantee real.
capture
Take an authorised amount. Separated from authorisation because the two rarely happen at the same moment.
partial capture
Take less than was authorised, which is the normal case whenever the final amount is not known up front.
void
Release an authorisation that will not be captured, instead of letting it expire against the cardholder's available balance.
refund
Return a captured amount, in full or in part, with the original payment as its lineage.
retrieve
Read the current state of a payment, including what the processor actually said rather than what was assumed.
A payment has a lifecycle, and provider acceptance is not the end of it
Treating an accepted request as a completed payment is how reconciliation breaks. The state model is designed to keep those separate.
attempted
accepted
Provider took the request
authorized
Funds reserved
captured
Funds taken
settled
Money actually moved
Diagram · Intended state model. Terminal states — refunded, disputed, failed — branch from this sequence and are not shown.
The distinction between accepted and settled is the one that costs money when it is collapsed. A platform that treats acceptance as settlement will report revenue that has not arrived and cannot explain the gap at month end.
Design commitments
- Idempotency
- Every mutating operation takes an idempotency key. A retried request after a timeout must not become a second charge — the failure mode where a customer is billed twice by a network blip is a design defect, not bad luck.
- Replay resistance
- Requests are bound to a merchant, a scope and a window, so that a captured request cannot be replayed later or against a different tenant.
- Deterministic audit
- Every payment mutation produces an audit record with a correlation identifier that survives across the gateway, the processor response and the reconciliation event.
- Sanitised errors
- Processor reason codes are normalised and stripped before they reach a caller, so that diagnosing a decline never becomes a way of extracting card data.