Skip to content

Routing Rules

What a rule can match, which rule wins when several do, and where it cannot help.

A routing rule names one of your connections for the payments that look a certain way. When a payment matches, that connection is tried first, before every connection no rule named and whatever the priority on either, with the rule's fallback provider right behind it. The channel's policy or the connection priority then orders the rest, as described in Orchestration.

A rule is not an ordered list of providers. It places one connection, two with its fallback, at the top of the ranked candidate list. Everything below them is the list Wajub would have built anyway.

Growth and above, live only

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

What a rule can match

A rule has conditions, one target, an optional fallback, and two numbers of its own. Every condition is optional, and a rule only matches a payment that meets every condition it sets. The names below are the fields of the rule form in the Dashboard.

Payment channelchanneloptional
An exact operator channel, the one payments are routed on: cm.mtn, sn.wave, card. Empty matches every channel.
CurrencyISO codeoptional
ISO code, in any case. 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.
Countrytwo lettersoptional
Redundant on a rule whose channel is an operator channel: cm.mtn already means Cameroon. It narrows a rule with no channel, or a rule on a channel without a country such as card, where it is compared with the payer's detected country. See below.
Route To Providerconnectionrequired
The one connection this rule places. It has to be a provider you are already connected to, active, in live mode.
Fallback Providerconnectionoptional
The connection tried after the target when the rule matches, or in its place when the target cannot be tried. Optional, and different from the target. See The fallback provider, below.
Priorityintegerrequireddefault : 0
Decides between matching rules: the higher one places its connection first. This is the rule's own priority and has nothing to do with the priority on your connection.
Weight (%)integer, 0 to 100optionaldefault : 100
Shares traffic between matching rules that are otherwise tied, on every payment. A rule at 0 never goes first while another one has some weight.
Activeon or offoptionaldefault : on
Inactive and deleted rules never match.

Advanced conditions

The Advanced conditions section of the rule form adds four more. Each one, when set, has to hold too.

ConditionMatches when
Time windowsThe payment happens inside one of the windows: days of the week, a start and an end time, read in the window's own timezone. A window that ends before it starts crosses midnight, so 22:00 to 04:00 runs through the night. The hours after midnight count on the next day, so tick that day too
Customer segmentsThe payer is in any of the segments picked. VIP: a customer tagged vip. Blacklist: a customer you blocked, or tagged blacklist. First transaction: no earlier successful payment to you. Returning: at least one. A payment with no customer matches neither of the last two
Metadata filtersEvery filter holds against the metadata you sent on the payment. The key can be a dot path, such as device.type. A key missing from the payment's metadata fails the filter, except an eq filter saved with an empty value, which matches only the payments without that key
Frequency capsNone of the rule's caps is reached. See Frequency caps

Customer tags are the tags on the customer, set from the API or the Dashboard. Metadata filters compare eq and in by the text of the value, so 100 typed in the form matches 100 sent as a number or as a string, and true matches the boolean. in takes several values separated by commas, such as web, app, and holds when the metadata equals one of them. contains looks for the text inside a string, and gt, gte, lt and lte compare numbers. A list or an object in your metadata only matches an identical value.

Frequency caps

A cap stops the rule matching once it has counted enough payments in its window. The rule matches again when the window rolls over.

FieldWhat it sets
Windowper minute, per hour or per day. Calendar windows in UTC: this minute, this hour, this day
maxHow many payments the window counts before the rule stops matching
ScopeRule: the payments this rule routed, to its target or to its fallback. Provider: every payment your account sent to the rule's target, whatever routed it

What counts is a payment a provider took: succeeded, pending, or waiting for the payer. A payment refused on the way counts nothing.

Which rule wins

Every active rule of yours is evaluated on every live payment, and every rule that matches places its target. They are taken in this order.

  1. The higher rule Priority first.
  2. At equal priority, the more specific rule.
  3. Rules still tied share traffic by Weight, on every payment. Weights of 70 and 30 put the first rule's target first on roughly seven payments in ten.

Each rule places its target, then its fallback, then the next rule does the same.

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. CinetPay is placed first by the rule. Flutterwave comes after it, ordered with every connection no rule named, and being cheaper with a better recent success rate does not change that.

Routing decision · cm.mtn · 12 000 XAF

One rule, two connections. The rule's target goes first, whatever the cost or the recent success.

  1. 1
    cinetpay
    accepted1.1 s
    priority 0rule match
  2. 2
    flutterwave
    never called
    priority 0least costrecent success

That is the point. Once a rule matches, nothing else outvotes it: not the priority on your connections, not their cost, not their live success rate. Write rules for cases where you know better than the numbers, and leave the rest to the numbers.

Splitting traffic

By amount. One rule per bracket, each with its own amount range and its own connection. A payment falls in one bracket, so only one of them matches.

By share. Two rules with the same conditions and the same priority, each pointing at a different connection, with weights of 70 and 30. The Routing Rules page warns about rules whose conditions overlap, except two at the same priority that both have a weight under 100 and different targets, which it reads as an intended split.

The fallback provider

A rule can name a second connection, the one you want tried when its target fails. When the rule matches a payment, the fallback is placed in one of two ways.

The target can be tried. The fallback comes right behind it, and it is the next connection tried if the target fails on the provider's side.

The target cannot be tried at all. It is paused on this channel after repeated failures, it does not carry the channel or the currency, or the connection is no longer active. The fallback then takes the target's place, as if the rule had named it.

A fallback is itself a connection like any other. If it cannot carry the payment either, the rule places nothing. In the routing log, a connection placed this way shows a Fallback badge.

Where a rule cannot help

Four things make a rule inert, and all four are worth checking before you conclude the rule was ignored.

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, except a rule with a fallback: the fallback then stands in for it.

The channel has to be an operator channel. Routing always uses the operator channel: cm.mobile with an MTN number is routed as cm.mtn, so write the rule against cm.mtn. 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 capped rule sits out until its window rolls over. Once a frequency cap is reached, the rule stops matching, and the payments it would have placed follow the general order.

A card stays with the provider that holds it. A card the payer entered in a provider's own fields can only be charged by that provider, so a rule pointing elsewhere does not move it. See Waterfall & fallback.

The country comes from the channel

On an operator rail the country comes from the channel: cm.mtn means Cameroon, whatever case you typed the rule's Country in. A rule on cm.mtn is already a rule about Cameroon. On a channel without a country, such as card, Wajub uses the country it detected for the payer when they opened the checkout, if there is one.

A rule that has an effect

The shape worth copying is narrow on the channel, explicit on the currency, and pointed at the connection you want for that case.

Say MTN Cameroon is your biggest rail, three connections can carry it, and one of them gives you the best acceptance for amounts under 100 000 XAF. Write one rule.

FieldValue
Payment channelcm.mtn
CurrencyXAF
Max Amount100000
Route To Provideryour preferred connection
Priority0

Under 100 000 XAF, that connection is tried first, whatever its priority. Above, the rule stops matching and the three connections are ordered by the channel's policy, or by their priority, cost and recent success, 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 Routing Rules page

The Routing simulator on the Routing Rules page runs a routing decision without charging anything. Give it a channel, a currency and an amount, and it answers with the order your connections would be tried in, the reason for each place (a rule, a rule's fallback, the channel policy or the connection priority), any guardrail that pushed a connection back, and the connections it left out, with why. Nothing is charged and nothing is written.

A connection is left out for one of these reasons:

ReasonWhy the connection is left out
provider_in_maintenanceWajub put the provider in Maintenance
provider_unavailableThe provider is Coming soon or Disabled
channel_not_servedThe provider cannot carry the channel, or your connection does not enable it
currency_not_supportedYour connection is limited to other currencies
no_driverWajub cannot charge through this provider yet
circuit_openThe connection is paused on this channel after repeated failures

It sends no customer and no metadata, so a rule with a customer segment or a metadata filter never matches there. It sends no country either: the country only comes from a channel slug that starts with one, so on card a rule with a Country never matches there, though it can on a real payment. Time windows are read at the current time and frequency caps at their current counts. Where weight shares traffic, two runs can differ. Like the rules themselves, the simulator needs a Growth plan or above.

The rule form also previews its impact before you save. It counts your live payments of the last 7 days that match the rule's channel, currency, country (read from the channel the payment was charged on) and amount range, and lists the connections that carried them and would now lose them to the one the rule points at. It ignores the advanced conditions, and it assumes the rule wins every time, so it is the ceiling of what the rule can move, not a forecast.

What did you think of this content?