Routing

Where a payment goes is a policy, not a guess.

Routing rules decide which provider sees each payment, in which order, and what happens when one of them fails. The rules are explicit, evaluated in priority order, and recorded on the payment — you can always answer the question why did this payment go there.

Anatomy of a rule

Scope, conditions, providers, strategy.

A rule applies to a transaction type and a mode, optionally to one merchant or project, and matches when every one of its conditions is true. Rules are evaluated by scope then priority; the first match wins.

country
Country of the payment, as sent on the request.
customer_country
Country attached to the customer object, where you provide one.
currency
ISO 4217 currency of the payment or payout.
merchant_id
Scopes a rule to one merchant account.
project_id
Scopes a rule to one project, for example a single storefront or app.
payment_method
card, bank_transfer, qr, open_banking, wallet, instant or local.
amount
Amount in minor units. Typical use: send high-value traffic to a provider with the right limits.
transaction_type
payment or payout. A payout rule never applies to a payment.
risk_score
The score produced by the risk layer before routing runs.
hour_of_day
UTC hour, 0–23. Used to avoid a provider's maintenance window.
day_of_week
UTC day, 0 (Sunday) to 6. Used for weekend banking coverage.
Operators
eqneqinnot_ingtgteltltebetween
Values are single values or lists. between takes two bounds, in and not_in take a list. Comparisons on text are case-insensitive; comparisons on amounts are numeric, in minor units.
Example

A rule chain reads like the policy it encodes.

Rules are written in the order you want them evaluated. Each one names the providers it can use; the strategy decides how those providers are ordered inside the rule.

  1. 01
    IF country = VN AND currency = VND AND payment_method = qrProvider A

    A local rail served best by a local provider. Ordered strategy, Provider A first.

  2. 02
    IF Provider A unavailable → Provider B

    Expressed as the fallback inside the same rule: if the first candidate is ineligible or its attempt fails in a retryable way, the next candidate is tried.

  3. 03
    IF amount > XProvider C

    High-value traffic to the provider whose limits and settlement terms suit it. Placed at a lower priority number so it is evaluated before the general rules.

The matched rule, the candidates it produced and the reason each candidate was kept or dropped are stored as the routing decision and shown on the payment timeline as routing.evaluated.

Strategies

Three ways to order the candidates.

Eligibility is a filter; the strategy is the ordering. Both are recorded, so a route can be reconstructed after the fact.

01

Ordered

The rule lists provider accounts in priority order. The first eligible one is tried, the next is the fallback. Fully predictable — the default for most rules.
ordered
02

Weighted

Traffic is split across providers by weight, using a deterministic draw seeded by the payment id. The same payment always produces the same order, so retries and replays are reproducible.
weighted
03

Score

Candidates are ranked by a transparent scoring function over cost, approval probability, uptime and latency. The architecture is prepared for an ML-based ranker later: same inputs, same output shape.
score
Smart routing

Scoring you can read, not a black box.

The score strategy ranks eligible providers with a small, inspectable function. Every factor is a number NATIO already has from your own traffic, and every score is stored with the routing decision.

Approval probability
The share of recent attempts on that provider account that ended successfully, for comparable traffic. Below a minimum sample size a neutral default is used instead of a noisy rate.
Processing cost
The account's percentage and fixed fee, expressed in basis points of the payment amount so that fixed fees are comparable across ticket sizes.
Provider uptime
The inverse of the share of technical failures on that account over the recent window.
Latency
Average provider response time over the same window.
Limits and capabilities
Not scored but filtered: method, currency and country support, account status and mode, and configured minimum and maximum amounts.

The function is deliberately simple: the same inputs always produce the same ranking, and the factors are reported alongside the decision. It is the extension point for a learned ranker later — same inputs, same output shape — rather than a model you would have to trust without evidence.

Default weighting
Approval probability
Weight 40 — the largest single contributor, because a declined payment costs more than a slightly more expensive approved one.
Processing cost
Weight 30 — applied as a penalty in basis points of the amount.
Provider uptime
Weight 20 — recent technical reliability of the account.
Latency
Weight 10 — a penalty, so a slow provider loses ties.
Account priority
Tie-break only, so two otherwise identical candidates order deterministically.
Failover

What NATIO does when a provider says no.

Every provider response is normalised into one of a small set of outcomes. The outcome, not the provider's own wording, decides whether the payment moves on to the next candidate.

OutcomeRetry behaviourWhat it means
hard declineNever retriedStolen, lost, expired or invalid instrument, fraud suspected, authentication failed, cancelled by the customer. Another provider would decline the same way; the payment fails immediately.
soft declineMay cascadeInsufficient funds, do-not-honor, issuer unavailable, try again later, limit exceeded. Retried on the next eligible provider when the project's retry policy allows it.
technical errorFails overThe provider returned an error that is not a decision about the payment: gateway errors, malformed responses, authentication problems on the connection.
timeoutVerified, then fails overNo answer within the adapter's deadline. NATIO does not assume anything; it asks the provider what happened before doing anything else.
provider unavailableFails overThe provider or the account is down, disabled or rejecting traffic. The next eligible candidate is tried.
Safety rule

After a timeout, NATIO asks the provider before it fails over.

A timeout is not a failure — it is an absence of information. The engine looks the attempt up at the provider and acts on the answer: if the provider confirms a charge, the payment is recovered as successful and no second attempt is made; only a confirmed absence of a charge allows the next provider to be tried. If the provider cannot answer, the attempt is marked unknown, a status sync is scheduled, and the payment does not fail over blind. A customer is never charged twice because NATIO guessed.

01

Retry policy per project

Maximum attempts per payment, retry on soft decline and retry on timeout are project settings, so a merchant can be as conservative as it wants.
02

Exhaustion is explicit

When no eligible candidate remains the payment fails with a policy failure — no route available or attempts exhausted — rather than the last provider's error code.
03

Everything is on the timeline

provider.error, failover.initiated, provider.selected, payment.successful: the reason for each hop is written down as it happens.

Reproduce every route in the sandbox.

Test scenarios force failover, timeouts, recovered timeouts, provider outages and total failure, so you can see the rules and the safety checks behave before they matter.