Skip to main content
A condition matches against an attribute of the incoming payment.
Conditions inside the same condition_sets[].conditions[] are combined with logical AND. For OR semantics, split into multiple condition sets ordered by sort_number.

condition_type catalog

CURRENCY and INSTALLMENTS are not valid standalone condition_type values. Sending either one rejects the whole routing with 400 INVALID_ROUTE_CONFIGURATION. To filter by currency, use AMOUNT with the sibling currency field — with an amount comparison, or with an empty values list to match the currency alone.

conditional operators

There is no NOT_BETWEEN operator. It is not a member of the conditional enum, so sending it rejects the whole routing at deserialization — use BETWEEN on the complementary ranges instead.
LESS_OR_EQUAL_THAN is the operator of VOLUME_PAYMENTS_LIMIT and is not meant for the other types in the table: the limit condition carries its own threshold semantics (the account total over a period, see below) rather than a generic comparison of one attribute. CONTAINS is a substring test for METADATA. For ADDITIONAL_FIELD it compares for equality against the values the field resolves to: on a multi-valued field, such as order_fee_item_sku_code, it matches when any item equals values[0], which is how you test “the order contains this SKU”. The Rejected at save time column is the value count only. A yes means POST/PUT returns 400 when the count does not match, naming the condition type and operator. A no means the count is not checked at save time, and what a wrong count does at evaluation depends on the operator — do not rely on it being harmless. TIME_PERIOD (one or two values) and VOLUME_PAYMENTS_LIMIT (exactly one) are always checked, whatever the operator. Where enforcement applies it is exact, not a minimum: a surplus value is rejected just as a missing one is. BETWEEN with ["0", "60", "EUR"] is a 400, not a silently truncated range.
A value count already stored on a routing version is kept. If a version holds a condition whose count predates this check, saving that version again does not fail on it — only a newly introduced wrong count is rejected. This also holds for a version duplicated from such a source.

Card brands

CARD_BRAND accepts the values below. A value outside the list is rejected at save time with 400 INVALID_CARD_BRAND, naming the offending value. The list is validated against two internal sources at save time, so a newly supported scheme may be accepted before it appears here.
These values do not exist in the list above, so a rule carrying one never matches a payment:AMEX, UNIONPAY and CB appeared in earlier versions of this page. The others are values that have been sent against the API and accepted before save-time validation existed.Existing rules holding any of these are not rejected on a later save — they are kept as they are — but they will never match a payment, so correct them.

Schedules: TIME_PERIOD

TIME_PERIOD matches when the payment is created inside a schedule. values[0] is when the schedule starts, the optional values[1] is when it ends, and the recurrence fields narrow it down:
This set matches payments created on weekdays between 09:00 and 18:00 (UTC−3), from October 1st, 2026 onwards.
Without recurrence fields the condition is a plain date range: it matches every payment between the start and the end. With a frequency, a payment matches when the whole units elapsed since the start are a multiple of time_period_repeat_amount, its weekday is in time_period_repetition_days (when set) and its time is inside the window (when set). YEARLY additionally requires the same month and day as the start. Rules checked at save time, each a 400 naming the field: a value that is not an ISO-8601 date-time with offset, three or more values, a frequency without an amount or the reverse, a zero amount, a start time after the end time, a start date after the end date, one end of the time window without the other, repetition days or a time window without a frequency, a timezone that is not an offset, and limit_by or payments_count on a schedule. A value outside an enum or a zero amount is caught at the API edge as INVALID_PARAMETERS; the rest is INVALID_ROUTE_CONFIGURATION.

Volume and count limits: VOLUME_PAYMENTS_LIMIT

VOLUME_PAYMENTS_LIMIT matches while the account stays under a limit over a period, counting the payment being routed. Use it to send the first N payments, or the first X of volume, of a day or a month through one route and the rest elsewhere:
This set matches while the account’s payments of the current calendar month, in USD and including the current one, add up to 50,000 or less.
Rules checked at save time: exactly one numeric value greater than zero; no time_period_repetition_days, time_period_start_time or time_period_end_time; a valid currency when limit_by is VOLUME (400 INVALID_VOLUME_LIMIT_CURRENCY); a supported period (400 INVALID_VOLUME_LIMIT_PERIOD); a whole-hour timezone (400 UNSUPPORTED_VOLUME_LIMIT_TIMEZONE).
Place the limit set before the route that should take the overflow. Once the limit is reached the set stops matching, so the following sets and the default_route receive the remaining payments of the period.

Additional fields: ADDITIONAL_FIELD

ADDITIONAL_FIELD matches a field of the payment request that has no condition type of its own. key names the field and is validated at save time; an unknown key is rejected with 400 INVALID_ROUTE_CONFIGURATION.
All values are compared as strings; email is compared case-insensitively. On a multi-valued field (order items, airline legs, passengers) every item must satisfy the operator, except CONTAINS, which matches when any item equals values[0]. A field absent from the payment never matches, with one exception: the numeric keys (installments, the amounts and quantities) resolve to the string "null" when absent, so a NOT_EQUAL or NOT_ONE_OF on them matches payments that do not carry the field.

Special cases

  • AMOUNT requires currency. Comparisons are FX-naive; only payments whose currency matches the rule’s currency are evaluated.
  • AMOUNT with an empty values list is a currency-only condition: { "condition_type": "AMOUNT", "conditional": "EQUAL", "values": [], "currency": "BRL" } matches every payment in BRL, whatever the amount. Only EQUAL is accepted in that form; another operator is rejected with 400 INVALID_ROUTE_CONFIGURATION. Responses return it in this same shape.
  • METADATA requires key. Compares payment.metadata[key]. If the key is absent on the payment (or the payment has no metadata), the condition does not match, whatever the operator. This includes the negative operators: a payment without the key does not match NOT_EQUAL or NOT_ONE_OF either. See the note below for how to route payments that don’t carry the key.
  • ADDITIONAL_FIELD requires key from the supported list; METADATA keys are free-form, ADDITIONAL_FIELD keys are not.
  • Card-only condition types (CARD_ISSUER_COUNTRY, CARD_TYPE, CARD_BRAND, CARD_BIN) are only valid when payment_method = "CARD".
  • COUNTRY vs CARD_ISSUER_COUNTRY. The two are sourced independently: COUNTRY matches the transaction country your backend submits in the payment request, while CARD_ISSUER_COUNTRY matches the issuer country Yuno’s own BIN lookup derives from the card number. The same payment can be COUNTRY = US and CARD_ISSUER_COUNTRY = GB at once. The BIN lookup runs before a provider is selected, is identical in sandbox and production, and reflects real-world BIN-registry data — never the processor’s view of the card.
  • Not to be confused with Communications Campaigns. That product has its own rule engine, where AMOUNT_AND_CURRENCY with BETWEEN takes three values ["min", "max", "currency"]. Routing’s AMOUNT takes two values plus a sibling currency, and a third value is rejected.
  • CARD_BIN with BETWEEN expresses an issuer range and is validated more strictly than the generic two-value rule: exactly two values, both the same length, that length either 6 or 8, all digits, and the first less than or equal to the second. Anything else is 400 INVALID_ROUTE_CONFIGURATION — so ["411111", "41111111"] (mismatched lengths) and ["500000", "400000"] (descending) are both rejected. Unlike every other condition type, a stored CARD_BIN BETWEEN is not grandfathered: a version holding a malformed one is rejected on every subsequent save until it is corrected.
  • Schedule and limit fields belong to TIME_PERIOD and VOLUME_PAYMENTS_LIMIT only. Any of them on another condition_type is rejected with 400 INVALID_ROUTE_CONFIGURATION.
  • Numeric values are submitted as strings to match the values: string[] schema. Yuno parses them based on the condition_type.
Routing payments that don’t carry a metadata keyBecause a missing key never matches, a rule such as METADATA QA NOT_EQUAL "true" skips every payment that has no QA key. To split traffic by the presence of a key, match the payments that do carry it, and let everything else fall through:
  1. Put a condition set with METADATA QA EQUAL "true" first (lower sort_number).
  2. Put the condition set for all other payments after it, without a METADATA condition on QA.
Payments with QA = "true" match the first set; payments without the key, or with any other value, reach the second.

Testing CARD_ISSUER_COUNTRY rules in sandbox

Provider test-card countries are simulator metadataThe “country” a payment provider documents for its test cards exists only inside that provider’s own test environment — it is simulator metadata attached to the PAN, not a property of the number itself. Yuno’s BIN lookup resolves the real-world registry entry instead, so a test card’s documented country and its resolved card_data.country_code in Yuno usually differ.
Two examples with Stripe’s test cards: To verify a CARD_ISSUER_COUNTRY rule end-to-end today, work with resolved values rather than documented ones — the lookup is deterministic:
  1. Run one sandbox payment with a candidate test card.
  2. Read card_data.country_code from the payment (payment details in the dashboard, or the Retrieve Payment response).
  3. Build the rule against that value. For example, 4242 4242 4242 4242 is a dependable GB card end-to-end.
The same caveat applies to every BIN-derived condition (CARD_TYPE, CARD_BRAND), though country is where provider test-card documentation diverges most often.