Contrôle de conformité (compliance_check)
Un compliance_check est une trace immutable et autonome d'une vérification de conformité effectuée sur un sujet. Il peut être rattaché à un dossier d'onboarding ou à une exécution de processus, mais ces contextes sont optionnels. Il enregistre qui a été vérifié, le provider lorsqu'il existe, le résultat et sa durée de validité.
Rôle
Le check constitue l'unité élémentaire de traçabilité KYC/KYB et de conformité. Il peut être produit pendant un onboarding, lors d'un checkout, par un contrôle continu, par une action manuelle ou être importé depuis un système externe. Lorsqu'il est rattaché à un dossier d'onboarding, il apparaît également dans le tableau checks de GET /v1/onboarding-cases/:id.
check_type et scope sont des chaînes libres. Le champ provider est lui aussi libre lorsqu'un prestataire externe a produit le contrôle, mais reste null pour un contrôle manuel sans provider identifié.
Identifiant et structure
Chaque check porte un identifiant stable préfixé par cpc_.
{
"object": "compliance_check",
"id": "cpc_9a8b7c6d5e4f3a2b",
"onboarding_case_id": "obc_3f8a1d9c2b4e7f6a",
"process_instance_id": "pci_1b2c3d4e5f6a7b8c",
"node_id": "kyc_identity_check",
"subject_type": "contact",
"subject_id": "ctc_d12e3f4a5b6c7d8e",
"scope": "director",
"check_type": "kyc",
"provider": "stripe_identity",
"result": "passed",
"raw_response": {
"verification_session": "vs_1Abc2Def",
"status": "verified"
},
"valid_until": "2028-06-17T00:00:00.000Z",
"source_reference": null,
"metadata": {},
"checked_at": "2026-06-17T10:15:00.000Z",
"created_at": "2026-06-17T10:00:00.000Z"
}Sujet du contrôle
Chaque check cible exactement un sujet, identifié par la combinaison subject_type + subject_id.
| subject_type | subject_id | Objet ciblé | Usage typique |
|---|---|---|---|
company | cmp_… | company | Contrôles portant sur l'entreprise elle-même : KYB, sanctions, réputation. |
contact | ctc_… | contact | Contrôles portant sur une personne physique : KYC, liveness, PEP. |
contact_role | ctr_… | contact_role | Contrôles portant sur un rôle spécifique : vérification de l'UBO déclaré, pouvoir du représentant. |
Le sujet détermine le marchand propriétaire du contrôle. Si un onboarding_case_id ou un process_instance_id est renseigné, ce contexte doit appartenir au même marchand. Un check de type contact_role (contact_role) est utile lorsque la vérification porte sur la fonction exercée par une personne plutôt que sur la personne elle-même.
Dimensions libres
check_type et scope sont des dimensions métier libres. provider est une dimension de provenance externe optionnelle :
| Champ | Description | Exemples courants |
|---|---|---|
check_type | Nature de la vérification | kyc, kyb, sanctions, pep, liveness, adverse_media |
provider | Prestataire externe ayant fourni le contrôle, si applicable | stripe_identity, sumsub ou null |
scope | Périmètre fonctionnel dans le dossier | company, director, beneficial_owner, shareholder |
Ces dimensions permettent de requêter les checks de façon précise via GET /v1/compliance-checks en combinant des filtres :
GET /v1/compliance-checks ?onboarding_case_id=obc_3f8a &subject_type=contact &check_type=kyc &result=passed
Résultat et immutabilité
Le champ result représente l'issue de la vérification. Un check créé avec result: "pending" peut être mis à jour via POST /v1/compliance-checks/:id. Une fois le résultat non-pending, le check devient immutable — toute tentative de mise à jour retourne une erreur 400.
| Résultat | Signification |
|---|---|
pending | Check créé, résultat non encore disponible. Modifiable. |
passed | Vérification réussie. Immutable. |
failed | Vérification échouée. Immutable. |
manual_review | Résultat ambigu, nécessite une révision humaine. Immutable. |
error | Erreur technique lors de la vérification. Immutable. |
Un check peut être créé directement avec un résultat non-pending si le provider répond de façon synchrone. Dans ce cas, l'événement correspondant est émis immédiatement à la création.
Validité
Le champ valid_until permet d'exprimer une durée de validité pour le résultat du check. Passé cette date, le résultat est considéré comme périmé — un nouveau check du même type devrait être effectué pour réentrer en relation avec le sujet ou renouveler son autorisation.
Lorsque valid_until est dépassé sur un résultat métier (passed, failed ou manual_review), Ormuz émet compliance_check.expired. Le champ result n'est pas modifié : le contrôle conserve son résultat historique, mais sa validité temporelle est expirée.
Des durées typiques :
- KYC individuel : 1 à 2 ans selon la réglementation applicable
- Screening sanctions : quelques mois (les listes évoluent fréquemment)
- Données Sirène : 6 mois à 1 an pour les informations d'entreprise
Flux asynchrone
La plupart des providers de vérification sont asynchrones : ils acceptent la demande immédiatement et retournent le résultat via webhook. Le pattern recommandé est de créer le check avec result: "pending", puis de le mettre à jour quand le résultat est disponible.
1. Création immédiate du contrôle avec un résultat en attente
POST /v1/compliance-checks
{
"onboarding_case_id": "obc_3f8a",
"subject_type": "contact",
"subject_id": "ctc_d12e",
"scope": "director",
"check_type": "kyc",
"provider": "stripe_identity",
"result": "pending"
}La création retourne notamment l’identifiant du contrôle et son résultat initial :
{
"id": "cpc_9a8b",
"result": "pending"
}2. Mise à jour après le callback du provider
POST /v1/compliance-checks/cpc_9a8b
{
"result": "passed",
"raw_response": {
"verification_session": "vs_1Abc2Def",
"status": "verified"
}
}La réponse confirme le résultat et entraîne l’émission de compliance_check.passed.
{
"result": "passed"
}onboarding_case_id et process_instance_id sont indépendants et optionnels. Lorsqu'ils sont présents, ils doivent appartenir au même marchand que le sujet. node_id n'est accepté qu'avec un process_instance_id.Dans les processus
Le node has_valid_compliance_check permet de réutiliser un contrôle existant lorsque sa nature, sa fraîcheur et sa période de validité satisfont le besoin du processus. Le sujet peut être un platform.company ou un platform.contact.
La stratégie de sélection est explicite : most_favorable retient le dernier passed éligible lorsqu'il existe, latest fait foi du dernier contrôle éligible, et most_conservative retient le dernier contrôle non-passed lorsqu'il en existe un. Ormuz n'applique donc aucune règle universelle de supersession entre producteurs.
| Paramètre | Type | Description |
|---|---|---|
subject | company | contact | Sujet dont les contrôles de conformité sont évalués. |
check_type | string | Nature du contrôle, par exemple kyc, kyb, aml ou liveness. |
max_age | common.duration | Fraîcheur maximale acceptée. P3M signifie trois mois calendaires. |
scope | string · optionnel | Périmètre fonctionnel à imposer lorsqu'il doit faire partie du critère. |
selection_strategy | enum · avancé | most_favorable, latest ou most_conservative. |
Les routes sont valid et not_valid. La sortie compliance_check expose le contrôle effectivement retenu par la stratégie pour justifier la décision ; elle est absente uniquement lorsqu'aucun contrôle éligible n'existe. La fraîcheur max_age demandée par le processus et le valid_until défini par le producteur restent deux contraintes distinctes.
Événements
| Événement | Déclencheur |
|---|---|
compliance_check.created | Un nouveau contrôle est créé, quel que soit son résultat initial. |
compliance_check.passed | Le contrôle entre dans le résultat "passed". |
compliance_check.failed | Le contrôle entre dans le résultat "failed". |
compliance_check.review_required | Le contrôle entre dans le résultat "manual_review". |
compliance_check.error | Le contrôle entre dans le résultat "error". |
compliance_check.expired | La date valid_until d’un résultat métier est dépassée. |
Une création directement en passed, failed, manual_review ou error émet d'abord compliance_check.created, puis l'événement correspondant au résultat. Un check créé en pending n'émet que created jusqu'à sa résolution.
Si un check en manual_review est rattaché à un onboarding, Ormuz émet ensuite onboarding_case.review_required comme conséquence sur le dossier. Son triggering_check_id identifie le contrôle à l'origine de cette revue ; ce champ reste optionnel car un onboarding peut nécessiter une revue pour d'autres raisons.