guides
Routing & fallback
Rules are evaluated in priority order (lower number first); the first matching rule supplies an ordered PSP chain — primary first, fallbacks after. With no matching rule, every eligible enabled connection is used in the order it was added.
Creating rules
POST /v1/routing_rules
{
"name": "EUR cards → Adyen first",
"priority": 10,
"conditions": {
"payment_method_types": ["card"],
"currencies": ["EUR"],
"amount_gte": 1000
},
"psp_order": ["psp_adyen…", "psp_stripe…"]
}
Conditions are ANDed; absent fields match anything. Manage rules from the dashboard's rule builder or via GET / PATCH / DELETE /v1/routing_rules.
Fallback semantics
- Falls back: technical failures where the PSP definitively did not receive the charge — connection refused, DNS failures, misconfigured credentials (401/403), rate limiting. The next connection in the chain is tried with a fresh attempt.
- Never falls back — declines:
insufficient_fundsfrom one PSP means the issuer said no — retrying it elsewhere invites fraud flags and duplicate charges. - Never falls back — ambiguous failures: a timeout after the request was sent, a PSP 5xx, or a connection lost mid-flight means the charge may exist at the PSP. Retrying on another provider could charge your customer twice, so the payment is held in
processingwith the failed attempt recorded; the PSP's webhook (or reconciliation) settles the true outcome. - Skipped up front: disabled connections (manual kill switch) and connections whose health checks are failing.
Explainability
Every attempt records its routing decision — strategy, matched rule id, position in the chain, and a fallback flag. You'll find it in API responses under attempts[].routing and visually on the payment timeline in the dashboard.
"attempts": [
{ "provider": "adyen", "status": "failed", "error_code": "psp_unavailable" },
{ "provider": "stripe", "status": "captured", "routing": { "fallback": true } }
]