Every payment runs through the same engine. Every decision is written down.
The orchestration engine takes a payment from creation to a terminal state: it evaluates risk, selects providers by rule, sends the request, interprets the outcome, retries where it is safe to do so, and emits events. The whole sequence is stored as a timeline you can read from the API and the dashboard.
Four stages inside one request.
For synchronous payment methods the full sequence completes within the create request. For asynchronous methods the engine pauses at the provider's customer action and resumes when the provider notifies NATIO.
Risk evaluation
Routing
Provider attempt
Retry, failover, events
Retries only when it is safe. Never a second charge.
Whether NATIO retries depends on the failure category reported by the provider, and on what the provider says actually happened.
- Double-charge protection
- After a timeout NATIO looks the attempt up at the provider before doing anything else. If the provider confirms the charge, the payment is recovered as successful; only a confirmed absence of a charge allows a failover.
- Unknown outcomes
- If the provider cannot answer, the attempt is marked unknown and a status sync is scheduled. The payment does not fail over blind.
- Attempts are recorded
- Each attempt carries provider, account, outcome, provider code and message, fee and latency. They are returned on the payment object and shown in the dashboard.
- Sandbox scenarios
- test_scenario values such as failover, timeout, timeout_recovered, unavailable and all_fail reproduce each path against the demo providers.
- soft
- Insufficient funds, do-not-honor, issuer unavailable, try again later, limits. May cascade to another eligible provider.
- hard
- Stolen, lost, expired or invalid card, fraud suspected, authentication failed, cancelled by customer. Never retried.
- technical
- Technical error, timeout, provider unavailable, configuration error. Fails over to the next provider after verification.
- policy
- No route available, unsupported currency or method, risk blocked, amount out of limits, attempts exhausted. Terminal.
Strict states, guarded transitions.
Payments, refunds and payouts move through explicit states. Transitions are validated in code and guarded at the database level, so concurrent writers cannot produce an invalid path.
| Status | Meaning | Allowed next states |
|---|---|---|
| created | Accepted and persisted; not yet sent to a provider. | processing · pending · failed · cancelled |
| pending | Waiting: manual risk review, or a provider awaiting customer action. | processing · failed · cancelled |
| processing | A provider attempt is in flight, or the payment awaits an asynchronous confirmation. | authorized · successful · failed · cancelled · pending |
| authorized | Funds reserved by the provider; capture pending (capture_method: manual). | successful · cancelled · failed |
| captured | Transitional state during capture. | successful |
| successful | The provider confirmed the payment. Refundable. | partially_refunded · refunded |
| partially_refunded | One or more refunds cover part of the captured amount. | partially_refunded · refunded |
| refunded | Fully refunded. Terminal. | — |
| failed | Declined, blocked or all eligible providers failed. Terminal, with a failure object. | — |
| cancelled | Cancelled by the merchant before completion. Terminal. | — |
Refunds: created → processing → successful | failed. Payouts: created → pending → processing → successful | failed, cancellable while created or pending. An invalid transition returns 409 invalid_state_transition.
What a failover looks like from the outside.
The timeline is the human-readable record of the engine. This is the sequence produced by a card payment in the sandbox with test_scenario: failover, exactly as returned by GET /v1/payments/{id}/timeline.
- Payment created100.00 USD · card · USpayment.created
- Risk evaluated: ALLOWscore 0 · no rules matchedrisk.evaluated
- Routing rule evaluated: Cards → Acquirer A, fallback Acquirer Bordered strategy · 2 eligible provider(s)routing.evaluated
- NATIO Demo Acquirer A selectedAttempt 1 · account Acquirer A · Test · fee 2.4% + 20provider.selected
- Request sent to providerNATIO Demo Acquirer A · createPaymentprovider.request_sent
- Provider technical errorNATIO Demo Acquirer A · GW-500 Internal gateway errorprovider.error
- Fallback initiatedtechnical error is retryable → next provider NATIO Demo Acquirer Bfailover.initiated
- NATIO Demo Acquirer B selectedAttempt 2 · account Acquirer B · Test · fee 2.9% + 30provider.selected
- Request sent to providerNATIO Demo Acquirer B · createPaymentprovider.request_sent
- Payment successfulNATIO Demo Acquirer B · 83 mspayment.successful
- Webhook queued for merchant1 endpoint(s) subscribed to payment.successfulwebhook.queued
A first line of defence, before routing.
The risk layer scores each payment with your rules before a provider is chosen. It is deliberately simple and transparent; it complements, rather than replaces, a dedicated fraud platform.
Signals
Decisions
Manual review
See the engine on your own traffic.
Create a sandbox account, send payments with test scenarios and read the timeline for each of them.