Gateway Routing
The checkout does not let the user choose which gateway to use. The platform selects it automatically from the tenant's configured gateways, picking the first one (in priority order) whose supported currencies include the cart's currency.
If no configured gateway supports the cart's currency, the checkout fails hard. There is no silent fallback.
How selection works
Each gateways row belongs to a tenant and carries:
- a
type(stripe,mercadopago,yuno,payu) - a
supported_currenciesJSON array (uppercase ISO codes, e.g.["ARS", "USD"]) - an
orderinteger used for sorting (lowest first, highest priority) retail_enabled/subscription_enabledflags- a derived
is_configuredflag (used as a routing filter to exclude gateways with missing or invalid settings)
Selection runs against pre-generated payment_links rather than directly against supported_currencies. For each tenant gateway, one link is materialized per (gateway × supported_currencies entry × plan), but only when a non-zero price is configured for that combination. At checkout, the platform keeps the links whose currency_id matches the cart currency and picks the one belonging to the gateway with the lowest order value.
The currency match is exact. A gateway configured for ARS will not match a CLP cart.
A gateway whose supported_currencies contains the cart currency but lacks a configured price for that (gateway, currency, plan) combination is silently skipped: no payment_link exists, so the next priority gateway is tried. This is the routing-side reason a plan may end up on a lower-priority gateway than expected.
Yuno is additionally gated by the yuno_checkout_enabled feature flag on the tenant: when the flag is off, the Yuno row is treated as unconfigured and excluded from routing regardless of supported_currencies.
retail_enabled and subscription_enabled gate which plan types each gateway can serve. A gateway with subscription_enabled = false will not be offered for a recurring plan even if its currency matches.
PlanGatewayMeta is not the routing source
A common mistake is to assume plans_gateways_meta drives gateway selection. It does not.
plans_gateways_meta stores plan-specific metadata per gateway: remote plan identifiers (Stripe plan id, MercadoPago preapproval plan id) and plan-level prices. The metadata is reused across purchases of the same plan to avoid creating duplicate remote plans at the gateway.
Gateway selection itself reads the gateway's supported_currencies and order columns. When debugging "wrong gateway selected for this cart", look at the gateways table, not plans_gateways_meta.
Gateway constraints
Not all gateways can be used everywhere. Two hard constraints apply regardless of priority or currency:
Refundable gateways: only Stripe, MercadoPago, and Yuno support refunds. PayU and Manual orders have no refund path. See Refund Flow.
Reader and gift flows: PayU and Yuno cannot be used when purchasing directly from the reader or as a gift. For Yuno, the underlying reason is technical (the checkout SDK must be loaded in the page layout, and the reader does not load it). For PayU, it is a legacy limitation.
These constraints are enforced as hard gates, not as UI-level hints.
Non-payment gateway types
The gateway_type column also carries values that are not payment gateways: manual, bulk, external, lti, saml, and totalDiscountCoupon. These do not go through gateway selection logic. See Gateway References and Manual, Bulk, and External Orders.