Motor de recomendaciones
Esta guía documenta la API orientada al comerciante para administrar reglas en el motor de recomendación DEUNA. Una regla combina condiciones con una lista ordenada de proveedores de pago, fraude o autenticación y reglas secundarias ponderadas opcionales para pruebas A/B. Las reglas se evalúan por prioridad hasta que una coincida.
En esta página
Motor de recomendación
Define la ruta ordenada de proveedores evaluada para una regla coincidente.
Autenticación#
Todos los puntos finales se autentican con un Clave API enviado en el X-Api-Key encabezado: este es el único esquema de autenticación admitido. Su comerciante se resuelve desde la clave API, por lo que el identificador de comerciante no no aparecen en la URL.
X-Api-Key: {{DEUNA's API Key}}
X-Idempotency-Key: {{UUID v4}}
Content-Type: application/json| encabezado | Requerido | Descripción |
|---|---|---|
X-Api-Key | Sí | Su clave API. Determina el entorno y el ámbito comercial. |
Content-Type | Sí | application/json. |
X-Idempotency-Key | Recomendado | Una clave única que genera por solicitud lógica (un UUID funciona bien). Reintentar con la misma clave devuelve el resultado original en lugar de aplicar la operación dos veces; envíela para que los reintentos de la red nunca creen reglas duplicadas ni cuenten dos veces una acción. |
Resumen de puntos finales#
| Método | Ruta | Propósito |
|---|---|---|
GET | /routing/v1/rules | Listar todas las reglas (orden de prioridad) |
POST | /routing/v1/rules | Crear una regla |
GET | /routing/v1/rules/{rule_id} | Get a single rule by ID |
PUT | /routing/v1/rules/{rule_id} | Actualizar una regla (reemplazo completo) |
PUT | /routing/v1/rules/{rule_id}/reorder | Cambiar la prioridad de una regla |
Parámetros de ruta:
| Parámetro | Tipo | Notas |
|---|---|---|
rule_id | integer | Identificador de regla numérico devuelto por create/list. |
El objeto de regla#
Una regla es el recurso principal devuelto y aceptado por estos puntos finales.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
id | integer | Sólo respuesta | Identificador de regla asignado por el servidor. |
label | string | Sí | Nombre de regla legible por humanos. |
data_type | string | Sí | Familia de métodos a los que se aplica esta regla: credit_card, debit_card, prepaid_card. |
priority | integer | Sí | Orden de evaluación — Las carreras más bajas primero, el primer partido gana. (números no negativos) |
status | Enumeración | Sí | enabled, disabled, draft |
is_default | boolean | Sí | si true, esta es la regla alternativa cuando no hay otras coincidencias. Una regla predeterminada debe tener no condiciones y no debe establecer ignore_next_rules. |
trigger | Enumeración | Sí | payment, rejecto merchant_rule. Ver Desencadenantes. |
conditions | array<Condition> | Condicional | Criterios de coincidencia, Y combinado. Requerido a menos que is_default = true. |
members | array<Member> | Condicional | Ordenó a los proveedores que lo intentaran. Requerido para payment; requerido (o children) para merchant_rule; prohibido para reject. |
children | array<Child> | Opcional | Ramas secundarias ponderadas para pruebas A/B (solo con trigger = merchant_rule). |
ignore_next_rules | boolean | Sí | si true, deje de evaluar más reglas una vez que ésta coincida. Prohibido para reject y para reglas predeterminadas. |
created_at | cadena (RFC3339) | Sólo respuesta | Marca de tiempo de creación. |
Desencadenantes
trigger | Significado | members | children | ignore_next_rules | is_default |
|---|---|---|---|---|---|
payment | Enrute el pago a los proveedores enumerados. | Requerido (≥1) | No permitido | Permitido | Permitido |
reject | Bloquee la transacción por completo. | No permitido | No permitido | No permitido | No permitido |
merchant_rule | Grupo/rama: ruta a través de miembros o niños ponderados. | Requerido si no hay niños | Permitido | Permitido | Permitido |
El objeto de condición#
Las condiciones definen lo que debe coincidir con una transacción. Todas las condiciones de una regla se combinan con AND.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
id | integer | Sólo respuesta | ID de condición asignada por el servidor. |
rule_option | object | Sí | El campo a coincidir, por ejemplo. { "id": 5, "label": "currency" }. Utilice una opción de regla disponible para el comerciante; id debe ser > 0. |
operator | Enumeración | Sí | Operador de comparación. Debe ser válido para esa opción de regla |
operand | string | Condicional | Los valores con los que comparar, siempre serializado como una cadena. El formato depende del operador. Requerido para cada operador excepto is_present, que no requiere operando. |
operand_type | string | No | values (predeterminado) o list (El operando hace referencia a una lista personalizada por UUID). |
operand_config | objeto | nulo | Condicional | Usado cuando operand_type = list: { "custom_list": { "field_to_evaluate": "email" } }. |
metadata_field_name | cadena | nulo | Condicional | Requerido cuando rule_option.id = 16 (metadata). La clave de metadatos a evaluar. |
metadata_field_type | cadena | nulo | Condicional | Requerido cuando rule_option.id = 16. uno de text, numeric. |
error_code | string | Sólo respuesta | Se establece cuando falla el procesamiento asíncrono de una condición (por ejemplo, importación de lista). |
error_message | string | Sólo respuesta | Detalles legibles por humanos para error_code. |
Ejemplo: igualar tarjetas de la marca Mastercard
{
"rule_option": { "id": 3, "label": "branch" },
"operator": "in",
"operand": "mastercard"
}El objeto miembro#
Los miembros son los proveedores que utiliza una regla coincidente, intentada en sort orden (la cascada). Un miembro hace referencia uno proveedor - un proveedor de pago, un proveedor de fraude, o un proveedor de autenticación.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
payment_provider_id | integer | Condicional | ID del proveedor de pagos DEUNA. Requerido si merchant_payment_provider_id está presente. |
payment_provider_name | string | Sólo respuesta | Nombre del proveedor (repetido). |
merchant_payment_provider_id | UUID | Condicional | Conexión de proveedor específica del comerciante. Si se envía, payment_provider_id debe También se enviará. |
merchant_payment_provider_name | string | Sólo respuesta | Nombre de la conexión (repetido). |
fraud_provider | string | Condicional | Nombre del proveedor de fraude/antifraude. Mutuamente excluyentes con los campos de proveedor de pago y autenticación. |
fraud_provider_id | string | Sólo respuesta | ID del proveedor fraudulento (repetido). |
authentication_provider | string | Condicional | Nombre del proveedor de autenticación (p. ej. UNICO_ID, CYBERSOURCE_3DS). Se excluyen mutuamente con los campos de proveedores de pago y fraude. |
authentication_provider_id | string | Sólo respuesta | ID del proveedor de autenticación (repetido). |
authentication_type | Enumeración | Condicional | El método de autenticación. uno de 3ds_authentication, 3ds_data_only, unico_id. Requerido cuando el miembro es un proveedor de autenticación. |
failover | objeto | nulo | Opcional | Autenticación de respaldo utilizada cuando el proveedor principal no está disponible: { "authentication_provider": "...", "authentication_type": "..." }. Válido solo en los miembros del proveedor de autenticación. |
sort | integer | Sí | Orden en cascada. debe ser único dentro de la regla. |
strategy | Enumeración | Sí | Actualmente solo cascade. |
capabilities | array<string> | Sí | Capacidades del proveedor a utilizar, p. ["3ds"]. enviar [] si ninguno. |
enabled3ds | boolean | No | Solicite autenticación 3DS en este miembro (crear carga útil). |
post_authorization | boolean | Sí | Sólo un fraude el proveedor puede establecer true, y debe ser el último miembro por sort. |
shadow_mode | boolean | Sí | Evaluar al proveedor sin afectar la ruta (prueba segura). |
enabled | boolean | Sólo respuesta | Si el proveedor está actualmente disponible para el comerciante. |
Ejemplo: miembro proveedor de pagos
{
"sort": 1,
"strategy": "cascade",
"payment_provider_id": 45,
"merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"capabilities": ["3ds"],
"post_authorization": false,
"shadow_mode": false
}Ejemplo: miembro proveedor fraudulento
{
"sort": 1,
"strategy": "cascade",
"fraud_provider": "CYBERSOURCE",
"capabilities": [],
"post_authorization": false,
"shadow_mode": false
}Ejemplo: miembro del proveedor de autenticación (con conmutación por error)
{
"sort": 1,
"strategy": "cascade",
"authentication_provider": "CYBERSOURCE_3DS",
"authentication_type": "3ds_authentication",
"failover": {
"authentication_provider": "CYBERSOURCE_3DS",
"authentication_type": "3ds_data_only"
},
"capabilities": [],
"shadow_mode": false
}Pruebas A/B: divide el tráfico entre dos rutas#
Para la prueba A/B, agregue dos rutas a una regla (como children) y dale a cada uno un porcentaje weight. El motor envía esa parte de las transacciones coincidentes a cada ruta, p. 70% a la Ruta A, 30% a la Ruta B - para que puedas compararlos en el tráfico en vivo.
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
weight | integer | Sí | Porcentaje de tráfico coincidente enviado a esta ruta. Los pesos de las dos rutas deben sumar 100. |
members | array<Member> | Sí | Los proveedores de esta ruta. |
Reglas:
- exactamente dos routes.
weightlos valores deben sumar 100.- La regla debe establecer
ignore_next_rules: true. - La tarea es pegajoso por
transaction_id(una transacción siempre obtiene la misma ruta), y la ruta que se ejecutó se repite en el/triggersresponse.
Ejemplo: división 70/30
{
"label": "A/B test — MXN cards",
"ignore_next_rules": true,
"conditions": [
{ "rule_option": { "id": 5, "label": "currency" }, "operator": "in", "operand": "MXN" }
],
"children": [
{
"weight": 70,
"members": [
{ "sort": 1, "strategy": "cascade", "payment_provider_id": 45, "merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8" }
]
},
{
"weight": 30,
"members": [
{ "sort": 1, "strategy": "cascade", "payment_provider_id": 52, "merchant_payment_provider_id": "8b3d7c90-1a2b-4c3d-9e0f-5a6b7c8d9e01" }
]
}
]
}Crear una regla#
POST /routing/v1/rules
El siguiente ejemplo crea una merchant_rule para tarjetas de crédito Mastercard en MXN, realiza una verificación de fraude y luego sucursales por fraud_risk: bloquear highy ruta medium/low a Cybersource.
cURL
curl -X POST 'https://api.sandbox.deuna.io/routing/v1/rules' \
-H 'X-Api-Key: {{API KEY}}' \
-H 'X-Idempotency-Key: b3f1c2d4-9a8e-4c11-bb77-2e5f9c74a6b1' \
-H 'Content-Type: application/json' \
-d '{
"label": "MX Mastercard — Cybersource",
"priority": 2,
"status": "enabled",
"trigger": "merchant_rule",
"is_default": false,
"data_type": "credit_card",
"ignore_next_rules": true,
"conditions": [
{ "rule_option": { "id": 3, "label": "branch" }, "operator": "in", "operand": "mastercard" },
{ "rule_option": { "id": 5, "label": "currency" }, "operator": "in", "operand": "MXN" }
],
"members": [
{ "sort": 1, "strategy": "cascade", "fraud_provider": "CYBERSOURCE" }
],
"children": [
{ "conditions": [ { "rule_option": { "id": 15 }, "operator": "eq", "operand": "high" } ], "members": [] },
{ "conditions": [ { "rule_option": { "id": 15 }, "operator": "eq", "operand": "medium" } ],
"members": [ { "sort": 1, "strategy": "cascade", "payment_provider_id": 45, "merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8", "capabilities": ["3ds"], "enabled3ds": false } ] },
{ "conditions": [ { "rule_option": { "id": 15 }, "operator": "eq", "operand": "low" } ],
"members": [ { "sort": 1, "strategy": "cascade", "payment_provider_id": 45, "merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8", "capabilities": ["3ds"], "enabled3ds": false } ] }
]
}'const response = await fetch("https://api.sandbox.deuna.io/routing/v1/rules", {
method: "POST",
headers: {
"X-Api-Key": "{{API KEY}}",
"X-Idempotency-Key": "b3f1c2d4-9a8e-4c11-bb77-2e5f9c74a6b1",
"Content-Type": "application/json"
},
body: JSON.stringify({
"label": "MX Mastercard — Cybersource",
"priority": 2,
"status": "enabled",
"trigger": "merchant_rule",
"is_default": false,
"data_type": "credit_card",
"ignore_next_rules": true,
"conditions": [
{
"rule_option": {
"id": 3,
"label": "branch"
},
"operator": "in",
"operand": "mastercard"
},
{
"rule_option": {
"id": 5,
"label": "currency"
},
"operator": "in",
"operand": "MXN"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"fraud_provider": "CYBERSOURCE"
}
],
"children": [
{
"conditions": [
{
"rule_option": {
"id": 15
},
"operator": "eq",
"operand": "high"
}
],
"members": []
},
{
"conditions": [
{
"rule_option": {
"id": 15
},
"operator": "eq",
"operand": "medium"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"payment_provider_id": 45,
"merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"capabilities": [
"3ds"
],
"enabled3ds": false
}
]
},
{
"conditions": [
{
"rule_option": {
"id": 15
},
"operator": "eq",
"operand": "low"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"payment_provider_id": 45,
"merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"capabilities": [
"3ds"
],
"enabled3ds": false
}
]
}
]
})
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"POST",
"https://api.sandbox.deuna.io/routing/v1/rules",
headers={
"X-Api-Key": "{{API KEY}}",
"X-Idempotency-Key": "b3f1c2d4-9a8e-4c11-bb77-2e5f9c74a6b1",
"Content-Type": "application/json"
},
json={
"label": "MX Mastercard — Cybersource",
"priority": 2,
"status": "enabled",
"trigger": "merchant_rule",
"is_default": False,
"data_type": "credit_card",
"ignore_next_rules": True,
"conditions": [
{
"rule_option": {
"id": 3,
"label": "branch"
},
"operator": "in",
"operand": "mastercard"
},
{
"rule_option": {
"id": 5,
"label": "currency"
},
"operator": "in",
"operand": "MXN"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"fraud_provider": "CYBERSOURCE"
}
],
"children": [
{
"conditions": [
{
"rule_option": {
"id": 15
},
"operator": "eq",
"operand": "high"
}
],
"members": []
},
{
"conditions": [
{
"rule_option": {
"id": 15
},
"operator": "eq",
"operand": "medium"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"payment_provider_id": 45,
"merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"capabilities": [
"3ds"
],
"enabled3ds": False
}
]
},
{
"conditions": [
{
"rule_option": {
"id": 15
},
"operator": "eq",
"operand": "low"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"payment_provider_id": 45,
"merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"capabilities": [
"3ds"
],
"enabled3ds": False
}
]
}
]
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/routing/v1/rules",
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: {{API KEY}}",
"X-Idempotency-Key: b3f1c2d4-9a8e-4c11-bb77-2e5f9c74a6b1",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"label" => "MX Mastercard — Cybersource",
"priority" => 2,
"status" => "enabled",
"trigger" => "merchant_rule",
"is_default" => false,
"data_type" => "credit_card",
"ignore_next_rules" => true,
"conditions" => [
[
"rule_option" => [
"id" => 3,
"label" => "branch"
],
"operator" => "in",
"operand" => "mastercard"
],
[
"rule_option" => [
"id" => 5,
"label" => "currency"
],
"operator" => "in",
"operand" => "MXN"
]
],
"members" => [
[
"sort" => 1,
"strategy" => "cascade",
"fraud_provider" => "CYBERSOURCE"
]
],
"children" => [
[
"conditions" => [
[
"rule_option" => [
"id" => 15
],
"operator" => "eq",
"operand" => "high"
]
],
"members" => []
],
[
"conditions" => [
[
"rule_option" => [
"id" => 15
],
"operator" => "eq",
"operand" => "medium"
]
],
"members" => [
[
"sort" => 1,
"strategy" => "cascade",
"payment_provider_id" => 45,
"merchant_payment_provider_id" => "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"capabilities" => [
"3ds"
],
"enabled3ds" => false
]
]
],
[
"conditions" => [
[
"rule_option" => [
"id" => 15
],
"operator" => "eq",
"operand" => "low"
]
],
"members" => [
[
"sort" => 1,
"strategy" => "cascade",
"payment_provider_id" => 45,
"merchant_payment_provider_id" => "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"capabilities" => [
"3ds"
],
"enabled3ds" => false
]
]
]
]
])
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/routing/v1/rules"))
.header("X-Api-Key", "{{API KEY}}")
.header("X-Idempotency-Key", "b3f1c2d4-9a8e-4c11-bb77-2e5f9c74a6b1")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString("{\n \"label\": \"MX Mastercard — Cybersource\",\n \"priority\": 2,\n \"status\": \"enabled\",\n \"trigger\": \"merchant_rule\",\n \"is_default\": false,\n \"data_type\": \"credit_card\",\n \"ignore_next_rules\": true,\n \"conditions\": [\n { \"rule_option\": { \"id\": 3, \"label\": \"branch\" }, \"operator\": \"in\", \"operand\": \"mastercard\" },\n { \"rule_option\": { \"id\": 5, \"label\": \"currency\" }, \"operator\": \"in\", \"operand\": \"MXN\" }\n ],\n \"members\": [\n { \"sort\": 1, \"strategy\": \"cascade\", \"fraud_provider\": \"CYBERSOURCE\" }\n ],\n \"children\": [\n { \"conditions\": [ { \"rule_option\": { \"id\": 15 }, \"operator\": \"eq\", \"operand\": \"high\" } ], \"members\": [] },\n { \"conditions\": [ { \"rule_option\": { \"id\": 15 }, \"operator\": \"eq\", \"operand\": \"medium\" } ],\n \"members\": [ { \"sort\": 1, \"strategy\": \"cascade\", \"payment_provider_id\": 45, \"merchant_payment_provider_id\": \"6e4c651a-3e5f-403d-af9d-6a9e9299acb8\", \"capabilities\": [\"3ds\"], \"enabled3ds\": false } ] },\n { \"conditions\": [ { \"rule_option\": { \"id\": 15 }, \"operator\": \"eq\", \"operand\": \"low\" } ],\n \"members\": [ { \"sort\": 1, \"strategy\": \"cascade\", \"payment_provider_id\": 45, \"merchant_payment_provider_id\": \"6e4c651a-3e5f-403d-af9d-6a9e9299acb8\", \"capabilities\": [\"3ds\"], \"enabled3ds\": false } ] }\n ]\n }"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
request, err := http.NewRequest("POST", "https://api.sandbox.deuna.io/routing/v1/rules", strings.NewReader("{\n \"label\": \"MX Mastercard — Cybersource\",\n \"priority\": 2,\n \"status\": \"enabled\",\n \"trigger\": \"merchant_rule\",\n \"is_default\": false,\n \"data_type\": \"credit_card\",\n \"ignore_next_rules\": true,\n \"conditions\": [\n { \"rule_option\": { \"id\": 3, \"label\": \"branch\" }, \"operator\": \"in\", \"operand\": \"mastercard\" },\n { \"rule_option\": { \"id\": 5, \"label\": \"currency\" }, \"operator\": \"in\", \"operand\": \"MXN\" }\n ],\n \"members\": [\n { \"sort\": 1, \"strategy\": \"cascade\", \"fraud_provider\": \"CYBERSOURCE\" }\n ],\n \"children\": [\n { \"conditions\": [ { \"rule_option\": { \"id\": 15 }, \"operator\": \"eq\", \"operand\": \"high\" } ], \"members\": [] },\n { \"conditions\": [ { \"rule_option\": { \"id\": 15 }, \"operator\": \"eq\", \"operand\": \"medium\" } ],\n \"members\": [ { \"sort\": 1, \"strategy\": \"cascade\", \"payment_provider_id\": 45, \"merchant_payment_provider_id\": \"6e4c651a-3e5f-403d-af9d-6a9e9299acb8\", \"capabilities\": [\"3ds\"], \"enabled3ds\": false } ] },\n { \"conditions\": [ { \"rule_option\": { \"id\": 15 }, \"operator\": \"eq\", \"operand\": \"low\" } ],\n \"members\": [ { \"sort\": 1, \"strategy\": \"cascade\", \"payment_provider_id\": 45, \"merchant_payment_provider_id\": \"6e4c651a-3e5f-403d-af9d-6a9e9299acb8\", \"capabilities\": [\"3ds\"], \"enabled3ds\": false } ] }\n ]\n }"))
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "{{API KEY}}")
request.Header.Set("X-Idempotency-Key", "b3f1c2d4-9a8e-4c11-bb77-2e5f9c74a6b1")
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}Respuesta 201
{
"id": 21866,
"label": "MX Mastercard — Cybersource",
"data_type": "credit_card",
"priority": 2,
"status": "enabled",
"is_default": false,
"trigger": "merchant_rule",
"conditions": [
{
"id": 44264,
"rule_option": { "id": 3, "label": "branch" },
"operator": "in",
"operand_config": null,
"operand": "mastercard",
"operand_type": "values",
"metadata_field_name": null,
"metadata_field_type": null,
"error_code": "",
"error_message": ""
},
{
"id": 44265,
"rule_option": { "id": 5, "label": "currency" },
"operator": "in",
"operand": "MXN",
"operand_type": "values"
}
],
"members": [
{
"payment_provider_name": null,
"merchant_payment_provider_name": null,
"fraud_provider": "CYBERSOURCE",
"sort": 1,
"capabilities": [],
"strategy": "cascade",
"post_authorization": false,
"shadow_mode": false
}
],
"ignore_next_rules": true,
"created_at": "2026-07-08T01:07:29.439794Z"
}Get a rule by ID#
GET /routing/v1/rules/{rule_id}
Devuelve una única regla, incluida su conditions, members y cualquier children. rule_id es el identificador numérico.
cURL
curl 'https://api.sandbox.deuna.io/routing/v1/rules/21866' \
-H 'X-Api-Key: {{API KEY}}'const response = await fetch("https://api.sandbox.deuna.io/routing/v1/rules/21866", {
method: "GET",
headers: {
"X-Api-Key": "{{API KEY}}"
}
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"GET",
"https://api.sandbox.deuna.io/routing/v1/rules/21866",
headers={
"X-Api-Key": "{{API KEY}}"
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/routing/v1/rules/21866",
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: {{API KEY}}"
]
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/routing/v1/rules/21866"))
.header("X-Api-Key", "{{API KEY}}")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
)
func main() {
request, err := http.NewRequest("GET", "https://api.sandbox.deuna.io/routing/v1/rules/21866", nil)
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "{{API KEY}}")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}Respuesta 200
{
"id": 21866,
"label": "MX Mastercard — Cybersource",
"data_type": "credit_card",
"priority": 2,
"status": "enabled",
"is_default": false,
"trigger": "merchant_rule",
"conditions": [
{
"id": 44269,
"rule_option": { "id": 3, "label": "branch" },
"operator": "in",
"operand": "mastercard",
"operand_type": "values"
},
{
"id": 44270,
"rule_option": { "id": 5, "label": "currency" },
"operator": "in",
"operand": "MXN",
"operand_type": "values"
}
],
"members": [
{
"fraud_provider_id": "3",
"fraud_provider": "CYBERSOURCE",
"sort": 1,
"capabilities": [],
"enabled": true,
"strategy": "cascade",
"post_authorization": false,
"shadow_mode": false
}
],
"ignore_next_rules": true,
"created_at": "2026-07-08T01:07:29.439794Z",
"children": [
{
"conditions": [
{ "id": 44271, "rule_option": { "id": 15, "label": "fraud_risk" }, "operator": "eq", "operand": "high", "operand_type": "values" }
],
"members": [],
"ignore_next_rules": true
},
{
"conditions": [
{ "id": 44272, "rule_option": { "id": 15, "label": "fraud_risk" }, "operator": "eq", "operand": "medium", "operand_type": "values" }
],
"members": [
{
"payment_provider_id": 45,
"payment_provider_name": "cybersource",
"merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"merchant_payment_provider_name": "Cybersource MX",
"sort": 1,
"capabilities": ["3ds"],
"enabled": true,
"strategy": "cascade",
"post_authorization": false,
"shadow_mode": false
}
],
"ignore_next_rules": true
}
]
}Errores: PAYROU-NOT_FOUND (404) si la regla no existe; PAYROU-FORBIDDEN (403) si no es accesible; PAYROU-INVALID_PATH_PARAM (400) si rule_id no es un número entero válido.
Lista de reglas#
GET /routing/v1/rules
Reglas de devoluciones para su comerciante en orden de prioridad. Los resultados son paginado con un cursor opaco.
| parámetro de consulta | Tipo | Descripción |
|---|---|---|
limit | integer | Opcional. Tamaño de página. Predeterminado 50, máximo 200. |
cursor | string | Opcional. Cursor opaco de una respuesta anterior pagination.next_cursor. Omitir para la primera página. |
payment_provider_id | integer | Opcional. Devuelva solo reglas que hagan referencia a este proveedor de pagos. |
La respuesta envuelve las reglas en un pagination objeto. Sigue solicitando con next_cursor mientras has_more es true.
pagination campo | Tipo | Descripción |
|---|---|---|
next_cursor | cadena | nulo | Cursor para la página siguiente, o null en la última página. |
has_more | boolean | true si hay más reglas disponibles. |
limit | integer | El tamaño de página que se aplicó. |
cURL
curl 'https://api.sandbox.deuna.io/routing/v1/rules?limit=50' \
-H 'X-Api-Key: {{API KEY}}'const response = await fetch("https://api.sandbox.deuna.io/routing/v1/rules?limit=50", {
method: "GET",
headers: {
"X-Api-Key": "{{API KEY}}"
}
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"GET",
"https://api.sandbox.deuna.io/routing/v1/rules?limit=50",
headers={
"X-Api-Key": "{{API KEY}}"
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/routing/v1/rules?limit=50",
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: {{API KEY}}"
]
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/routing/v1/rules?limit=50"))
.header("X-Api-Key", "{{API KEY}}")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
)
func main() {
request, err := http.NewRequest("GET", "https://api.sandbox.deuna.io/routing/v1/rules?limit=50", nil)
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "{{API KEY}}")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}Respuesta 200
{
"merchant_id": "87dd2c00-1f7a-44aa-9e05-34330bab73cc",
"pagination": {
"next_cursor": "eyJwcmlvcml0eSI6M30",
"has_more": true,
"limit": 50
},
"rules": [
{
"id": 21873,
"label": "MX Mastercard — Cybersource",
"data_type": "credit_card",
"priority": 2,
"status": "enabled",
"is_default": false,
"trigger": "payment",
"conditions": [
{ "id": 44274, "rule_option": { "id": 3, "label": "branch" }, "operator": "in", "operand": "mastercard", "operand_type": "values" }
],
"members": [
{
"payment_provider_id": 45,
"payment_provider_name": "cybersource",
"merchant_payment_provider_id": "6e4c651a-3e5f-403d-af9d-6a9e9299acb8",
"merchant_payment_provider_name": "Cybersource MX",
"sort": 1,
"capabilities": ["3ds"],
"enabled": true,
"strategy": "cascade",
"post_authorization": false,
"shadow_mode": false
}
],
"ignore_next_rules": true,
"created_at": "2026-07-08T01:09:49.553614Z"
}
]
}Actualizar una regla#
PUT /routing/v1/rules/{rule_id}
Reemplazo completo de la regla. Envíe el cuerpo de regla completo (la misma forma que creó), incluido id y created_at. Uso común: voltear status entre enabled y disabled (Así es como se "retira" una regla en lugar de eliminarla).
cURL: deshabilitar una regla
curl -X PUT 'https://api.sandbox.deuna.io/routing/v1/rules/21866' \
-H 'X-Api-Key: {{API KEY}}' \
-H 'X-Idempotency-Key: 7c2e5a19-4b8d-4f10-9a3c-1d2e3f4a5b6c' \
-H 'Content-Type: application/json' \
-d '{
"id": 21866,
"created_at": "2026-07-08T01:07:29.439794Z",
"label": "MX Mastercard — Cybersource",
"priority": 2,
"status": "disabled",
"trigger": "merchant_rule",
"is_default": false,
"data_type": "credit_card",
"ignore_next_rules": true,
"conditions": [
{ "id": 44264, "rule_option": { "id": 3, "label": "branch" }, "operator": "in", "operand": "mastercard", "operand_type": "values" },
{ "id": 44265, "rule_option": { "id": 5, "label": "currency" }, "operator": "in", "operand": "MXN", "operand_type": "values" }
],
"members": [
{ "sort": 1, "strategy": "cascade", "fraud_provider": "CYBERSOURCE", "capabilities": [], "post_authorization": false, "shadow_mode": false }
]
}'const response = await fetch("https://api.sandbox.deuna.io/routing/v1/rules/21866", {
method: "PUT",
headers: {
"X-Api-Key": "{{API KEY}}",
"X-Idempotency-Key": "7c2e5a19-4b8d-4f10-9a3c-1d2e3f4a5b6c",
"Content-Type": "application/json"
},
body: JSON.stringify({
"id": 21866,
"created_at": "2026-07-08T01:07:29.439794Z",
"label": "MX Mastercard — Cybersource",
"priority": 2,
"status": "disabled",
"trigger": "merchant_rule",
"is_default": false,
"data_type": "credit_card",
"ignore_next_rules": true,
"conditions": [
{
"id": 44264,
"rule_option": {
"id": 3,
"label": "branch"
},
"operator": "in",
"operand": "mastercard",
"operand_type": "values"
},
{
"id": 44265,
"rule_option": {
"id": 5,
"label": "currency"
},
"operator": "in",
"operand": "MXN",
"operand_type": "values"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"fraud_provider": "CYBERSOURCE",
"capabilities": [],
"post_authorization": false,
"shadow_mode": false
}
]
})
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"PUT",
"https://api.sandbox.deuna.io/routing/v1/rules/21866",
headers={
"X-Api-Key": "{{API KEY}}",
"X-Idempotency-Key": "7c2e5a19-4b8d-4f10-9a3c-1d2e3f4a5b6c",
"Content-Type": "application/json"
},
json={
"id": 21866,
"created_at": "2026-07-08T01:07:29.439794Z",
"label": "MX Mastercard — Cybersource",
"priority": 2,
"status": "disabled",
"trigger": "merchant_rule",
"is_default": False,
"data_type": "credit_card",
"ignore_next_rules": True,
"conditions": [
{
"id": 44264,
"rule_option": {
"id": 3,
"label": "branch"
},
"operator": "in",
"operand": "mastercard",
"operand_type": "values"
},
{
"id": 44265,
"rule_option": {
"id": 5,
"label": "currency"
},
"operator": "in",
"operand": "MXN",
"operand_type": "values"
}
],
"members": [
{
"sort": 1,
"strategy": "cascade",
"fraud_provider": "CYBERSOURCE",
"capabilities": [],
"post_authorization": False,
"shadow_mode": False
}
]
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/routing/v1/rules/21866",
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: {{API KEY}}",
"X-Idempotency-Key: 7c2e5a19-4b8d-4f10-9a3c-1d2e3f4a5b6c",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"id" => 21866,
"created_at" => "2026-07-08T01:07:29.439794Z",
"label" => "MX Mastercard — Cybersource",
"priority" => 2,
"status" => "disabled",
"trigger" => "merchant_rule",
"is_default" => false,
"data_type" => "credit_card",
"ignore_next_rules" => true,
"conditions" => [
[
"id" => 44264,
"rule_option" => [
"id" => 3,
"label" => "branch"
],
"operator" => "in",
"operand" => "mastercard",
"operand_type" => "values"
],
[
"id" => 44265,
"rule_option" => [
"id" => 5,
"label" => "currency"
],
"operator" => "in",
"operand" => "MXN",
"operand_type" => "values"
]
],
"members" => [
[
"sort" => 1,
"strategy" => "cascade",
"fraud_provider" => "CYBERSOURCE",
"capabilities" => [],
"post_authorization" => false,
"shadow_mode" => false
]
]
])
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/routing/v1/rules/21866"))
.header("X-Api-Key", "{{API KEY}}")
.header("X-Idempotency-Key", "7c2e5a19-4b8d-4f10-9a3c-1d2e3f4a5b6c")
.header("Content-Type", "application/json")
.method("PUT", HttpRequest.BodyPublishers.ofString("{\n \"id\": 21866,\n \"created_at\": \"2026-07-08T01:07:29.439794Z\",\n \"label\": \"MX Mastercard — Cybersource\",\n \"priority\": 2,\n \"status\": \"disabled\",\n \"trigger\": \"merchant_rule\",\n \"is_default\": false,\n \"data_type\": \"credit_card\",\n \"ignore_next_rules\": true,\n \"conditions\": [\n { \"id\": 44264, \"rule_option\": { \"id\": 3, \"label\": \"branch\" }, \"operator\": \"in\", \"operand\": \"mastercard\", \"operand_type\": \"values\" },\n { \"id\": 44265, \"rule_option\": { \"id\": 5, \"label\": \"currency\" }, \"operator\": \"in\", \"operand\": \"MXN\", \"operand_type\": \"values\" }\n ],\n \"members\": [\n { \"sort\": 1, \"strategy\": \"cascade\", \"fraud_provider\": \"CYBERSOURCE\", \"capabilities\": [], \"post_authorization\": false, \"shadow_mode\": false }\n ]\n }"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
request, err := http.NewRequest("PUT", "https://api.sandbox.deuna.io/routing/v1/rules/21866", strings.NewReader("{\n \"id\": 21866,\n \"created_at\": \"2026-07-08T01:07:29.439794Z\",\n \"label\": \"MX Mastercard — Cybersource\",\n \"priority\": 2,\n \"status\": \"disabled\",\n \"trigger\": \"merchant_rule\",\n \"is_default\": false,\n \"data_type\": \"credit_card\",\n \"ignore_next_rules\": true,\n \"conditions\": [\n { \"id\": 44264, \"rule_option\": { \"id\": 3, \"label\": \"branch\" }, \"operator\": \"in\", \"operand\": \"mastercard\", \"operand_type\": \"values\" },\n { \"id\": 44265, \"rule_option\": { \"id\": 5, \"label\": \"currency\" }, \"operator\": \"in\", \"operand\": \"MXN\", \"operand_type\": \"values\" }\n ],\n \"members\": [\n { \"sort\": 1, \"strategy\": \"cascade\", \"fraud_provider\": \"CYBERSOURCE\", \"capabilities\": [], \"post_authorization\": false, \"shadow_mode\": false }\n ]\n }"))
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "{{API KEY}}")
request.Header.Set("X-Idempotency-Key", "7c2e5a19-4b8d-4f10-9a3c-1d2e3f4a5b6c")
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}Respuesta 200
Devuelve la regla actualizada con status ahora disabled. Nota: condición idLos s se vuelven a publicar en el momento de la actualización.
Cambiar la prioridad de una regla (reordenar)#
PUT /routing/v1/rules/{rule_id}/reorder
Mueve una regla a una nueva prioridad. Otras reglas se vuelven a secuenciar en consecuencia.
cURL
curl -X PUT 'https://api.sandbox.deuna.io/routing/v1/rules/21873/reorder' \
-H 'X-Api-Key: sk_sandbox_9f8b2c1a7d4e60b3' \
-H 'Content-Type: application/json' \
-d '{ "priority": 2 }'const response = await fetch("https://api.sandbox.deuna.io/routing/v1/rules/21873/reorder", {
method: "PUT",
headers: {
"X-Api-Key": "sk_sandbox_9f8b2c1a7d4e60b3",
"Content-Type": "application/json"
},
body: JSON.stringify({
"priority": 2
})
});
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const data = await response.json();import requests
response = requests.request(
"PUT",
"https://api.sandbox.deuna.io/routing/v1/rules/21873/reorder",
headers={
"X-Api-Key": "sk_sandbox_9f8b2c1a7d4e60b3",
"Content-Type": "application/json"
},
json={
"priority": 2
},
)
response.raise_for_status()
data = response.json()<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sandbox.deuna.io/routing/v1/rules/21873/reorder",
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Api-Key: sk_sandbox_9f8b2c1a7d4e60b3",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"priority" => 2
])
]);
$response = curl_exec($curl);
curl_close($curl);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.sandbox.deuna.io/routing/v1/rules/21873/reorder"))
.header("X-Api-Key", "sk_sandbox_9f8b2c1a7d4e60b3")
.header("Content-Type", "application/json")
.method("PUT", HttpRequest.BodyPublishers.ofString("{ \"priority\": 2 }"))
.build();
HttpResponse<String> response = HttpClient.newHttpClient().send(
request, HttpResponse.BodyHandlers.ofString()
);
System.out.println(response.body());
}
}package main
import (
"fmt"
"io"
"net/http"
"strings"
)
func main() {
request, err := http.NewRequest("PUT", "https://api.sandbox.deuna.io/routing/v1/rules/21873/reorder", strings.NewReader("{ \"priority\": 2 }"))
if err != nil { panic(err) }
request.Header.Set("X-Api-Key", "sk_sandbox_9f8b2c1a7d4e60b3")
request.Header.Set("Content-Type", "application/json")
response, err := http.DefaultClient.Do(request)
if err != nil { panic(err) }
defer response.Body.Close()
body, _ := io.ReadAll(response.Body)
fmt.Println(string(body))
}| Campo | Tipo | Requerido | Restricción |
|---|---|---|---|
priority | integer | Sí | Non-negative integer |
Respuesta 200
{ "priority": 2 }Errores: PAYROU-VALIDATION (400) con errors[].code = PRIORITY_OUT_OF_RANGE si priority no es un número entero no negativo.
Validaciones#
Cree y actualice ejecute estas comprobaciones. Cualquier error devuelve HTTP 400 con código de nivel superior PAYROU-VALIDATION y una entrada por campo infractor en errors[] (ver Errores para el sobre y el catálogo completo de códigos a nivel de campo).
Nivel de regla
statusdebe ser uno deenabled,disabled,draft,process-in-background.triggerdebe ser uno depayment,reject,merchant_rule.trigger = payment→ al menos un miembro; sin hijos.trigger = reject→ sin miembros, sin hijos,ignore_next_rulesdebe ser falso,is_defaultdebe ser falso.trigger = merchant_rule→ al menos un miembro o al menos un hijo.is_default = true→ sin condiciones yignore_next_rulesdebe ser falso.is_default = false→ al menos una condición.prioritydebe ser> 0y≤ 1000.
Condiciones
rule_option.idrequerido (> 0);operandrequerido (no vacío).operatordebe ser válido para esa opción de regla (ver catálogo).- un
rule_optionpuede aparecer sólo una vez por regla (exceptometadata). - para
metadata(identificación 16):metadata_field_nameymetadata_field_typerequerido; el tipo debe sertextonumeric. - para
operand_type = list:operanddebe ser un UUID de lista válido que exista.
Miembros
- Cada miembro debe hacer referencia exactamente a un tipo de proveedor: pago, pago a comerciantes, fraude o autenticación.
- Los tipos de proveedores no se pueden mezclar en un solo miembro.
- si
merchant_payment_provider_idestá presente,payment_provider_idtambién debe estar presente. - Los miembros de autenticación requieren
authentication_type(uno de3ds_authentication,3ds_data_only,unico_id). failoveres valido solo sobre miembros de autenticación; esauthentication_typetambién debe ser un valor válido.sortdebe ser único dentro de la regla.- Un proveedor puede aparecer sólo una vez por regla.
strategydebe sercascade.post_authorization = truesolo para proveedores fraudulentos, y ese miembro debe ser último porsort.
Nivel de servicio (comprobado con la configuración del comerciante)
- La opción de regla a la que se hace referencia debe existir y ser compatible con el operador determinado.
- El proveedor de pago/pago-comerciante/fraude/autenticación al que se hace referencia debe estar habilitado para el comerciante.
merchant_payment_provider_iddebe pertenecer a lo dadopayment_provider_id.
Errores#
Sobre de error
Cada respuesta de error utiliza la misma forma JSON:
{
"code": "PAYROU-VALIDATION",
"message": "One or more fields failed validation.",
"request_id": "req_01J9Z8K7QF3M2N4P5R6S7T8U9V",
"errors": [
{
"field": "members",
"code": "MEMBERS_REQUIRED",
"message": "At least one member is required when trigger is 'payment'."
}
]
}| Campo | Tipo | Descripción |
|---|---|---|
code | string | Código de nivel superior estable y legible por máquina. Rama en esto, nunca en message. |
message | string | Resumen legible por humanos. Puede reformularse o localizarse; no lo analice. |
request_id | string | Único por respuesta y también devuelto en el X-Request-Id encabezado de respuesta (en caso de éxito y error). Cítelo en cualquier solicitud de soporte. |
errors | array | Presente sólo para PAYROU-VALIDATION. Una entrada por campo infractor. |
errors[].field | string | Ruta al campo, usando notación de punto/corchete, p.e. priority, conditions[1].operand, members[0].sort. |
errors[].code | string | Código estable a nivel de campo (ver códigos de validación). |
errors[].message | string | Detalle legible por humanos. No analizar. |
Siempre envía un
X-Idempotency-Keyen escribe. Al reproducir la misma clave se devuelve la respuesta original; reutilizar una llave con un diferente el cuerpo regresa409 PAYROU-CONFLICT.
Códigos de estado HTTP
| Estado | Significado |
|---|---|
200 / 201 | Success. |
400 | La solicitud no es válida: error de validación, JSON con formato incorrecto o parámetros de consulta/ruta incorrectos. |
401 | Autenticación falló - el X-Api-Key falta o no es válido. |
403 | Autorización fallido: la clave es válida pero no se le permite acceder a este comerciante/recurso. |
404 | La regla o un recurso al que se hace referencia no existe. |
409 | Conflicto: reutilización de claves de idempotencia con un cuerpo diferente o una actualización simultánea. |
429 | Límite de velocidad excedido: vuelva a intentarlo después del Retry-After header. |
500 | Error inesperado del servidor. |
503 | Una dependencia descendente no está disponible temporalmente; es seguro volver a intentarlo con una pausa. |
Códigos de nivel superior
| Código | HTTP | cuando |
|---|---|---|
PAYROU-VALIDATION | 400 | Uno o más campos no superaron la validación. Detalles en errors[]. |
PAYROU-MALFORMED_JSON | 400 | El cuerpo de la solicitud no es JSON válido. |
PAYROU-INVALID_PATH_PARAM | 400 | Un parámetro de ruta es del tipo/formato incorrecto (por ejemplo, no entero rule_id). |
PAYROU-INVALID_QUERY_PARAM | 400 | Un parámetro de consulta no es válido (p. ej. limit fuera de rango, mal formado cursor). |
PAYROU-UNAUTHENTICATED | 401 | Clave API faltante o no válida. |
PAYROU-FORBIDDEN | 403 | Clave válida, pero no vinculada a este comerciante/recurso. |
PAYROU-NOT_FOUND | 404 | No se encontró la regla o el recurso al que se hace referencia. |
PAYROU-CONFLICT | 409 | Reutilización de claves de idempotencia con una carga útil diferente o modificación simultánea. |
PAYROU-RATE_LIMITED | 429 | Demasiadas solicitudes. |
PAYROU-INTERNAL | 500 | Error inesperado del servidor. |
PAYROU-UPSTREAM_UNAVAILABLE | 503 | Una dependencia descendente no está disponible temporalmente. |
Códigos de validación
Regresado adentro errors[] cuando el código de nivel superior es PAYROU-VALIDATION. Cada uno es estable y seguro para ramificarse.
Nivel de regla
code | Típico field | causa |
|---|---|---|
INVALID_STATUS | status | Ninguno de enabled, disabled, draft, process-in-background. |
INVALID_TRIGGER | trigger | Ninguno de payment, reject, merchant_rule. |
PRIORITY_OUT_OF_RANGE | priority | no entre 1 y 1000 (cubre ambos ≤ 0 y > 1000). |
MEMBERS_REQUIRED | members | trigger = payment sin miembros. |
MEMBERS_OR_CHILDREN_REQUIRED | members | trigger = merchant_rule sin miembros ni hijos. |
CONDITIONS_REQUIRED | conditions | Regla no predeterminada sin condiciones. |
TRIGGER_CANNOT_BE_DEFAULT | is_default | reject gobernar con is_default = true. |
TRIGGER_CANNOT_HAVE_MEMBERS | members | reject gobernar con los miembros. |
TRIGGER_CANNOT_HAVE_CHILDREN | children | payment/reject gobernar con los niños. |
TRIGGER_CANNOT_IGNORE_NEXT_RULES | ignore_next_rules | reject gobernar con ignore_next_rules = true. |
DEFAULT_RULE_CANNOT_HAVE_CONDITIONS | conditions | Regla predeterminada con condiciones. |
DEFAULT_RULE_CANNOT_IGNORE_NEXT_RULES | ignore_next_rules | Regla predeterminada con ignore_next_rules = true. |
Condiciones
code | Típico field | causa |
|---|---|---|
RULE_OPTION_ID_REQUIRED | conditions[i].rule_option.id | Desaparecido o ≤ 0. |
OPERAND_REQUIRED | conditions[i].operand | Operando vacío para un operador que lo requiere. |
OPERATOR_REQUIRED | conditions[i].operator | El operador está vacío. |
INVALID_OPERATOR | conditions[i].operator | Operador no válido para esa opción de regla. |
DUPLICATE_RULE_OPTION | conditions[i].rule_option | La misma opción de regla se usa más de una vez (excepto metadata). |
METADATA_FIELDS_REQUIRED | conditions[i].metadata_field_name | metadata falta la condición metadata_field_name/metadata_field_type. |
INVALID_METADATA_FIELD_TYPE | conditions[i].metadata_field_type | no text o numeric. |
RULE_OPTION_NOT_FOUND | conditions[i].rule_option.id | La opción de regla no existe. |
INVALID_LIST_REFERENCE | conditions[i].operand | operand_type = list pero el UUID de la lista no es válido o no se encuentra. |
Miembros
code | Típico field | causa |
|---|---|---|
MEMBER_PROVIDER_REQUIRED | members[i] | El miembro no hace referencia a ningún proveedor (pago, fraude o autenticación). |
MEMBER_MULTIPLE_PROVIDER_TYPES | members[i] | El miembro combina tipos de proveedores (por ejemplo, pago + fraude o pago + autenticación). |
PAYMENT_PROVIDER_ID_REQUIRED | members[i].payment_provider_id | merchant_payment_provider_id enviado sin payment_provider_id. |
AUTHENTICATION_TYPE_REQUIRED | members[i].authentication_type | Miembro de autenticación sin authentication_type. |
INVALID_AUTHENTICATION_TYPE | members[i].authentication_type | Ninguno de 3ds_authentication, 3ds_data_only, unico_id (se aplica a failover.authentication_type también). |
FAILOVER_ONLY_ON_AUTHENTICATION | members[i].failover | failover establecido en un miembro sin autenticación. |
DUPLICATE_MEMBER | members[i] | El mismo proveedor aparece más de una vez en la regla. |
DUPLICATE_MEMBER_SORT | members[i].sort | Dos miembros comparten un sort value. |
INVALID_STRATEGY | members[i].strategy | no cascade. |
POST_AUTH_ONLY_FRAUD | members[i].post_authorization | post_authorization = true en un miembro no fraudulento. |
POST_AUTH_MUST_BE_LAST | members[i].post_authorization | El post_authorization el miembro no es el último en sort. |
PROVIDER_NOT_AVAILABLE | members[i] | El proveedor (pago, fraude o autenticación) no está habilitado para este comerciante. |
MERCHANT_PROVIDER_MISMATCH | members[i].merchant_payment_provider_id | La conexión no pertenece a lo dado. payment_provider_id. |
Pruebas A/B
code | Típico field | causa |
|---|---|---|
SPLIT_WEIGHTS_MUST_SUM_TO_100 | children | niño weight los valores no suman 100. |
Flujo de extremo a extremo#
El /triggers soportes de punto final dos modos de integración – elija lo que se ajuste a la cantidad de lógica de decisión que desea poseer. Ambos utilizan el mismo punto final y las mismas reglas; sólo difieren la forma de respuesta y el número de llamadas. Selecciónelo con mode en la solicitud (single es el valor predeterminado). De cualquier manera, cierras el ciclo con uno /feedback call.
| Modo | Cómo funciona | ¿Cuándo es lo mejor? |
|---|---|---|
| 1 · Llamada única (impulsado por el cliente) | uno /triggers la llamada devuelve el plan completo — la autenticación a ejecutar (con conmutación por error) y el actions que asignan cada resultado a proceso o declive. Tú mismo ejecutas el plan. | Quiere realizar el menor número de viajes de ida y vuelta y se siente cómodo aplicando la decisión localmente. |
| 2 · Guiado (impulsado por motor) | tu llamas /triggers y el motor devuelve sólo el siguiente paso más un status. Lo realizas y luego llamas. /triggers nuevamente con el resultado de ese paso; el motor regresa al siguiente paso. Repita hasta status = completed. | Quiere que DEUNA se apropie y centralice la lógica de decisión, paso a paso. |
Modo 1: llamada única
haces un soltero /triggers llamar. Si ejecuta un proveedor de fraude ante la DEUNA, incluya su resultado en esa llamada. La respuesta es autocontenida: nombra la autenticación a ejecutar (con un conmutación por error si el principal no está disponible) y el acciones que asignan el resultado de la autenticación a qué hacer a continuación: proceso con un proveedor de pagos o declive. Su plataforma ejecuta ese plan localmente y cierra el ciclo con uno /feedback llamar - hay no second /triggers round-trip.
paso a paso
- (Opcional) Califique con un proveedor de fraude. Si su configuración utiliza un proveedor de fraude desde el principio, capture su puntuación/decisión para que pueda coincidir con las reglas (a través de
fraud_riskopción ometadata). - Solicitar la recomendación (una llamada).
POST /routing/v1/triggerscon los datos de la transacción (y el resultado del fraude, si lo hubiera). La respuesta contiene unaauthenticationbloquear (primary+ opcionalfailover) y unactionsblock. - Authenticate. Ejecute la autenticación recomendada (por ejemplo, autenticación 3DS, solo datos 3DS o ID Unico). si el
primaryproveedor no está disponible, utilice elfailover. - Decidir y procesar. Aplicar
actions: cada resultado se asigna aprocess(con el proveedor de pago nombrado en la acción) odecline; eldefaultLa acción se aplica cuando ningún otro resultado coincide. - Informar el resultado.
POST /routing/v1/feedbackcon elcollectionobjeto y elattempts(resultado de autenticación + resultado de pago). Esto cierra el ciclo de análisis y etiquetado de ML.
Los comerciantes con un único proveedor de pago verán un proveedor en el
processacción; Los comerciantes con varios pueden configurar una cascada en la regla.membersy la recomendación refleja los proveedores a intentar.
Respuesta del modo 1: el plan completo
El /triggers La respuesta es una recomendación única e independiente: authentication para ejecutar (con un opcional failover) y el actions que asignan el resultado de la autenticación a qué hacer. Su plataforma ejecuta esto localmente.
{
"collection": {
"id": "c7b9e3a2-4d51-4f8a-9b21-6e0f2a1c8d34",
"prediction_id": "pred_xyz789abc"
},
"recommendation": {
"rule_id": 21866,
"rule_label": "High risk → 3DS authentication",
"authentication": {
"primary": { "authentication_type": "3ds_authentication" },
"failover": { "authentication_type": "3ds_data_only" }
},
"actions": {
"on_success_with_liability_shift": { "action": "process", "provider": "acquirer_gateway" },
"default": { "action": "decline" }
}
}
}| Campo | Tipo | Descripción |
|---|---|---|
collection.id | UUID | ID de correlación para esta evaluación. Hazlo eco en /feedback. |
collection.prediction_id | string | Identificador de ML para la recomendación. Hazlo eco en /feedback. |
recommendation.rule_id | integer | La regla que coincidió (el mismo identificador que el objeto de regla) id). |
recommendation.rule_label | string | Nombre de regla legible por humanos. |
recommendation.authentication.primary | object | La autenticación que se ejecutará primero: { "authentication_type": "3ds_authentication" }. usa lo mismo authentication_type valores como miembros de la regla. |
recommendation.authentication.failover | objeto | nulo | Autenticación de respaldo si la principal no está disponible. |
recommendation.actions | object | Asigna el resultado de la autenticación a una acción. Clave por resultado. |
recommendation.actions.<outcome>.action | Enumeración | process o decline. |
recommendation.actions.<outcome>.provider | string | presente cuando action = process — el nombre del proveedor de pago a utilizar, según lo configurado en su regla (p. ej. acquirer_gateway). |
recommendation.actions.default | object | La acción alternativa se aplicó cuando no coincide ninguna otra clave de resultado. |
Claves de resultados en actions describir el resultado de autenticación al que se aplican (p. ej. on_success_with_liability_shift); default es el comodín.
Modo 2: guiado (paso a paso)
Configura "mode": "guided" en la solicitud. En lugar del plan completo, el motor devuelve el siguiente paso y un statusy usted dirige el flujo paso a paso:
status: awaiting_authentication→next_steple indica qué autenticación ejecutar.status: awaiting_fraud→next_steple indica qué verificación de fraude ejecutar.status: completed→ el motor ha decidido;next_step.actionesprocess(con unprovider) odecline.
Después de realizar un paso, llame /triggers otra vez— eco de la collection de la respuesta anterior e incluya el resultado de ese paso (authentication_result o fraud_result). El motor avanza y regresa al siguiente paso. Repita hasta status = completed, luego cerrar con /feedback.
Primera respuesta: un paso a realizar
{
"collection": { "id": "c7b9e3a2-4d51-4f8a-9b21-6e0f2a1c8d34", "prediction_id": "pred_xyz789abc" },
"recommendation": {
"rule_id": 21866,
"status": "awaiting_authentication",
"next_step": {
"type": "authentication",
"authentication_type": "3ds_authentication",
"failover": { "authentication_type": "3ds_data_only" }
}
}
}Solicitud de seguimiento: publique el resultado del paso
{
"mode": "guided",
"collection": { "id": "c7b9e3a2-4d51-4f8a-9b21-6e0f2a1c8d34", "prediction_id": "pred_xyz789abc" },
"authentication_result": { "eci": "05", "pares_status": "Y", "liability_shift": true }
}Respuesta a la terminal — status = completed
{
"collection": { "id": "c7b9e3a2-4d51-4f8a-9b21-6e0f2a1c8d34", "prediction_id": "pred_xyz789abc" },
"recommendation": {
"rule_id": 21866,
"status": "completed",
"next_step": { "type": "process", "provider": "acquirer_gateway" }
}
}| Campo | Tipo | Descripción |
|---|---|---|
mode | Enumeración | Campo de solicitud: single (predeterminado) o guided. |
collection | object | Campo de solicitud en llamadas guiadas de seguimiento: haga eco del collection de la respuesta anterior para continuar con la misma evaluación. |
authentication_result / fraud_result | object | Campo de solicitud: el resultado del paso que acaba de realizar. |
recommendation.status | Enumeración | awaiting_authentication, awaiting_fraudo completed. |
recommendation.next_step.type | Enumeración | authentication, fraud, processo decline. |
recommendation.next_step.authentication_type | Enumeración | presente cuando type = authentication. |
recommendation.next_step.failover | objeto | nulo | Copia de seguridad opcional para un paso de autenticación. |
recommendation.next_step.provider | string | presente cuando type = process — el proveedor de pago a utilizar. |
Ambos modos están respaldados por las mismas reglas y producen las mismas decisiones: el modo guiado simplemente le pide a DEUNA un paso a la vez en lugar de devolver todo el plan desde el principio.
Tarjeta de identificación en /triggers
la tarjeta en payment_source.card_info se puede suministrar una de tres maneras:
| Método | Campos | Notas |
|---|---|---|
| PAN completo | card_number | BIN y marca se derivan del lado del servidor. |
| BIN + últimos cuatro | bin (8 dígitos), last_four | Úselo cuando no transmita el PAN completo. BIN de 8 dígitos proporciona enrutamiento a nivel de emisor. |
| token de red | network_token: { dpan, par, account_bin, cryptogram, eci } | Para credenciales tokenizadas. Consulte la nota a continuación sobre cómo obtener datos a nivel BIN. |
Comentarios attempts ejemplo
attempts informa lo que realmente sucedió: el resultado de la autenticación, luego el resultado del pago de su proveedor de pago (códigos ISO 8583).
{
"collection": { "id": "c7b9e3a2-4d51-4f8a-9b21-6e0f2a1c8d34", "prediction_id": "pred_xyz789abc" },
"transaction_id": "1b3d5f7a-8c9e-40a2-b1c3-d4e5f6a7b8c9",
"attempts": [
{
"step": "authentication",
"authentication_type": "3ds_authentication",
"result": { "eci": "05", "pares_status": "Y", "liability_shift": true }
},
{
"step": "payment",
"provider": "acquirer_gateway",
"result": { "status": "declined", "error_code": "05", "error_reason": "do_not_honor" }
}
]
}
error_codeutiliza códigos de respuesta ISO 8583, p."05"= no honrar.eciypares_statusllevar el resultado 3DS;liability_shiftindica si la autenticación transfirió la responsabilidad.
Autenticación de respaldo (conmutación por error)
Las reglas pueden definir un conmutación por error proveedor de autenticación. si lo recomendado primary El proveedor no está disponible (por ejemplo, el proveedor de autenticación 3DS está inactivo), la recomendación devuelve el failover (por ejemplo, solo datos 3DS) para que una interrupción del proveedor nunca deje una transacción sin autenticar.
¿Preguntas o detalles faltantes? Contacta con tu equipo de integración DEUNA.