Dispatching
Dispatching allows distributing requests across multiple gateways configured on the merchant.
The dispatching block is defined within a rule and contains the following fields:
list— a list of gateway aliases from the merchant’s settings, among which requests are distributed.method— the distribution algorithm:"queue","limit"or"conversion".rate— the measurement window, for"conversion"only.accepted_only— score only the attempts where a requisite was issued, for"conversion"only.min_conversion— the minimum conversion of a gateway, in percent, below which the gateway is not considered, for"conversion"only.
{ "list": ["TEST1", "TEST2", "TEST3"], "method": "queue" | "limit" | "conversion"}Rule setup
Section titled “Rule setup”Dispatching requires one rule per gateway in the list. All rules must belong to the same setting, and that setting must include every gateway in use. Each rule specifies a unique acq_alias corresponding to its gateway.
For a setting with three gateways (TEST1, TEST2, TEST3), three rules are required:
Rule 1 — TEST1
{ "header": { "mid": "81", "acq_alias": "TEST1" }, "body": { "status": { "sum": { "1#approved#amount": [0, 2000000] } } }, "routing": null, "action": null, "dispatching": { "list": ["TEST1", "TEST2", "TEST3"], "method": "queue" }}Rule 2 — TEST2
{ "header": { "mid": "81", "acq_alias": "TEST2" }, "body": { "status": { "sum": { "1#approved#amount": [0, 2000000] } } }, "routing": null, "action": null, "dispatching": { "list": ["TEST1", "TEST2", "TEST3"], "method": "queue" }}Rule 3 — TEST3
{ "header": { "mid": "81", "acq_alias": "TEST3" }, "body": { "status": { "sum": { "1#approved#amount": [0, 2000000] } } }, "routing": null, "action": null, "dispatching": { "list": ["TEST1", "TEST2", "TEST3"], "method": "queue" }}Method queue
Section titled “Method queue”Iterates through the gateways in list in order. The first request goes to TEST1, the second to TEST2, the third to TEST3, the fourth back to TEST1, and so on in a round-robin fashion.
Method limit
Section titled “Method limit”Each request is routed to the gateway with the lowest current counter. Once a gateway’s counter reaches its limit, that gateway is excluded from selection and receives no further requests.
Method conversion
Section titled “Method conversion”Each request is routed to the gateway converting best right now. Every gateway in list is scored over the same sliding window and the highest one takes the payment.
{ "header": { "mid": 81, "acq_alias": "TEST1", "currency": "INR" }, "body": {}, "routing": null, "action": null, "dispatching": { "list": ["TEST1", "TEST2", "TEST3"], "method": "conversion", "rate": "1d#approved" }}The rate field is [window][s|h|d|w|m|y]#[success_value] — 30s#approved, 12h#approved, 3d#approved, 2w#approved. A bare number means days, and it defaults to 1d#approved.
Unlike the count and sum counters this window slides with every request instead of being flushed at a timezone midnight, so a timezone suffix is accepted but ignored.
Scoring
Section titled “Scoring”A gateway that has settled nothing has no conversion rate, and one that has settled a single transaction has a rate of 0% or 100% — neither is something to route on. So scores are calculated with:
score = (approved + 1) / (settled + 2)A gateway with no history sits at 50%, ahead of a poor performer and behind a good one. This solves the case where a gateway converting at a terrible 10% takes every payment and gives the others no chance to prove themselves.
Equal scores fall back to the order the gateways are listed in.
What is counted
Section titled “What is counted”Conversion is measured per attempt, not per transaction, so a cascaded payment is scored against every gateway that handled it, not just the one that finished it.
| What the gateway did | Default | With accepted_only |
|---|---|---|
| Gave a requisite, payment approved | a conversion | a conversion |
| Gave a requisite, payment declined or expired later | a failed conversion | a failed conversion |
| Declined up front, no requisite | a failed conversion | nothing at all |
Each gateway is measured within the group named by the header keys holding a plain value — mid and currency in the example above, so conversion is per merchant and per currency rather than platform-wide. Header keys holding an array or an operator object ({"range": [...]}, {"gte": ...}) select the rule but do not split the group.
accepted_only
Section titled “accepted_only”Off by default. Turn it on to score a gateway only on the payments where it issued a requisite: a gateway that declines before issuing one does not lose conversion.
"dispatching": { "method": "conversion", "list": ["TEST1", "TEST2", "TEST3"], "rate": "1d#approved", "accepted_only": true}min_conversion
Section titled “min_conversion”Off by default. Sets a conversion threshold in percent: gateways scoring below it are left out of the choice, and the payment goes to the best of the rest. A gateway scoring exactly at the threshold stays in.
"dispatching": { "method": "conversion", "list": ["TEST1", "TEST2", "TEST3"], "rate": "1d#approved", "min_conversion": 30}If every gateway is below the threshold, the payment is declined right away, without calling any gateway. For example, with "min_conversion": 30 and a best score of 29%, the merchant gets a decline with the reason antifraud: Conversion of every alias is below 30%.
Such a decline is stored as an attempt of the gateway the payment came in on, but it is not counted in that gateway’s conversion: the gateway never got the payment. Otherwise every declined payment would add a fresh failed attempt, and the gateway could never climb back above the threshold.
The value is a number, or a string holding a number, from 0 to 100. An invalid value ("abc", 150) is ignored and no threshold applies.
Cascading on an instant decline
Section titled “Cascading on an instant decline”If the chosen gateway declines synchronously, before any requisite reaches the merchant, the payment can be handed to the next gateway in the ranking instead of ending in a decline. The trigger is set in the rule body:
{ "header": { "mid": 81, "acq_alias": "TEST1" }, "body": { "status": { "not_in": ["declined"] } }, "routing": { "status:not_in": { "dispatching": true } }, "action": null, "dispatching": { "list": ["TEST1", "TEST2", "TEST3"], "method": "conversion", "rate": "1d#approved" }}{ "dispatching": true } picks the best converting gateway among those the payment has not already been through. If min_conversion is set, gateways below the threshold are skipped; when no eligible gateway is left, the payment ends with the gateway’s own decline.
This replaces the one-rule-per-hop chain a static routing target needs: the order is decided by conversion at the moment of the decline rather than written into the rules.
