Moteur recommandé
Ce guide documente l'API de gestion des règles du moteur de recommandation DEUNA, orientée vers les marchands. Une règle combine les conditions avec une liste ordonnée de fournisseurs de paiement, de fraude ou d'authentification et des règles facultatives pondérées pour les tests A/B. Les règles sont évaluées par priorité jusqu'à ce qu'une seule rencontre soit faite.
Sur cette page
Moteur de recommandation
Définissez le parcours ordonné des fournisseurs évalué pour une règle correspondante.
Authentification#
Tous les paramètres authentifient avec un Clé API envoyé dans le X-Api-Key header — c'est le seul système d'authentification supporté. Votre marchand est résolu à partir de la clé API, donc l'identificateur du marchand pas apparaît dans l'URL.
X-Api-Key: {{DEUNA's API Key}}
X-Idempotency-Key: {{UUID v4}}
Content-Type: application/json| En-tête | Obligatoire | Descriptif |
|---|---|---|
X-Api-Key | Oui | Votre clé API. Déterminer l'environnement et la portée marchande. |
Content-Type | Oui | application/json. |
X-Idempotency-Key | Recommandé | Une clé unique que vous générez par requête logique (un UUID fonctionne bien). Reessayer avec la même clé renvoie le résultat original au lieu d'appliquer l'opération deux fois — l'envoyer donc les rétries réseau ne créent jamais de règles dupliquées ou double-compte une action. |
Résumé du point de fin#
| Méthode | Chemin | Objectif |
|---|---|---|
GET | /routing/v1/rules | Liste de toutes les règles (ordre de priorité) |
POST | /routing/v1/rules | Créer une règle |
GET | /routing/v1/rules/{rule_id} | Get a single rule by ID |
PUT | /routing/v1/rules/{rule_id} | Mettre à jour une règle (remplacer complètement) |
PUT | /routing/v1/rules/{rule_id}/reorder | Changer la priorité d'une règle |
Paramètres de trajectoire :
| Paramètre | Tapez | Remarques |
|---|---|---|
rule_id | integer | Identificateur de règles numériques retourné par create/list. |
Objet de la règle#
Une règle est la ressource de base renvoyée et acceptée par ces paramètres.
| Champ | Tapez | Obligatoire | Descriptif |
|---|---|---|---|
id | integer | Réponse seulement | Identifiant de règle attribué au serveur. |
label | string | Oui | Nom de la règle lisible par l'homme. |
data_type | string | Oui | Famille de méthodes Cette règle s'applique : credit_card, debit_card, prepaid_card. |
priority | integer | Oui | Ordre d'évaluation — moins de manches en premier, premier match gagne (nombres non négatifs) |
status | énumération | Oui | enabled, disabled, draft |
is_default | boolean | Oui | Si trueC'est la règle de repli quand aucun autre match. Une règle par défaut doit avoir Non, je ne sais pas. conditions et ne doivent pas fixer ignore_next_rules. |
trigger | énumération | Oui | payment, reject, ou merchant_rule. Voir Déclencheurs. |
conditions | array<Condition> | Conditionnel | Critères de correspondance, ET combinés. Requise sauf is_default = true. |
members | array<Member> | Conditionnel | Les fournisseurs ont ordonné de tenter. Requis pour payment; requis (ou children) pour merchant_rule; interdit de reject. |
children | array<Child> | Facultatif | Branches d'enfants pondérées pour le test A/B (uniquement avec trigger = merchant_rule). |
ignore_next_rules | boolean | Oui | Si true, arrêtez d'évaluer d'autres règles quand celle-ci correspond. Interdit de reject et pour les règles par défaut. |
created_at | chaîne de caractères (RFC3339) | Réponse seulement | L'horodatage de la création. |
Déclencheurs
trigger | Signification | members | children | ignore_next_rules | is_default |
|---|---|---|---|---|---|
payment | Acheminez le paiement vers les fournisseurs énumérés. | Requis (≥1) | Non autorisé | Autorisé | Autorisé |
reject | Bloquez la transaction. | Non autorisé | Non autorisé | Non autorisé | Non autorisé |
merchant_rule | Groupe/branche: itinéraire via les membres ou les enfants pondérés. | Nécessaire si aucun enfant | Autorisé | Autorisé | Autorisé |
Objet de la condition#
Les conditions définissent ce qu'une transaction doit correspondre. Toutes les conditions d'une règle sont combinées avec AND.
| Champ | Tapez | Obligatoire | Descriptif |
|---|---|---|---|
id | integer | Réponse seulement | ID de l'état attribué au serveur. |
rule_option | object | Oui | Le champ à correspondre, par exemple { "id": 5, "label": "currency" }. Utiliser une option de règle à la disposition du marchand; id doit être > 0. |
operator | énumération | Oui | Opérateur de comparaison. Doit être valide pour cette option de règle |
operand | string | Conditionnel | La ou les valeurs à comparer, toujours sérialisée comme une chaîne. Le format dépend de l'opérateur. Requis pour chaque opérateur sauf is_present, qui ne prend pas d'opérande. |
operand_type | string | Non | values (par défaut) ou list (operand référence une liste personnalisée par UUID). |
operand_config | objet .. null | Conditionnel | Utilisée lorsque operand_type = list: { "custom_list": { "field_to_evaluate": "email" } }. |
metadata_field_name | chaîne -0 null | Conditionnel | Obligatoire quand rule_option.id = 16 (metadata) . La clé de métadonnées à évaluer. |
metadata_field_type | chaîne -0 null | Conditionnel | Obligatoire quand rule_option.id = 16. Une des text, numeric. |
error_code | string | Réponse seulement | Régler lorsque le traitement async d'une condition (par exemple l'importation de la liste) a échoué. |
error_message | string | Réponse seulement | Détails lisibles par l'homme pour error_code. |
Exemple — correspondre aux cartes de marque Mastercard
{
"rule_option": { "id": 3, "label": "branch" },
"operator": "in",
"operand": "mastercard"
}Objet du Membre#
Les membres sont les fournisseurs d'une règle appariée, sort ordre (la cascade). Références d'un membre une prestataire — a prestataire de paiement, une fournisseur de fraudeou une fournisseur d'authentification.
| Champ | Tapez | Obligatoire | Descriptif |
|---|---|---|---|
payment_provider_id | integer | Conditionnel | DÉUNA identifiant du fournisseur de paiement. Requis si merchant_payment_provider_id Instrument et données de connexion utilisés pour traiter le paiement. |
payment_provider_name | string | Réponse seulement | Nom du fournisseur (échoué). |
merchant_payment_provider_id | UUID | Conditionnel | La connexion spécifique du fournisseur de Merchant. Si envoyé, payment_provider_id doivent être également envoyé. |
merchant_payment_provider_name | string | Réponse seulement | Nom de connexion (échoed back). |
fraud_provider | string | Conditionnel | Nom du fournisseur de services de lutte contre la fraude. Exclusivité mutuelle avec les champs de paiement et d'authentification-fournisseur. |
fraud_provider_id | string | Réponse seulement | Identification du fournisseur de fraude (échoué). |
authentication_provider | string | Conditionnel | Nom du fournisseur d'authentification (p. ex. UNICO_ID, CYBERSOURCE_3DS). mutuellement exclusive avec les domaines de paiement et de fraude-fournisseur. |
authentication_provider_id | string | Réponse seulement | ID du fournisseur d'authentification (échoué). |
authentication_type | énumération | Conditionnel | La méthode d'authentification. Une des 3ds_authentication, 3ds_data_only, unico_id. Obligatoire lorsque le membre est un fournisseur d'authentification. |
failover | objet .. null | Facultatif | Authentification de sauvegarde utilisée lorsque le fournisseur principal n'est pas disponible : { "authentication_provider": "...", "authentication_type": "..." }. Valide seulement sur les membres fournisseurs d'authentification. |
sort | integer | Oui | Ordre de cascade. Ça doit être unique. dans le respect de la règle. |
strategy | énumération | Oui | Actuellement, seulement cascade. |
capabilities | array<string> | Oui | Capacités des fournisseurs à utiliser, p. ex. ["3ds"]. Envoyer [] si aucune. |
enabled3ds | boolean | Non | Demander l'authentification 3DS sur ce membre (créer une charge utile). |
post_authorization | boolean | Oui | Seulement un fraude le fournisseur peut définir true, et il doit être le dernier par sort. |
shadow_mode | boolean | Oui | Évaluer le fournisseur sans affecter la route (essai sécuritaire). |
enabled | boolean | Réponse seulement | Si le fournisseur est actuellement à la disposition du marchand. |
Exemple — Membre prestataire de paiement
{
"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
}Exemple — membre fournisseur de services de fraude
{
"sort": 1,
"strategy": "cascade",
"fraud_provider": "CYBERSOURCE",
"capabilities": [],
"post_authorization": false,
"shadow_mode": false
}Exemple — membre fournisseur d'authentification (avec décrochage)
{
"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
}Essais A/B — trafic divisé entre deux voies#
Ajouter deux au test A/B itinéraires à une règle (comme children) et donnent chacun un pourcentage weight. Le moteur envoie cette part des transactions correspondantes à chaque itinéraire — par exemple: 70 % jusqu'à la route A, 30 % jusqu'à la route B — pour pouvoir les comparer sur le trafic en direct.
| Champ | Tapez | Obligatoire | Descriptif |
|---|---|---|---|
weight | integer | Oui | Pourcentage de trafic correspondant envoyé à cette route. Les poids des deux routes doivent être 100. |
members | array<Member> | Oui | Le ou les fournisseurs de cette route. |
Règles:
- Exactement. deux routes.
weightvaleurs doivent être égales à 100.- La règle doit être définie
ignore_next_rules: true. - L'affectation est collant par
transaction_id(une transaction obtient toujours la même route), et la route qui a couru est repris dans le/triggersresponse.
Exemple — 70/30 fractionnement
{
"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" }
]
}
]
}Créer une règle#
POST /routing/v1/rules
L'exemple ci-dessous crée un merchant_rule pour les cartes de crédit Mastercard dans MXN, effectue un contrôle de fraude, puis des succursales par fraud_risk: bloc high, et itinéraire medium/low à 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))
}Renvoie la commande traitée avec son 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}
Retourne une seule règle, y compris conditions, members et n'importe quelle children. rule_id est l'identificateur numérique.
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))
}Renvoie la commande traitée avec son 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
}
]
}Erreurs : PAYROU-NOT_FOUND (404) si la règle n'existe pas; PAYROU-FORBIDDEN (403) si elle n'est pas accessible; PAYROU-INVALID_PATH_PARAM (400) si rule_id n'est pas un entier valide.
Règles de liste#
GET /routing/v1/rules
Règles de retour pour votre marchand en ordre de priorité. Les résultats sont paginés avec un curseur opaque.
| Paramètre de requête | Tapez | Descriptif |
|---|---|---|
limit | integer | Facultatif. Taille de la page. Par défaut 50, maximum 200. |
cursor | string | Facultatif. Un curseur opaque d'une réponse précédente pagination.next_cursor- Omettre pour la première page. |
payment_provider_id | integer | Facultatif. Retourner seulement les règles qui font référence à ce fournisseur de paiement. |
La réponse enveloppe les règles dans un pagination Objet. Continuer de demander avec next_cursor pendant has_more est true.
pagination champ | Tapez | Descriptif |
|---|---|---|
next_cursor | chaîne -0 null | Curseur pour la page suivante, ou null à la dernière page. |
has_more | boolean | true si d'autres règles sont disponibles. |
limit | integer | La taille de la page qui a été appliquée. |
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))
}Renvoie la commande traitée avec son 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"
}
]
}Mettre à jour une règle#
PUT /routing/v1/rules/{rule_id}
Remplacez la règle. Envoyer le corps de règle complet — la même forme que créer — y compris id et created_at. Usage courant: flip status entre enabled et disabled (c'est ainsi que vous «retirez» une règle au lieu de la supprimer).
cURL — invalidation d'une règle
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))
}Renvoie la commande traitée avec son 200
Renvoie la règle mise à jour avec status Maintenant disabledNote: État ids sont réédités à jour.
Changer la priorité d'une règle (réorganiser)#
PUT /routing/v1/rules/{rule_id}/reorder
Déplace une règle vers une nouvelle priorité. D'autres règles sont réséquemment appliquées en conséquence.
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))
}| Champ | Tapez | Obligatoire | Contrainte |
|---|---|---|---|
priority | integer | Oui | Non-negative integer |
Renvoie la commande traitée avec son 200
{ "priority": 2 }Erreurs : PAYROU-VALIDATION (400) avec errors[].code = PRIORITY_OUT_OF_RANGE si priority n'est pas un entier non négatif.
Validations#
Créer et mettre à jour lancez ces vérifications. Toute défaillance retourne HTTP 400 avec code de niveau supérieur PAYROU-VALIDATION et une entrée par champ contrevenant errors[] (voir Erreurs pour l'enveloppe et le catalogue complet de codes de champ).
Niveau de règle
statusdoit être l'une desenabled,disabled,draft,process-in-background.triggerdoit être l'une despayment,reject,merchant_rule.trigger = payment→ au moins un membre; pas d'enfants.trigger = reject→ pas de membres, pas d'enfants,ignore_next_rulesdoit être faux,is_defaultdoit être faux.trigger = merchant_rule→ au moins un membre ou au moins un enfant.is_default = true→ aucune condition etignore_next_rulesdoit être faux.is_default = false→ au moins une condition.prioritydoit être> 0et≤ 1000.
Conditions
rule_option.idnécessaire (> 0);operandrequis (non vide).operatordoit être valide pour cette option de règle (voir catalogue).- Un
rule_optionpeut apparaître qu'une seule fois par règle (saufmetadata). - Pour
metadata(id 16):metadata_field_nameetmetadata_field_typerequis; le type doit être:textounumeric. - Pour
operand_type = list:operanddoit être une liste UUID valide qui existe.
Membres
- Chaque membre doit mentionner exactement un type de fournisseur : paiement, paiement marchand, fraude ou authentification.
- Les types de fournisseurs ne peuvent être mélangés sur un seul membre.
- Si
merchant_payment_provider_idest présent,payment_provider_iddoit également être présent. - Les membres d'authentification doivent
authentication_type(l'un des3ds_authentication,3ds_data_only,unico_id). failoverest valide seulement sur les membres d'authentification;authentication_typedoit également être une valeur valide.sortdoit être unique dans la règle.- Un fournisseur ne peut apparaître qu'une seule fois par règle.
strategydoit êtrecascade.post_authorization = trueuniquement pour les fournisseurs de services de fraude, et ce membre doit être dernier parsort.
Niveau de service (vérifié en fonction de la configuration du marchand)
- L'option de règle référencée doit exister et soutenir l'opérateur donné.
- Le fournisseur de paiement/paiement/fraude/authentification doit être activé pour le commerçant.
merchant_payment_provider_iddoit appartenir à lapayment_provider_id.
Erreurs#
enveloppe d'erreur
Chaque réponse d'erreur utilise la même forme 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'."
}
]
}| Champ | Tapez | Descriptif |
|---|---|---|
code | string | Code de niveau supérieur stable et lisible par machine. Branche sur ce, jamais sur message. |
message | string | Résumé lisible par l'homme. Peut être reformulé ou localisé — ne l'analysez pas. |
request_id | string | Unique par réponse et aussi retourné dans le X-Request-Id en-tête de réponse (sur succès) et erreur). Citation dans toute demande d'assistance. |
errors | array | Présent uniquement pour PAYROU-VALIDATION. Une entrée par champ criminel. |
errors[].field | string | Voie vers le champ, en utilisant la notation point/bracket — par exemple priority, conditions[1].operand, members[0].sort. |
errors[].code | string | Code de champ stable (voir Codes de validation). |
errors[].message | string | Un détail lisible par l'homme. Ne pas analyser. |
Toujours envoyer un
X-Idempotency-Keysur écrit. Rejouer la même clé renvoie la réponse originale; réutiliser une clé avec une différent retour du corps409 PAYROU-CONFLICT.
Codes d'état HTTP
| Statut | Signification |
|---|---|
200 / 201 | Success. |
400 | La demande est invalide — validation échouée, JSON mal formée, ou mauvais params chemin/query. |
401 | Authentification échoué — X-Api-Key est manquant ou invalide. |
403 | Autorisation La clé est valide, mais elle n'est pas autorisée à accéder à ce marchand/source. |
404 | La règle ou une ressource référencée n'existe pas. |
409 | Conflit — réutilisation de clé idempotency avec un organisme différent, ou mise à jour simultanée. |
429 | Taux maximal dépassé — réessayer après la Retry-After header. |
500 | Erreur inattendue du serveur. |
503 | Une dépendance en aval est temporairement indisponible — sans danger pour la réessayer avec le recul. |
Codes de premier niveau
| Code | HTTP | Quand |
|---|---|---|
PAYROU-VALIDATION | 400 | Un ou plusieurs champs ont échoué à la validation. Détails dans errors[]. |
PAYROU-MALFORMED_JSON | 400 | Le corps de demande n'est pas valide JSON. |
PAYROU-INVALID_PATH_PARAM | 400 | Un paramètre chemin est le mauvais type/format (par exemple non entier) rule_id). |
PAYROU-INVALID_QUERY_PARAM | 400 | Un paramètre de requête est invalide (par exemple : limit hors de portée, mal formé cursor). |
PAYROU-UNAUTHENTICATED | 401 | Clé API manquante ou invalide. |
PAYROU-FORBIDDEN | 403 | Clé valide, mais non étendue à ce marchand/ressource. |
PAYROU-NOT_FOUND | 404 | Règle ou ressource référencée non trouvée. |
PAYROU-CONFLICT | 409 | Réemploi de clé d'urgence avec une charge utile différente, ou modification simultanée. |
PAYROU-RATE_LIMITED | 429 | Trop de demandes. |
PAYROU-INTERNAL | 500 | Erreur inattendue du serveur. |
PAYROU-UPSTREAM_UNAVAILABLE | 503 | Une dépendance en aval est temporairement indisponible. |
Codes de validation
Retour à l'intérieur errors[] lorsque le code de niveau supérieur est PAYROU-VALIDATION. Chacun est stable et sûr à brancher.
Niveau de règle
code | Typique field | Cause |
|---|---|---|
INVALID_STATUS | status | Pas un des enabled, disabled, draft, process-in-background. |
INVALID_TRIGGER | trigger | Pas un des payment, reject, merchant_rule. |
PRIORITY_OUT_OF_RANGE | priority | Pas entre 1 et 1000 (couvre les deux ≤ 0 et > 1000). |
MEMBERS_REQUIRED | members | trigger = payment sans membres. |
MEMBERS_OR_CHILDREN_REQUIRED | members | trigger = merchant_rule avec ni membres ni enfants. |
CONDITIONS_REQUIRED | conditions | Règle de non-défaut sans conditions. |
TRIGGER_CANNOT_BE_DEFAULT | is_default | reject règle avec is_default = true. |
TRIGGER_CANNOT_HAVE_MEMBERS | members | reject de la loi avec les membres. |
TRIGGER_CANNOT_HAVE_CHILDREN | children | payment/reject règnent avec les enfants. |
TRIGGER_CANNOT_IGNORE_NEXT_RULES | ignore_next_rules | reject règle avec ignore_next_rules = true. |
DEFAULT_RULE_CANNOT_HAVE_CONDITIONS | conditions | Règle par défaut avec conditions. |
DEFAULT_RULE_CANNOT_IGNORE_NEXT_RULES | ignore_next_rules | Règle par défaut avec ignore_next_rules = true. |
Conditions
code | Typique field | Cause |
|---|---|---|
RULE_OPTION_ID_REQUIRED | conditions[i].rule_option.id | Manque ou ≤ 0. |
OPERAND_REQUIRED | conditions[i].operand | Opérateur vide pour un opérateur qui en a besoin. |
OPERATOR_REQUIRED | conditions[i].operator | L'opérateur est vide. |
INVALID_OPERATOR | conditions[i].operator | Opérateur non valide pour cette option de règle. |
DUPLICATE_RULE_OPTION | conditions[i].rule_option | Même option de règle utilisée plus d'une fois (sauf metadata). |
METADATA_FIELDS_REQUIRED | conditions[i].metadata_field_name | metadata État manquant metadata_field_name/metadata_field_type. |
INVALID_METADATA_FIELD_TYPE | conditions[i].metadata_field_type | Pas text ou numeric. |
RULE_OPTION_NOT_FOUND | conditions[i].rule_option.id | L'option règle n'existe pas. |
INVALID_LIST_REFERENCE | conditions[i].operand | operand_type = list mais la liste UUID est invalide ou non trouvée. |
Membres
code | Typique field | Cause |
|---|---|---|
MEMBER_PROVIDER_REQUIRED | members[i] | Les membres ne font référence à aucun fournisseur (paiement, fraude ou authentification). |
MEMBER_MULTIPLE_PROVIDER_TYPES | members[i] | Les membres mélangent les types de fournisseurs (p. ex. paiement + fraude, ou paiement + authentification). |
PAYMENT_PROVIDER_ID_REQUIRED | members[i].payment_provider_id | merchant_payment_provider_id envoyé sans payment_provider_id. |
AUTHENTICATION_TYPE_REQUIRED | members[i].authentication_type | Membre d'authentification sans authentication_type. |
INVALID_AUTHENTICATION_TYPE | members[i].authentication_type | Pas un des 3ds_authentication, 3ds_data_only, unico_id (s'applique failover.authentication_type aussi). |
FAILOVER_ONLY_ON_AUTHENTICATION | members[i].failover | failover fixé sur un membre non-authentificateur. |
DUPLICATE_MEMBER | members[i] | Le même fournisseur apparaît plus d'une fois dans la règle. |
DUPLICATE_MEMBER_SORT | members[i].sort | Deux membres partagent une sort value. |
INVALID_STRATEGY | members[i].strategy | Pas cascade. |
POST_AUTH_ONLY_FRAUD | members[i].post_authorization | post_authorization = true sur un membre non frauduleux. |
POST_AUTH_MUST_BE_LAST | members[i].post_authorization | Le post_authorization membre n'est pas le dernier par sort. |
PROVIDER_NOT_AVAILABLE | members[i] | Le fournisseur (paiement, fraude ou authentification) n'est pas autorisé pour ce marchand. |
MERCHANT_PROVIDER_MISMATCH | members[i].merchant_payment_provider_id | La connexion n'appartient pas à la donnée payment_provider_id. |
Essais A/B
code | Typique field | Cause |
|---|---|---|
SPLIT_WEIGHTS_MUST_SUM_TO_100 | children | Enfant weight valeurs ne se résument pas à 100. |
Débit de bout en bout#
Le /triggers prise en charge du paramètre deux modes d'intégration — choisissez la valeur de la logique de décision que vous voulez posséder. Les deux utilisent le même paramètre et les mêmes règles; seule la forme de la réponse et le nombre d'appels diffèrent. Sélectionnez-le avec mode sur la demande (single est la valeur par défaut). Dans tous les cas, tu fermes la boucle avec un /feedback call.
| Mode | Comment ça marche | Meilleur quand |
|---|---|---|
| 1 · Appel unique (guichets du client) | Une /triggers appel retourne le plan complet — l'authentification à exécuter (avec décrochage) et actions qui cartographient chaque résultat à processus ou _déclin_Tu exécutes le plan toi-même. | Vous voulez les moins de aller-retour et êtes à l'aise d'appliquer la décision localement. |
| 2 · Guidée (moteur) | Vous appelez /triggers et le moteur ne retourne que le prochaine étape + status. Vous l'exécutez, puis appelez /triggers encore avec le résultat de cette étape; le moteur retourne l'étape suivante. Répéter jusqu'à status = completed. | Vous voulez que DEUNA possède et centralise la logique de décision, étape par étape. |
Mode 1 — appel unique
Vous faites une unique /triggers Appelez. Si vous lancez un fournisseur de fraude avant DEUNA, incluez son résultat dans cet appel. La réponse est autonome : elle donne le nom de l'authentification à exécuter (avec Défaut si le primaire n'est pas disponible) et Mesures prises que map le résultat d'authentification à ce qu'il faut faire ensuite — processus avec un prestataire de paiement ou déclin. Votre plateforme exécute ce plan localement et ferme la boucle avec un /feedback appel — il y a pas de seconde /triggers aller-retour.
Étape par étape
- (facultatif) Score avec un fournisseur de fraude. Si votre configuration utilise un fournisseur de fraudes à l'avant, capturez sa partition/décision afin qu'il puisse être assorti par des règles (via le
fraud_riskoption oumetadata). - Demander la recommandation (un appel).
POST /routing/v1/triggersavec les données de transaction (et le résultat de la fraude, le cas échéant). La réponse contient uneauthenticationbloc (primary+ optionnelfailover) et uneactionsblock. - Authenticate. Exécutez l'authentification recommandée (par exemple Authentification 3DS, Données 3DS seulement, ou Unico ID). Si le
primaryfournisseur est indisponible, utiliser lefailover. - Décider et procéder. Appliquer
actions: chaque carte des résultatsprocess(avec le prestataire de paiement désigné dans l'action) oudecline; lesdefaultl'action s'applique lorsqu'aucun autre résultat ne correspond. - Rapportez les résultats.
POST /routing/v1/feedbackaveccollectionobjet etattempts(Résultat de l'authentification + résultat du paiement). Ceci ferme la boucle pour l'analyse et l'étiquetage ML.
Les commerçants avec un seul fournisseur de paiement verront un seul fournisseur dans le
processaction; les marchands avec plusieurs peuvent configurer une cascade dans la règlemembers, et la recommandation reflète le ou les fournisseurs à tenter.
Réponse du mode 1 — le plan complet
Le /triggers réponse est une recommandation unique, autonome: authentication à courir (avec un optionnel failover) et les actions que map le résultat d'authentification à ce qu'il faut faire. Votre plateforme exécute cela localement.
{
"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" }
}
}
}| Champ | Tapez | Descriptif |
|---|---|---|
collection.id | UUID | Identification de corrélation pour cette évaluation. Faites-le entrer. /feedback. |
collection.prediction_id | string | ML poignée pour la recommandation. Faites-le entrer. /feedback. |
recommendation.rule_id | integer | La règle qui correspond (même identifiant que l'objet de la règle id). |
recommendation.rule_label | string | Nom de la règle lisible par l'homme. |
recommendation.authentication.primary | object | L'authentification pour exécuter en premier: { "authentication_type": "3ds_authentication" }. Utilise la même authentication_type les valeurs en tant que membres de la règle. |
recommendation.authentication.failover | objet .. null | Authentification de sauvegarde si le primaire n'est pas disponible. |
recommendation.actions | object | Trace le résultat d'authentification à une action. Clôturé par le résultat. |
recommendation.actions.<outcome>.action | énumération | process ou decline. |
recommendation.actions.<outcome>.provider | string | Présente quand action = process — le nom du prestataire de paiement à utiliser, tel que configuré dans votre règle (par exemple: acquirer_gateway). |
recommendation.actions.default | object | L'action de repli s'applique lorsqu'aucune autre clé de résultat ne correspond. |
Clés de résultat sous actions décrire le résultat d'authentification auquel ils s'appliquent (p. ex. on_success_with_liability_shift); default est le piège.
Mode 2 — guidé (étape par étape)
Renseignez "mode": "guided" sur demande. Au lieu du plan complet, le moteur retourne le prochaine étape et un status, et vous conduisez le flux une étape à la fois:
status: awaiting_authentication→next_stepvous indique l'authentification à exécuter.status: awaiting_fraud→next_stepvous dit quel contrôle de fraude à courir.status: completed→ le moteur a décidé;next_step.actionestprocess(avecprovider) oudecline.
Après avoir fait une étape, appelez /triggers encore — faire écho au collection de la réponse précédente et inclure le résultat de cette étape (authentication_result ou fraud_result) . Le moteur avance et retourne l'étape suivante. Répéter jusqu'à status = completed, puis à proximité /feedback.
Première réponse — une étape à accomplir
{
"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" }
}
}
}Demande de suivi — afficher le résultat de l'étape
{
"mode": "guided",
"collection": { "id": "c7b9e3a2-4d51-4f8a-9b21-6e0f2a1c8d34", "prediction_id": "pred_xyz789abc" },
"authentication_result": { "eci": "05", "pares_status": "Y", "liability_shift": true }
}Réponse du 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" }
}
}| Champ | Tapez | Descriptif |
|---|---|---|
mode | énumération | Champ de demande: single (par défaut) ou guided. |
collection | object | Demande de champ sur les appels guidés de suivi : collection de la réponse précédente pour poursuivre la même évaluation. |
authentication_result / fraud_result | object | Champ de demande : le résultat de l'étape que vous venez d'effectuer. |
recommendation.status | énumération | awaiting_authentication, awaiting_fraud, ou completed. |
recommendation.next_step.type | énumération | authentication, fraud, process, ou decline. |
recommendation.next_step.authentication_type | énumération | Présente quand type = authentication. |
recommendation.next_step.failover | objet .. null | Sauvegarde optionnelle pour une étape d'authentification. |
recommendation.next_step.provider | string | Présente quand type = process — le prestataire de paiement à utiliser. |
Les deux modes sont soutenus par les mêmes règles et produisent les mêmes décisions — le mode guidé demande simplement à DEUNA une étape à la fois au lieu de renvoyer l'ensemble du plan à l'avant.
Identification de la carte /triggers
La carte est payment_source.card_info peut être fourni une des trois façons:
| Méthode | Champs | Remarques |
|---|---|---|
| PAN complet | card_number | BIN et marque sont dérivés côté serveur. |
| BIN + quatre derniers | bin (8 chiffres), last_four | Utilisez quand vous ne transmettez pas le PAN complet. Le BIN à 8 chiffres donne un routage au niveau de l'émetteur. |
| Jeton réseau | network_token: { dpan, par, account_bin, cryptogram, eci } | Pour des lettres de créances symboliques. Voir la note ci-dessous sur l'obtention des données de niveau BIN. |
Commentaires attempts exemple
attempts rapporte ce qui s'est réellement passé : le résultat d'authentification, puis le résultat de paiement de votre fournisseur de paiement (codes 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_codeutilise les codes de réponse ISO 8583 — par exemple"05"= ne pas honorer.ecietpares_statusde porter le résultat 3DS;liability_shiftindique si la responsabilité d'authentification a changé.
Authentification de sauvegarde (échec)
Les règles peuvent définir une Défaut fournisseur d'authentification. Si la recommandation est faite primary fournisseur est indisponible (p. ex., le fournisseur d'authentification 3DS est en panne), la recommandation retourne le failover (p. ex., données 3DS seulement) de sorte qu'une panne de fournisseur ne laisse jamais une transaction sans authentification.
Des questions ou des détails manquants ? Contactez votre équipe d'intégration DEUNA.