Quickstart
Make the routing visible on a live payment, then move one connection and watch it move.
There is nothing to switch on. Orchestration has been ranking your connections since your first live payment, and no request field starts it or stops it. So this quickstart does not add a call to your integration. It makes the ranking visible, then changes it once so you can watch it move.
Five steps. All of them in live mode, and the first one explains why.
Sandbox does not route
A sandbox payment is not routed: it does not use your connections or your rules, no decision is recorded, and Konsole's routing log refuses a sandbox key outright. There is no way to rehearse a routing decision without real money, so use the smallest amount your operator accepts and pay yourself.
1. Connect a second provider
One connection has nothing to fall back to. Wajub still records a routing decision, but the list is one line long and a failure ends the payment.
Add a second in the dashboard under Orchestration, Providers. Both sides have to be live: the provider itself, and your connection to it. An inactive provider or connection is never tried, so a half-finished connection is invisible rather than last.
2. Give them an order
Every connection carries two numbers, both on the provider page under Routing configuration.
| Field | What it decides | Default |
|---|---|---|
priority | The order of the list. Higher first | 0 |
weight (%) | How two connections share traffic when nothing else separates them | 100 |
Priority orders every connection no routing rule names, on a channel with no channel policy. A connection in a lower tier is never tried before every connection above it has been tried and failed, whatever it costs. A matching routing rule and a channel policy come before it, which is why this quickstart uses neither: Orchestration has the full order.
Weight only splits what nothing else separates
Weight shares traffic between connections on the same priority that nothing else separates: on cost and recent success they look the same. On a fresh account no negotiated rates and no recent history separate the connections, so priority, then weight, decides.
Set one connection to 10 and leave the other at 0. That gives you two tiers, which is the
smallest setup where the next steps show something.
3. Send a live payment
A payment is two calls, and this is the part most integrations get wrong: the first call does not route. It creates the transaction, and it accepts no channel and no provider.
https://api.wajub.com/paymentsPass an amount, a currency, and one way to identify the payer among email, phone, customer_id
and customer.
curl https://api.wajub.com/payments \
-H "Authorization: sk.xxxxxxxxxxxxxxxx…" \
-H "Content-Type: application/json" \
-d '{
"amount": 500,
"currency": "XAF",
"phone": "+237670000000",
"description": "Watching the router work"
}'The second call is the one that routes. It names a channel, and everything in Orchestration happens inside it.
https://api.wajub.com/payments/{id}curl https://api.wajub.com/payments/trx_CSUGajfv9xh0XQ5wu2lx \
-H "Authorization: sk.xxxxxxxxxxxxxxxx…" \
-H "Content-Type: application/json" \
-d '{
"channel": "cm.mobile",
"data": { "phone": "+237670000000" }
}'Routing always uses the operator channel. Wajub reads the number, recognises MTN and routes the
payment as cm.mtn, so a connection that declares cm.orange and not cm.mtn is left out.
4. Read the decision
Open the payment in the dashboard. Under the timeline sits Routing decision, and "View routing details" opens the ranked list, in the order the connections were to be tried.
Routing decision · cm.mtn · 500 XAF
Two connections, two tiers. The first one answered, so the second was never called.
- 1

cinetpayaccepted1.2 spriority 10least cost - 2

flutterwavenever calledpriority 0least cost
Both connections carry Least cost, and that is the expected reading on a fresh account: with no negotiated rates entered, they cost the same as far as routing knows, and with no recent history on this channel, neither stands out on recent success. Nothing separates them, no rule matched and the channel has no policy, so priority is doing all the work, which is exactly what you set up in step 2.
The same list lives in the routing log, one row per charge attempt rather than one per payment. That page is live only, for the reason in the first callout.
5. Move one, and watch it move
Swap the two priorities: the connection that was on 0 goes to 10, the other drops to 0. Send a
second payment, identical to the first.
The ladder comes back in the new order. Nothing in your code changed, no deploy happened, and the payment request is byte for byte the one you sent five minutes ago. That is the whole point of the feature, and it is worth doing once with your own eyes before you trust it in production.
What the API will not tell you
The payment object has no provider field. GET /payments/{id} returns the channel that was
charged, never the connection that carried it, and there is no merchant endpoint that returns
priority, weight or a candidate list. Routing is visible in the dashboard and in Konsole, and
nowhere else.
A 422 on channel means the list came back empty
When no connection survives the filters, the payment answers
422 No eligible payment provider found for this transaction. on the channel key and the
transaction goes back to pending. It is an account configuration problem, not a payer problem:
the channel, the currency or connections paused on the channel left no connection to try.
Related pages
- Payment OrchestrationWhich connections qualify, then rules, channel policy and priority, in that order.
- Routing RulesSend a country, channel, currency or amount range to one connection first.
- Waterfall & FallbackWhat walks down the list, and what stops it for good.
- Accept a paymentThe full two-call flow, hosted page included.