What moves a payout forward
1
CREATED → PENDING_PAYMENT
We lock an FX rate, compute the settlement amount and fees, and issue a
payment instruction with an expiry. Generation starts as soon as the payout is
created; a sweep every 30 seconds re-picks anything left behind.Until this runs,
settlement_amount is 0 and payment_instruction is
null. That is not an error — the amount is genuinely unknown until the rate
is locked.2
PENDING_PAYMENT → PAYMENT_RECEIVED
We match your settlement to the instruction by the account it was paid into
and the amount. Crypto settlements additionally wait for network
confirmations.Underpayment does not advance the payout — it is held for review rather
than partially processed. Overpayment proceeds, and the excess is recorded and
returned with any later refund.
3
PAYMENT_RECEIVED → PROCESSING
We dispatch the transfer to the processor. Each attempt is a separate record,
so a retry never overwrites the history of a failed one — see
GET /v1/payouts/{id}/outflows.4
PROCESSING → SUCCESSFUL or FAILED
We poll the processor until it reports a terminal outcome. A failed attempt
with retries remaining returns the payout to
PAYMENT_RECEIVED so a fresh
attempt is dispatched; only once attempts are exhausted does it become
FAILED.Expiry is terminal
If the instruction expires unpaid, the instruction is markedEXPIRED and the
payout ends at EXPIRED. It is not regenerated and the rate is not re-locked.
A merchant who misses the window creates a new payout.
A payout that is holding money is never expired — not on underpayment, and not
while a crypto settlement is still confirming. Those stay in
PENDING_PAYMENT
for our operations team to resolve. EXPIRED only ever means no funds arrived,
which is why it needs no refund.expires_at off the instruction rather than assuming a
duration.
When a payout fails
If a payout fails after your settlement was confirmed, the money is not lost. We raise a refund and send it to the destination you registered for that settlement currency, minus the cost of sending it back. The payout is markedis_refunded: true with a refund_reference as soon as the
refund is raised. There is no wallet and no balance to withdraw — see
Refunds.
A payout that failed before any money arrived has nothing to return and raises no
refund.
No cancellation
There is no cancel endpoint. A payout you no longer want simply goes unpaid and lapses toEXPIRED at the instruction’s expiry. Once you have settled it, it is
committed.
The status timeline
GET /v1/payouts/{id} returns a status_timeline: every transition in order,
each with the reason it happened, what triggered it, and when.
Reason codes
Status values are uppercase everywhere they appear — on the payout, in
status_timeline, and inside webhook payloads. Webhook event types are the
lowercase dotted form (payout.pending_payment), so the two are easy to mix up
when you branch on them.