Skip to content

Routing Rules

What a rule can pin down, what its match is worth, and where it cannot help.

A routing rule is one addition. It says that when a payment looks a certain way, one of your connections gets points, and those points only compete against the other connections sitting in the same priority tier. That is the whole mechanism.

A rule is not an ordered list of providers, and it does not build a fallback chain. The chain is the ranked candidate list described in Orchestration, and a rule can only change who goes first inside one tier of it.

Growth and above, live only

Routing rules are a paid feature. On Pay as you go the Orchestration, Rules page is replaced by an upgrade prompt, and the whole Orchestration section is live only by route middleware. Everything on this page assumes a live key and a Growth, Scale or Enterprise plan.

What the router reads

A rule has four conditions, one target, and one number of its own. Every field is optional except the target.

channelstringoptional
An exact channel slug, the same one the router works on: cm.mtn, sn.wave, card. Empty matches every channel.
currencystringoptional
ISO code, stored uppercase. Empty matches every currency.
min_amount / max_amountamountoptional
Inclusive bounds in the currency you entered, in major units like the payment itself. Either side can be left open.
country_codestringoptional
Two letters. Redundant with the channel on every operator rail, and it does not currently narrow anything. See below.
provider_idstringrequired
The one connection this rule boosts. It has to be a provider you are already connected to, active, in live mode.
priorityintegerrequireddefault : 0
Added on top of the match. This is the rule's own priority and has nothing to do with the priority on your connection.
is_activebooleanoptionaldefault : true
Inactive rules are not loaded at all.

Every active rule of yours is evaluated on every live payment. There is no ordering to maintain and no first-match-wins: rules that match all contribute, each to its own target.

What a match is worth

The score is built from the number of conditions the rule actually pins down. A vague rule is worth less than a precise one, on purpose.

Part of the matchPoints
The rule matched at all1000
It pins a channel500
It pins a currency500
It pins an amount range, either side500
It pins a country500
The rule's own priorityIts value, added as is

Take an account with CinetPay and Flutterwave both connected, both at priority 0, both able to carry cm.mtn in XAF, and one rule pinning cm.mtn and XAF to CinetPay with a rule priority of 0. CinetPay scores 1000 for the match plus 500 for the channel plus 500 for the currency, so 2000. Flutterwave has no rule, and on a fresh account it picks up at most the least-cost boost and the telemetry boost.

Routing decision · cm.mtn · 12 000 XAF

One rule, two connections in the same tier. 2000 against 250 is not close.

  1. 1
    cinetpay
    accepted1.1 s
    priority 0 · score 2000rule +2000
  2. 2
    flutterwave
    never called
    priority 0 · score 250least cost +200success 91 % +50

That gap is the point. A rule is worth between 1000 and 3000 while cost is worth 200 and live success rate is worth 50 at best, so once a rule matches, nothing else in the score can outvote it. Write rules for cases where you know better than the numbers, and leave the rest to the numbers.

Two rules on the same connection

Only the highest-scoring rule survives per target. If a broad rule pinning just cm.mtn and a narrow one pinning cm.mtn, XAF and an amount ceiling both point at CinetPay, CinetPay is scored once, at 2500, and the broad rule contributes nothing extra. Stacking rules on one connection never compounds.

Two rules on different connections

Both count, each on its own target, and the higher total goes first. This is how you split traffic by amount: one rule per bracket, each pointing at a different connection.

Where a rule cannot help

Three things silently make a rule inert, and all three are worth checking before you conclude the engine ignored you.

A rule never crosses a priority tier. Candidates are grouped by the priority on your connection and the top group is exhausted before the next is touched. A 3000-point rule pointing at a connection in a lower tier changes nothing at all: the higher tier is still tried first, and if one of them accepts, your rule's target is never called. If a rule looks ignored, look at the connection's priority first.

The target has to be a connection you hold. The form only lets you pick from providers already connected to your account, active, in live mode. A connection you later pause takes its rules out of play with it.

The channel has to be a slug the router actually sees. By the time candidates are ranked, the channel is a resolved operator slug. A rule written against a product word like mobile_money, bank_transfer or mobile matches nothing, because no payment is ever routed on those strings.

A rule that has an effect

The shape worth copying is narrow on the channel, explicit on the currency, and pointed at a connection that already sits in the tier where the decision happens.

Say MTN Cameroon is your biggest rail, you have three connections that can carry it, and one of them gives you the best acceptance for amounts under 100 000 XAF. Put all three at the same priority so they compete, then write one rule.

FieldValue
channelcm.mtn
currencyXAF
max_amount100000
provider_idyour preferred connection
priority0

That rule scores 2500. Above 100 000 XAF it stops matching, the boost disappears, and the three connections fall back to competing on cost and on live success rate, which is usually what you want for the amounts you care most about.

Amount bounds are entered in major units, the same units as the payment. 100000 means 100 000 XAF, not 1 000 XAF.

The simulator on the Rules page

The Rules page has a simulator that takes a channel, a currency and an amount, and shows which of your rules match. It is useful for one thing: checking that the conditions you typed select the rules you meant.

It is not the router. It reads your rules directly and does not reproduce the connection priority tiers, the least-cost boost, the live success rate boost, or the circuit breaker, and it compares the country condition case-insensitively where the engine does not. A provider can come first in the simulator and never be called on a real payment. For the real answer, send a live payment and read the routing log.

Fields the form stores but the router ignores

The rule form carries more than the engine consumes. These are written to your rule, visible when you reopen it, and read by nothing on the payment path.

FieldWhat happens
fallback_provider_idStored. The fallback order comes from the candidate list, never from a rule
weightStored. Traffic splitting uses the weight on the connection, not on the rule
Time windowsStored, never evaluated
Customer segmentsStored, never evaluated
Metadata filtersStored, never evaluated
Frequency capsStored, never evaluated

Everything the router reads is in the first table on this page. If a behaviour you expect is not explained by those fields, it is not coming from your rules.

What did you think of this content?