Passer au contenu principal
Cette page s’adresse à l’autre partie d’un échange Didit Travel Rule : le VASP contrepartie (ou son équipe d’ingénierie), qui doit envoyer des données Travel Rule à un VASP fonctionnant sur Didit, ou en recevoir de sa part. Toute l’infrastructure décrite ici est une infrastructure publique exploitée par Didit. Vous n’avez besoin ni d’un compte Didit, ni d’une clé API, ni d’une relation commerciale avec Didit pour interopérer : l’intégration la plus complète ne requiert que HTTPS et JSON.

Comment Didit achemine une plateforme d’échange

Lorsqu’un client de Didit envoie un transfert, Didit essaie ces voies dans un ordre de priorité strict et utilise la première qui peut vous atteindre :
Didit ne peut pas recevoir de réponse TRUST et n’accepte pas encore les transferts qui lui sont envoyés via un réseau. Via TRUST, un transfert d’un client de Didit vous parvient, mais votre réponse ne peut pas revenir, et le transfert expire à la date limite de confirmation de l’expéditeur au lieu d’aboutir. Via GTR, VERIFYVASP et SYGNA, Didit lit votre réponse directement sur le réseau, par sa réponse ou en interrogeant le statut du transfert.
Le tableau ci-dessus couvre les transferts envoyés par un client de Didit. Lorsque vous envoyez un transfert à un client de Didit, Didit ne peut le prendre en charge que sous forme de demande d’information de transfert TRP (transfer inquiry), une fois l’hôte TRP public de Didit en service (il ne répond pas encore, voir Endpoints TRP), ou, après règlement, sous forme d’inscription sunrise : aujourd’hui, aucune voie réseau ni aucun canal e-mail ne livre un transfert entrant à un client de Didit. Les voies réseau (GTR, TRUST, VERIFYVASP, SYGNA) passent par une adhésion côté expéditeur. Aujourd’hui, il doit s’agir de l’adhésion propre et connectée du client de Didit : Didit ne détient encore aucune adhésion de plateforme sur ces réseaux et est en cours d’intégration en tant que prestataire. GTR n’est pas inclus par défaut, et la même exigence d’adhésion s’applique aux quatre réseaux. L’expéditeur doit vérifier l’objet networks dans Obtenir les paramètres Travel Rule : didit signifie que l’adhésion de Didit porte cette application en tant que participant en propre sur le réseau, own signifie une adhésion client connectée, off signifie que le routage par la plateforme est désactivé, et unavailable signifie qu’aucun envoi n’est possible sur ce réseau pour l’application pour l’instant. Tant que Didit ne détient pas d’adhésion de plateforme, aucun réseau n’affiche didit. Activer la Travel Rule n’active pas une adhésion réseau. Voir Réseaux Travel Rule pour savoir ce que chaque réseau permet d’atteindre aujourd’hui. Si vous êtes sur l’un de ces réseaux et que le client de Didit détient sa propre adhésion, partagez votre identifiant réseau avec lui : le transfert vous parvient sur le réseau que vous exploitez déjà. Via SYGNA, votre réponse d’autorisation finalise ou refuse le transfert : Didit interroge le statut du transfert toutes les 5 minutes et enregistre aussi https://trp.didit.me/sygna/callbacks/permission/{token}/ comme callback de chaque demande d’autorisation, avec un token généré pour ce transfert. Ce callback se trouve sur l’hôte TRP public de Didit, qui ne répond pas encore aux requêtes. Un permission_status égal à ACCEPTED fait passer le transfert de l’expéditeur à COMPLETED, et REJECTED le fait passer à COUNTERPARTY_VASP_GENERAL_DECLINE, ou à COUNTERPARTY_MISMATCHED_DATA lorsque le reject_code vaut BVRC007 (le nom du bénéficiaire ne correspond pas). Le callback exige votre signature : il répond 401 avec {"status": "INVALID_SIGNATURE"} sans signature valide, 404 pour un token inconnu, et 200 à nouveau pour une décision déjà appliquée. Sans aucune adhésion partagée, TRP est la voie à prévoir : partagez votre Travel Address avec le client de Didit, et ses transferts atteignent votre endpoint TRP. La réponse fournie dans votre réponse à la requête finalise ou refuse immédiatement le transfert ; une réponse envoyée ultérieurement au callback de Didit nécessite l’hôte TRP public de Didit, qui n’est pas encore en service. Lorsqu’aucune voie ne peut vous identifier, Didit exécute une étape de résolution supplémentaire : attribution par analyse blockchain. Le portefeuille de destination est confronté aux données d’analyse blockchain et, s’il est attribué à votre plateforme d’échange ou à votre service de conservation, Didit enregistre votre nom dans son annuaire de VASP et relance les voies avec ce nom. Vous pouvez donc être identifié même lorsque l’expéditeur n’a fourni qu’une adresse. Les transferts attribués ne vous sont acheminés automatiquement que lorsque votre entrée d’annuaire comporte un moyen d’acheminement : un endpoint TRP vérifié, une inscription sur un réseau, ou un contact chargé de la conformité (voir Entrer dans l’annuaire VASP de Didit). La chaîne de résolution complète est donc la suivante : un client de Didit qui a prouvé le contrôle du portefeuille (INTERNAL) et la Travel Address que l’expéditeur a enregistrée pour ce portefeuille, puis les voies de protocole et de réseau, puis l’analyse blockchain.

Travel Addresses

Every Didit VASP with Travel Rule enabled has a Travel Address - une chaîne courte commençant par ta qui encode l’URL de son endpoint personnel d’interrogation de transfert TRP. Les clients Didit consultent la leur dans leurs paramètres Travel Rule et la partagent avec leurs contreparties ; lorsqu’un client Didit vous communique la sienne, vous disposez de tout le nécessaire pour le joindre via TRP. L’encodage suit la convention TRP relative aux Travel Address :
  • Retirez le préfixe ta.
  • Décodez le reste en Base58Check (alphabet Bitcoin, somme de contrôle double-SHA256).
  • Les octets décodés correspondent à l’URL d’interrogation sans son schéma ; ajoutez https:// devant.
  • L’URL contient toujours la paire de paramètres t=i (type : inquiry).
Une Travel Address Didit décodée a l’une de deux formes :
{profile_uuid} identifie le profil VASP hébergé : envoyez vos requêtes concernant les transferts à cette URL via une requête POST, et interrogez d’abord l’endpoint d’identité correspondant pour vérifier l’identité de votre interlocuteur. La seconde forme est une Travel Address par portefeuille : elle désigne un portefeuille du client Didit (receiving_travel_address dans son carnet d’adresses), afin que votre requête atteigne ce portefeuille sans que le client ait à le retrouver par numéro de compte ou nom du titulaire. Elle renvoie 404 une fois le portefeuille supprimé ou enregistré comme appartenant à un autre VASP.

Endpoints TRP

Didit utilise la version 3.2.1 de l’API TRP, à l’URL de base https://trp.didit.me. Tous les endpoints échangent du JSON en HTTPS.
L’hôte TRP public de Didit ne sert pas encore ces endpoints. Tant qu’il ne les sert pas, une demande de transfert TRP ou une demande d’identité TRP adressée à un client de Didit ne peut pas être livrée. Cette section décrit le contrat que cet hôte appliquera une fois en service.
Deux en-têtes TRP sont importants :
  • api-version - la version du protocole TRP que vous utilisez, par exemple 3.2.1. Obligatoire sur les demandes et sur les deux rappels.
  • request-identifier - votre identifiant unique de la requête, renvoyé dans les en-têtes de réponse. Obligatoire sur les demandes et sur les deux rappels.
Une requête adressée aux endpoints de demande ou de rappel sans ces deux en-têtes renvoie 400. Chaque réponse de Didit contient api-version: 3.2.1 et renvoie votre request-identifier.

GET /identity

Renvoie l’identité de l’opérateur de la plateforme. Aucun en-tête n’est requis.

GET /trp/identity//

Renvoie l’identité du VASP précis avec lequel vous êtes sur le point d’échanger. Utilisez-la pour vérifier le nom et le LEI avant d’envoyer des données personnelles. Didit effectue la même vérification dans l’autre sens lorsqu’il initie l’échange : si l’identité signalée par votre endpoint ne correspond pas au LEI ou au nom attendu, l’échange est interrompu.
Renvoie 404 lorsque le profil n’existe pas ou lorsque sa configuration Travel Rule est désactivée.

POST /trp/inquiries//

Soumettez une demande de transfert : vous êtes le VASP donneur d’ordre, et le client de Didit est le VASP bénéficiaire.
Sur ce canal, les actifs sont identifiés par leur DTI, et un DTI identifie un token sur une seule blockchain. Didit associe aujourd’hui BTC (4H95J0R2X), ETH (X9J9K872S) et USDC sur neuf réseaux, et d’autres actifs seront ajoutés au fil du temps. Consultez les identifiants d’actifs TRP pour la liste complète. Une demande dont Didit ne reconnaît pas le DTI est tout de même acceptée et transmise au VASP bénéficiaire avec le DTI comme code d’actif. Une réponse 200 signifie que la demande a été acceptée pour traitement. 400 signifie que des en-têtes TRP sont manquants ou que le corps est invalide. 404 signifie que le profil (ou le portefeuille d’une Travel Address par portefeuille) est inconnu ou désactivé. 422 signifie que la requête utilise une extension TRP : Didit n’en prend en charge aucune, donc un en-tête api-extensions ou une clé extensions dans le corps est refusé. Renvoyer le même request-identifier est idempotent : la demande d’origine est réutilisée au lieu d’être dupliquée. Didit crée ensuite le transfert entrant dans l’application du client et le résout selon le carnet d’adresses de portefeuilles et la politique du client. Il identifie le bénéficiaire par le portefeuille désigné par une Travel Address par portefeuille, sinon par la première adresse de portefeuille dans IVMS101.beneficiary.accountNumber, ou, à défaut, par le nom de beneficiaryPersons[0].naturalPerson parmi les entrées de portefeuille vérifiées du client. La réponse 200 contient la décision lorsque Didit peut la donner immédiatement :
  • {"approved": {"address": "...", "callback": "..."}} lorsque la demande a été approuvée automatiquement. Didit n’envoie pas en plus cette approbation à votre callback.
  • {"rejected": "NOT_ENOUGH_COUNTERPARTY_DATA: inquiry carries no beneficiary identification"} lorsque la demande ne désigne ni le bénéficiaire ni une adresse de portefeuille. Incluez donc toujours les deux.
  • {"version": "3.2.1"} lorsque la décision attend le client de Didit. La résolution arrive alors plus tard, sous la forme d’un POST vers votre URL callback, avec l’un des deux corps ci-dessous.
L’approbation peut être automatique, lorsque le VASP bénéficiaire active l’acceptation automatique et que le bénéficiaire correspond à une entrée de portefeuille vérifiée sur la chaîne de l’actif. Elle peut aussi suivre un examen manuel ou une preuve de propriété du portefeuille côté bénéficiaire. Prévoyez donc un délai entre la demande et la résolution. Une demande ne correspond jamais à un portefeuille que le client de Didit a enregistré comme appartenant à un autre VASP. Le nom de votre VASP, tel qu’indiqué dans originatingVASP, est ce que le client de Didit voit comme VASP donneur d’ordre du transfert. Didit ne fixe aucune échéance pour une demande que vous envoyez, et un client de Didit qui l’annule ne vous envoie aucun rejet. Appliquez donc votre propre délai d’expiration. Après avoir reçu une approbation et diffusé le transfert on-chain, clôturez l’échange en envoyant un POST à l’URL de rappel approved.callback qui vous a été fournie :
Si vous abandonnez le transfert, envoyez plutôt { "canceled": "reason" } à la même URL. txid fait passer le transfert côté bénéficiaire à FINISHED ; canceled le fait passer à CANCELLED. Les deux rappels renvoient 204 une fois traités, 404 pour un token inconnu ou pour un transfert qui n’attend plus ce rappel, et 400 pour un corps qui ne contient aucun des deux champs du rappel.

Traiter les demandes que Didit vous envoie

Lorsqu’un client de Didit vous envoie un transfert via TRP, Didit :
  1. Récupère /identity à la racine de l’hôte de votre URL de demande (https://{your-host}/identity) et vérifie le nom et le LEI déclarés par rapport à ceux que le client attend. Lorsque l’acheminement provient de l’annuaire de Didit, votre /identity doit déclarer le LEI de cette entrée d’annuaire.
  2. Envoie en POST une demande de transfert à votre URL de demande, avec la même structure de corps que ci-dessus : asset.dti, un amount en unités de base sous forme de nombre JSON, un callback et le payload IVMS101.
Seule une réponse 2xx est considérée comme livrée. Une réponse 3xx est refusée, car les redirections ne sont pas suivies. Toute autre réponse est consignée dans la chronologie du transfert du client, avec votre code de statut, par exemple refused by counterparty (HTTP 403): .... Les deux appels transportent les deux en-têtes TRP, et Didit ne suit pas les redirections HTTP sur ces appels : servez donc /identity et l’URL de demande directement. Si /identity est injoignable, ne déclare aucun LEI, déclare un LEI différent de celui fourni par le client, ou déclare un nom qui ne correspond pas, Didit s’arrête avant d’envoyer la demande et le transfert du client passe à COUNTERPARTY_VASP_NOT_REACHABLE. Si l’envoi de la demande échoue ensuite, ou si votre endpoint y répond par un statut 4xx ou 5xx, le transfert passe également à COUNTERPARTY_VASP_NOT_REACHABLE. Le callback de cette demande pointe vers l’endpoint de résolution de Didit (/trp/callbacks/resolution/{token}/). Répondez en envoyant en POST les mêmes corps de résolution que ceux qu’utilise Didit : { "approved": { "address": "...", "callback": "..." } } pour approuver (votre callback est l’URL à laquelle Didit enverra la confirmation on-chain), ou { "rejected": "reason" } pour refuser. Joignez les deux en-têtes TRP à cette requête. Didit répond 204 une fois la requête traitée, 404 lorsque le transfert n’attend plus de résolution, et 400 pour une approbation sans address, ou dont le callback n’est pas une URL http(s) publique que Didit peut appeler. En cas d’approbation, le côté Didit passe à COMPLETED. Une fois que le client signale le hash on-chain, Didit envoie en POST { "txid": "..." } à l’URL de confirmation que vous avez fournie (ou { "canceled": "reason" } si le transfert est annulé auparavant).
Les tokens de rappel sont des secrets dédiés à une seule finalité, impossibles à deviner, générés pour chaque transfert : traitez les URL de rappel complètes comme confidentielles, et notez qu’une résolution n’est acceptée que tant que le transfert attend encore une réponse.

Récupération par e-mail

Si aucun canal protocolaire ne permet de vous joindre et que le client de Didit a fourni l’adresse e-mail de votre service conformité, Didit se rabat sur l’e-mail : votre contact conformité reçoit un message qui nomme le VASP donneur d’ordre, accompagné d’un lien sécurisé de récupération à usage unique. Aucun compte, aucune clé API ni aucune intégration n’est nécessaire : le token du lien fait office d’authentification. L’ouverture du lien affiche l’échange en attente. L’API sous-jacente, que la page hébergée pilote pour vous, est publique :
amount est la valeur décimale enregistrée, telle quelle, et comporte donc les 18 décimales complètes.
decision vaut accept ou decline. En cas d’acceptation, indiquez le nom du bénéficiaire tel qu’il figure dans vos registres, afin que le côté donneur d’ordre puisse comparer les noms, ou envoyez votre réponse IVMS 101 complète dans ivms_response : le nom du bénéficiaire qu’elle contient prévaut alors. En cas de refus, vous pouvez indiquer un decline_reason (data_mismatch, not_our_customer, wallet_not_hosted, sanctions, risk_appetite, jurisdiction, insufficient_data ou other) ainsi qu’un decline_detail de 512 caractères maximum, obligatoire pour other. Une acceptation sans beneficiary_name est enregistrée comme une incohérence lorsque l’expéditeur a fourni un nom de bénéficiaire, sauf si la comparaison des noms est désactivée chez l’expéditeur. La réponse est le {"status": "..."} obtenu : COMPLETED lorsque les noms correspondent, COUNTERPARTY_MISMATCHED_DATA lorsqu’ils ne correspondent pas, ou COUNTERPARTY_VASP_GENERAL_DECLINE après un refus. Vous ne pouvez répondre qu’une seule fois, tant que le transfert attend votre réponse. Après une réponse, après l’annulation du transfert ou après son échéance de confirmation, les deux endpoints renvoient 410, et un token inconnu renvoie 404. La demande affiche les champs du donneur d’ordre que l’expéditeur partage, ainsi qu’un ivms_request IVMS 101 dans la langue de votre juridiction. Vous recevez un rappel 72, 24 et 6 heures avant l’échéance tant que vous n’avez pas répondu.

Sunrise: les transferts réglés avant l’échange

Lorsqu’un transfert parvient au portefeuille d’un client de Didit avant tout échange Travel Rule (faute de canal commun à ce moment-là), les données peuvent tout de même être transmises après le règlement. Transmettez au client de Didit (votre contrepartie bénéficiaire) le payload Travel Rule par votre canal habituel, et demandez-lui de l’enregistrer. Il appelle POST /v3/travel-rule/inbound/ avec la chaîne du dépôt, le txid, l’adresse, le montant, la devise et vos données de donneur d’ordre. Incluez l’identité de votre VASP (nom, LEI et Travel Address) sous la forme originating_vasp dans ce payload, afin que le transfert du client de Didit indique qui a envoyé le dépôt. Cette information reste sur ce transfert et ne crée ni ne modifie jamais votre entrée d’annuaire. Le LEI doit être un LEI valide de 20 caractères, et la Travel Address doit être valide, faute de quoi l’enregistrement est rejeté.

Figurer dans l’annuaire VASP de Didit

Didit tient à jour un annuaire VASP que consulte l’acheminement sortant de ses clients. Les entrées proviennent des sources suivantes :
  • Le registre intérimaire MiCA de l’ESMA des prestataires de services sur crypto-actifs, consulté chaque semaine : votre nom, votre LEI et votre État membre d’origine si vous y figurez.
  • L’annuaire public TRISA, consulté chaque semaine : votre identité, votre pays et votre inscription TRISA.
  • Le registre mondial LEI, qui renseigne votre LEI, vos autres dénominations légales et votre pays.
  • L’attribution par les outils d’analyse blockchain, lorsqu’un portefeuille de destination est rattaché à votre service d’échange ou de conservation : Didit ajoute ou rapproche votre entrée et conserve le nom attribué comme alias.
  • L’équipe de Didit, qui sélectionne les entrées : identifiants de routage et inscriptions sur les réseaux qu’elle a vérifiés, contacts de conformité, alias, ainsi que marques et leurs entités.
Ce qu’un client de Didit signale à votre sujet, comme un originating_vasp lors d’un enregistrement Sunrise ou une Travel Address sur un transfert, reste attaché au transfert de ce client et ne modifie jamais votre entrée. Les demandes de transfert que vous envoyez à un client de Didit ne créent pas non plus votre entrée et ne la mettent pas à jour. Votre entrée achemine un transfert vers vous lorsqu’elle contient un endpoint TRP vérifié, une inscription sur un réseau que l’expéditeur peut utiliser, ou un contact de conformité pour le repli par e-mail. Une adresse de conformité sur l’un de vos propres domaines qui répond à une demande via son lien de réponse devient un contact que tout client de Didit peut utiliser. Tant que votre entrée ne comporte pas de route, un client de Didit ne peut vous joindre qu’avec les champs qu’il transmet à chaque transfert : votre Travel Address, votre identifiant de réseau (counterparty_gtr_vasp_code, counterparty_trust_membership_id, counterparty_verifyvasp_id ou counterparty_sygna_vasp_code), ou votre e-mail de conformité (counterparty_vasp_email). Pour être joignable dès aujourd’hui, partagez votre Travel Address, votre identifiant de réseau ou votre e-mail de conformité avec les clients de Didit avec lesquels vous travaillez.

Liste de contrôle pour les VASP contreparties

  • Vous utilisez déjà TRP : partagez votre Travel Address et votre LEI avec le client de Didit : ses transferts en BTC, ETH et USDC vous arrivent sous forme de demandes TRP standard sur votre endpoint. Répondez à la demande dans votre réponse : une réponse ultérieure nécessite l’hôte TRP public de Didit, qui n’est pas encore en service.
  • Vous êtes sur GTR, TRUST ou VerifyVASP : partagez votre identifiant de réseau ; les transferts vous arrivent par ce réseau lorsque le client de Didit détient sa propre adhésion à celui-ci. Didit lit votre réponse GTR ou VerifyVASP depuis le réseau, mais pas une réponse TRUST : publiez donc aussi un endpoint TRP lorsqu’un échange sur TRUST doit être conclu. Réseaux Travel Rule indique quand cela change.
  • Vous êtes sur Sygna Bridge : partagez votre code VASP Sygna ; lorsque le client de Didit détient sa propre adhésion Sygna, votre réponse d’autorisation finalise ou refuse le transfert une fois que Didit la lit par interrogation.
  • Vous n’avez pas encore de canal de protocole : donnez au client de Didit un e-mail de conformité surveillé : vous recevrez les liens de prise en charge et pourrez répondre depuis la page hébergée, sans aucune intégration.
  • Un transfert est déjà réglé : transmettez les données via l’enregistrement Sunrise par l’intermédiaire du client de Didit.
  • Vous souhaitez aussi émettre des transferts vers des VASP Didit : demandez à votre contrepartie sa Travel Address dans ses paramètres Travel Rule de Didit, puis suivez POST /trp/inquiries une fois l’hôte TRP public de Didit en service.

Prochaines étapes

Travel Rule

Le produit destiné aux clients : cycle de vie, paramètres, canaux de transmission et l’API /v3/.

Widget de propriété du portefeuille

Comment les preuves de propriété côté bénéficiaire sont collectées lorsque le portefeuille est auto-hébergé.

Enregistrement Sunrise

Enregistrer les données Travel Rule pour les dépôts déjà réglés on-chain.

Webhooks

Comment les clients de Didit suivent de leur côté chaque changement d’état de l’échange.
Dernière modification le 7 novembre 2026