跳转到主要内容
Didit 为虚拟资产转账运行 FATF/欧盟《资金转账条例》(TFR)规定的汇款人与收款人信息交换:它会寻找能够触达交易对手 VASP 的通道,通过该通道协商所需数据,通过包含 13 个状态的生命周期跟踪交换过程,并在交换结束时通知您,以便您在链上放行资金。

概述

FATF Travel Rule(建议 16)在欧盟通过《资金转账条例》(Transfer of Funds Regulation,TFR)实施,要求发起方虚拟资产服务提供商(originator VASP)在虚拟资产转账结算之前,收集汇款人和收款人信息,并将其传输给接收方虚拟资产服务提供商(beneficiary VASP)。 与大多数司法辖区不同,欧盟 TFR 适用没有最低金额门槛:每一笔加密货币转账都在适用范围内,而不仅限于超过报告门槛的转账。 Didit 的 Travel Rule 产品是一项托管式的信息交换服务,而不仅仅是一个数据字段:
  • 您以 transaction_category: "travelRule" 提交转账。
  • Didit 按优先级顺序尝试各条通道以联系交易对手 VASP,并在第一条能够联系到对方的通道上完成信息交换。如果对方返回了收款人姓名,Didit 会将其与您发送的收款人姓名进行匹配。
  • 只有当交换达到 COMPLETED 状态后,您才应在链上广播该转账。
  • 随后,您将链上交易哈希回报给 Didit,使交换以 FINISHED 状态关闭。
本版本共提供七条通道,严格按优先级顺序尝试,第一条能够联系到交易对手的通道胜出: 网络通道(GTR、TRUST、VERIFYVASP、SYGNA)需要发送方拥有网络成员身份,目前该成员身份必须是您自己的。 在控制台的 Marketplace(Travel Rule 网络类别)中连接您的成员凭据,您的转账将以您自己的网络身份发出。 Didit 目前未持有这四个网络的任何平台成员身份,正在作为提供方接入这些网络。 在接入完成之前,这四个网络的 platform_available 均为 false,设置中的 didit 模式(通过 Didit 的平台成员身份路由)对任何网络都不可用,disabled_networks 也没有可关闭的内容。 您自行连接的成员身份始终优先于平台成员身份。 默认不包含任何网络成员身份,GTR 也不例外。 启用 Travel Rule 并不会激活 GTR、TRUST、VerifyVASP 或 Sygna。 请查看获取 Travel Rule 设置,了解应用当前生效的 networks 模式;并查看 Travel Rule 网络,了解各网络目前能够联系到的范围。 如果四个网络均返回 unavailable,则没有任何网络能够路由交换:请在 Marketplace 中连接您自己的成员身份,或改用可联系到的 INTERNAL、TRP 或 EMAIL 交易对手。 保存成员身份时,其参与方代码必须是您自己的。如果该代码是 Didit 在该网络上的代码,或是其他应用的成员身份已占用的代码,保存将返回 400。 GTR 成员身份需要提供其 ed25519 私钥(base64 格式),且该私钥对应的公钥必须已在 GTR 门户中注册:该私钥用于加密您发送的个人数据,并解密您接收的数据。 VerifyVASP 成员身份指向您自己的 VerifyVASP Enclave:其 URL 为您的 Enclave 地址,其 token 为您的 Enclave 向 Didit 出示的 token。 即使使用您自己的成员身份,只有当网络通道的 beneficiary_data 携带该网络上交易对手的 ID(counterparty_gtr_vasp_code、counterparty_trust_membership_id、counterparty_verifyvasp_id 或 counterparty_sygna_vasp_code),或交易对手的目录条目在该网络上列出了其 ID(参见路由)时,该网络通道才会路由转账。 platform_available 表示是否已配置平台成员身份,而不是实时的网络健康检查。同样,connected 表示您的成员凭据已保存并通过本地验证;首次实时交换时才会在网络上验证这些凭据。didit 或 own 模式并不保证交易对手可以联系到,也不保证成功投递。 凭借你自己的会员身份,Didit 会从网络的响应中读取交易对手通过 GTR、VERIFYVASP 和 SYGNA 发送的回复,或每 5 分钟轮询一次网络,由此完成或拒绝该转账。 TRUST 仅用于发送:通过它发出的转账会保持在 AWAITING_COUNTERPARTY 状态,直到 confirmation_timeout_hours 指定的时长结束,随后转为 EXPIRED,并适用你的 timeout_outcome。 接收其他 VASP 通过网络发来的转账功能尚未开通,也尚未在实际网络上完成过任何网络交换。详见 Travel Rule 网络。 CODE(韩国联盟)、TRISA、Notabene 和 Veriscope 等其他网络已在控制台的 Marketplace 中以“申请访问”卡片的形式列出。 Didit 尚未与它们集成,因此目前任何转账都无法通过这些网络路由。 当七条通道都无法识别交易对手时,Didit 会在放弃之前再执行一个识别步骤:区块链分析归因。 系统会将目标钱包与区块链分析数据进行比对;若该钱包属于已知的交易所或托管机构,Didit 会在转账上记录归因得到的 VASP,将其添加到目录中,并使用新名称重新运行一次通道。 完整行为和定价详见区块链分析归因。 若转账的目标为声明为自托管钱包的地址,则会跳过全部七条通道,因为不存在可与之交换信息的交易对手 VASP,并直接进入终端用户的钱包所有权证明环节。
Didit 还运营着交易对手一侧的交换服务:供其他 VASP 调用以联系你的公开的 TRP 身份和查询端点、回调端点以及电子邮件取件流程。 你无需自行调用这些接口,它们由 Didit 统一托管。但 Travel Rule 互操作性页面记录了其中的每一项,方便交易对手 VASP 与你对接。 你只能通过本页所述的 /v3/ 端点使用 Travel Rule。

提交转账时会执行什么

检查在一次 POST /v3/transactions/ 调用内完成:您收到响应时,筛查已经运行,转账已经存储,规则也已评估完毕。 信息交换本身在响应之后才开始:Didit 在您的请求之外选择通道并联系交易对手,因此任何网络或交易对手都无法拖慢或导致创建失败。 此后的每次状态变更都会以 travel_rule.status.updated Webhook 的形式送达,并注明所用通道;Travel Rule 转账端点返回的转账对象包含 delivery 字段,用于显示消息是否送达。 没有需要轮询的流程;异步部分包括信息交换、交易对手的回复,以及终端用户的操作。 分步说明:
  1. 验证与主体绑定。 系统会校验 payload。 您应用中已使用的 transaction_id 会被以 400 拒绝;若两个相同 id 的请求发生竞争,其中一个会收到 409。 subject 通过 vendor_data 关联到您的用户或企业档案,以便该转账显示在该档案下用于监控。 列入黑名单的主体或交易对手 vendor_data 会被以 400 拒绝,且不会创建任何交易。 黑名单中的钱包、银行账户、IP 与设备会在第 6 步检查,并在通道路由运行之后于该步骤拒绝交易。
  2. 设备与网络信息补充。 参与方 IP 会进行地理信息补充,任何设备上下文(通过 SDK 提交 自动获取)都会被规范化后写入设备图谱。这与 KYC 会话写入的图谱相同,因此”按设备关联”可同时用于入驻与交易。
  3. 加密货币筛查。 对于启用了监控的加密货币转账,相关钱包(或链上哈希)会在任何信息交换之前,通过区块链分析进行筛查,包括制裁风险敞口、混币器关联和被盗资金。参见 加密货币与钱包筛查。
  4. Travel Rule 转账。 信息交换引擎检查阈值,并认可 自托管钱包声明,然后存储转账:低于您阈值的转账为 NOT_APPLICABLE;已声明的自托管钱包为 UNCONFIRMED_OWNERSHIP;对方钱包为您本人已验证的钱包时为 COMPLETED;其他情况为 AWAITING_COUNTERPARTY,此时其通道仍为空。 每次状态变更都会排入一个 travel_rule.status.updated 事件,Didit 会在交易的 transaction.created(第 7 步)之后发送该事件。
  5. 钱包所有权组件生成。 如果转账需要终端用户证明控制权,且 auto_wallet_verification 已开启,则会生成 钱包所有权组件 会话,并在 action_required 中返回。
  6. 规则评估。 所有启用的规则都会运行:EU TFR 规则包 对第 4 步设定的转账状态作出反应;您的自定义规则读取第 3 步的筛查输出;规则可以挂起交易(IN_REVIEW)、拒绝交易,或要求 加强验证(AWAITING_USER)。
  7. 计费与通知。 出站交易按一条计费项计费:若启动了信息交换,则按 Travel Rule 计费项 计费,否则按 Transaction Screening 计费。入账转账不收取任何费用,沙盒应用永不计费。 系统返回响应,并向您的 Webhook 目标发送 transaction.created,随后发送第 4 步的 travel_rule.status.updated 事件。
  8. 路由,在响应之后。 Didit 按优先级依次尝试 七条通道;若均无法解析,则 区块链分析归因 会识别交易对手,通道随后重新运行一次。第一条可达的通道承载信息交换:在交易对手回复期间,转账保持在该通道上的 AWAITING_COUNTERPARTY;若匹配到 INTERNAL 交易对手,则立即结算(COMPLETED 或 COUNTERPARTY_MISMATCHED_DATA);若没有任何通道能够连接交易对手,则变为 COUNTERPARTY_VASP_NOT_FOUND。每次变更都会触发 travel_rule.status.updated,且只要状态或通道发生变化,您的规则就会再次运行。路由后仍处于 COUNTERPARTY_VASP_NOT_FOUND 的转账,此时会生成钱包所有权组件会话(需开启 auto_wallet_verification);您可以通过 获取交易 从交易的 action_required 中读取该会话。

每个步骤对应的义务

测试说明。 沙盒应用会跳过规则评估和计费,且不发送 transaction.created 或 transaction.status.updated Webhook。除非到期的 Travel Rule 转账应用了您的 timeout_outcome,沙盒交易将保持 APPROVED,且不收取任何费用。 启用 Travel Rule 后,Travel Rule 信息交换引擎本身也会在沙盒应用上运行,且仅与一个交易对手交互:所有出站交换都会发往 TEST_VASP 通道上的 Didit 测试 VASP。它会在 Didit 内部以您所选的场景作出回应,因此转账可能完成、被拒绝、不匹配、变为不可达、过期,或等待钱包所有权验证。 任何合规消息都不会到达真实的交易对手 VASP,travel_rule.status.updated Webhook 会以 environment: sandbox 投递。 入账方面,测试 VASP 可以向您发送转账(触发测试 VASP 入账转账),注册(POST /v3/travel-rule/inbound/)会像在正式应用上一样与您的钱包地址簿结算,结果为 ON_HOLD、UNCONFIRMED_OWNERSHIP、COUNTERPARTY_MISMATCHED_DATA,或 COMPLETED 后再 FINISHED。 参见 在沙盒中测试 Travel Rule。

生命周期

每笔转账的 status 取自 13 个值之一。 常规情况下,交换从 AWAITING_COUNTERPARTY 开始。当金额低于你的 threshold_amount,或闪电支付请求未指明收款方时(参见 Lightning),交换从 NOT_APPLICABLE 开始。当目标钱包已被声明为自托管钱包时,交换从 UNCONFIRMED_OWNERSHIP 开始。交换最终进入以下终态之一:FINISHED、CANCELLED 或 EXPIRED。 转账拥有自己的状态机,与底层交易的审核状态相互独立。 交换状态本身从不改变交易状态,唯一例外是过期:过期时会应用你配置的 timeout_outcome(若适用,则应用sunrise 或无响应策略)。 你的规则会在每次状态转换时重新运行,因此 EU TFR 规则或任何基于 travel_rule_status 的规则都可能移动交易,例如将其转为 IN_REVIEW。 需要终端用户证明钱包控制权的转账,会在交易上添加一个 action_required 块,但其 status 保持为你的规则所设定的状态。 请从 travel_rule.status 读取交换状态;从交易自身的 status 读取放行、挂起或拒绝的判定结果。 每次状态转换(以及每个被动上报的状态)也会同步写入交易的自定义值,以便规则据此设置条件:custom_values.travel_rule_status(规范化状态)、custom_values.travel_rule_rail(承载此次交换的通道,选定前为空),以及 custom_values.travel_rule_regime(由你的设置中的 jurisdiction 推导:SG → singapore,GB → uk,任何欧盟或欧洲经济区成员代码(如 DE 或 FR)→ eu;未映射的代码会被转为小写,例如 US → us。你自行提交的 props.travel_rule_regime 始终优先于推导出的值)。
在 COMPLETED 之前切勿广播。 如果转账处于 AWAITING_COUNTERPARTY、UNCONFIRMED_OWNERSHIP 或任何不匹配或被拒绝的状态,就在链上释放资金,这会使信息交换失去意义。 请以 status == "COMPLETED" 作为广播步骤的前置条件,然后使用返回的 payment_txn_id 调用 PATCH .../travel-rule/,将其切换为 FINISHED。
各状态转换概览(CANCELLED 还可通过 action: "cancel" 从每个非终态进入):

投递与重试

Didit 会在引发该转账的请求之外发送转账所需的每条消息,并持续重试,直到对方接收为止。 通过 完成、取消或重新发送、确认所有权 和 sunrise 注册 返回的转账对象,会在 delivery 中携带最新一条消息的信息;交易中嵌入的 travel_rule 对象也包含该信息。如果转账从未需要投递消息,则其值为 null。 对于网络可能仍会恢复的故障(超时未响应、连接失败、HTTP 408、429 或 5xx),会在 30 秒、2 分钟、10 分钟、30 分钟和 1 小时后重试。 如果首条消息最终失败,即网络拒绝了它,或第六次尝试也失败了,转账会进入 COUNTERPARTY_VASP_NOT_REACHABLE 状态,失败原因(last_error)记录在其 timeline 中,您可以使用 action: "resend" 重试。 其他最终失败的消息会记录在 timeline 中。 delivery 永远不会取代转账的 status:请以 status 判断信息交换的状态,并使用 delivery 查看转账仍在等待的原因。

旧版状态值

如果您在本次发布之前就已在发送 travel_rule_details.status,这些值仍然有效,并会自动映射。 任何状态的驼峰式写法(例如 counterpartyVaspNotFound)在提交时以及 规则 条件值中同样可以接受,并会规范为标准形式:

设置

请在每个应用中配置一次 VASP 资料和协商策略,使用 GET/PUT /v3/travel-rule/settings/。
PUT 为部分更新,只需发送要修改的字段。

姓名匹配严格度

所有权验证模式

ownership_validation_mode 决定在转账依赖某个钱包的所有权之前,需要多少证明: 钱包经验证后,会针对每个终端用户记住该钱包。 在 FULL 和 SIMPLIFIED 模式下,后续转账只有在该模式对该转账接受的证明支持该钱包时才会复用它。 当 inbound_auto_accept 在地址簿中找不到匹配的钱包时,您恰好在一位终端用户的交易中记录过的加密钱包可用于识别持有人。 Didit 会将该钱包作为您的自我声明添加到该终端用户的地址簿中;除非模式为 FULL,否则标记为已验证。若地址簿已将同一链的某个钱包列在其他名称下(eth 和 ethereum),包括被记录为其他 VASP 的钱包,则不会再添加该钱包。 其他 VASP 在发送前进行的地址检查(通过 GTR、Sygna 和 VerifyVASP)同样遵循该模式:在 FULL 模式下,终端用户仅作出声明的钱包不会被报告为您的钱包。

数据共享

data_sharing_fields 决定 Didit 就您自己的用户向交易对手发送哪些字段,个人和公司分别设置:
  • 个人可以共享 name、wallet_address、address、national_id、customer_identification、date_of_birth 和 place_of_birth。公司只能共享前五项。
  • name 和 wallet_address 始终会被发送。
  • 您从未选择过的实体类型会共享所有字段。空列表也是一种选择:它只共享姓名和钱包。
  • PUT 按实体类型合并,因此发送 individual 不会改变已存储的 company 选择。
  • 若某项选择无法满足您所在 jurisdiction 监管制度(EU TFR 或 FATF 建议第16条)的汇款人义务,包括空列表在内,将返回 400。错误信息位于 data_sharing_fields 下,并以实体类型为键。

按字段匹配

matching_rules 设置交易对手数据的每个字段与您所持数据比较时的严格程度:
每个值为 NONE、STRICT、CONTAINS、DEFAULT 或 FUZZY 之一。 默认值:name 遵循 name_matching_strictness,date_of_birth 和 address 为 NONE,account 为 STRICT。 省略的字段保持其默认值。实体类型不进行比较的字段(例如公司没有 date_of_birth)会返回 400。

按司法辖区划分的阈值

threshold_amount 之所以存在,是因为 Travel Rule 的适用范围因监管机构而异。 Didit 默认值为 0.00,即欧盟的做法,因此除非您主动提高该值,否则每笔转账都会进行信息交换: 将 threshold_amount 设置为您所在监管机构规定的金额。低于该金额的转账将解析为 NOT_APPLICABLE,且不交换任何身份数据。 阈值会变化,请与您的合规法律顾问确认当前金额,不要将本表视为法律建议。

IVMS 101 数据模型

Travel Rule 要求交换的数据所采用的行业标准是 IVMS 101(interVASP Messaging Standard)。 travel_rule_details.originator_data 和 travel_rule_details.beneficiary_data 是遵循 IVMS 101 格式的人员 payload。Didit 会将它们封装进每个通道原生的信封中:TRP 通道交换 IVMS101 数据块(ivms101.2023,在转账的 ivms_version 字段中体现),Sygna 通道使用其 ECIES 加密的 IVMS 变体,而 GTR、TRUST 和 VERIFYVASP 通道则使用各自的加密信封。因此,同一种 payload 结构可以按各协议要求的格式送达每一个交易对手。 Didit 在构建 IVMS 101 消息时,会从每个人员 payload 中读取以下键:first_name 和 last_name(或单个 name 或 full_name)、date_of_birth、place_of_birth、residence_country(或 country)、vendor_data(或 customer_identification),以及 wallet_address。 两条实用规则:
  • 拉丁字母。 IVMS 101 要求使用拉丁字母书写的值,因此原本使用其他文字书写的姓名需要音译。Didit 的名称匹配会比较标准化后的词元集合,因此词序和大小写差异不会导致交换失败,但双方使用不同文字则会失败。
  • 发送已验证的数据。 当 vendor_data 所对应的主体是持有已通过的 Didit KYC 验证的用户时,Didit 传输的是已验证的身份信息,而不是你输入的值。详见已验证数据与来源。 对于其他主体,Didit 会原样传输你发送的 originator_data,因此请根据入驻时已验证的身份信息来构建它,而不要使用未经验证的表单字段。 这正是 FATF 对“必需且准确的汇款人信息”(required and accurate originator information)的要求。 在 INTERNAL 通道上,收款方的应用还会以入账交易中交易对手的身份,接收你发送的 subject(包括姓名、vendor_data、出生日期、国家/地区和地址)。

已验证数据与来源

当转账的主体是你的某位用户,即 KYC 验证已通过的个人时,Didit 会根据已验证的数据构建该方的信息交换内容:
  • 你通过 POST /v3/transactions/ 创建的转出交易中的汇款人;
  • 你通过 POST /v3/transactions/ 报告的转入交易中的收款人,或当匹配钱包的 holder_vendor_data 指向该用户时,通过 POST /v3/travel-rule/inbound/ 报告的转入交易中的收款人。
在 POST /v3/transactions/ 中,当 Travel Rule 开启时,两者都适用于 transaction_category 为 travel_rule 的交易。 已验证的姓名、出生日期和出生地、证件号码和类型、地址,以及居住国家/地区(由该地址得出),优先于你发送的值。验证中没有的字段保留你的值。如果已验证的地址不足以完成传输,则你发送的完整地址同样保留。 转账的 metadata(位于交易内嵌的 travel_rule 对象中)记录了每个字段的来源,以及你的值与已验证值不一致的地方:
*_provenance 将每个字段映射为 verified 或 caller。*_verified_differences 列出你发送的值与已验证值存在差异的每个字段,比较时忽略大小写、空格以及两位或三位国家代码的写法差异。当转入交易的数据处于已脱敏状态时,差异不会列出。这两项均由 Didit 自行计算,因此你在 travel_rule_details.metadata 中发送的这些键的副本,以及 name_match 的副本,都会被丢弃。

直接发送 IVMS 101

除了扁平的 originator_data 和 beneficiary_data 对象之外,POST /v3/transactions/ 中的 travel_rule_details 以及 POST /v3/travel-rule/inbound/ 还接受完整的 IVMS 101 数据:
  • 一个 originator 块和一个 beneficiary 块,其中 originatorPersons 或 beneficiaryPersons 包含一个 naturalPerson 或一个 legalPerson,并包含 accountNumber;
  • 同样的块放在 ivms101(或 IVMS101)对象中;
  • 一个 IVMS 101 人员,或一整个数据块,作为 originator_data 或 beneficiary_data 传入。
每一方只能包含一个人员:一个 naturalPerson,或一个 legalPerson(这会使该方成为公司)。非空的扁平 originator_data 或 beneficiary_data 会覆盖同一方的数据块。
格式错误的数据块会返回 400,并以其路径作为键,例如 {"travel_rule_details": {"originator.originatorPersons": ["must be a non-empty list of originator persons."]}}。在 POST /v3/travel-rule/inbound/ 中,相同的键位于顶层,若你使用了包装器,则位于 ivms101. 之下。

按监管制度的必填数据

Travel Rule 开启时,金额达到或超过你的阈值的转出交易必须包含其所适用监管制度要求的数据,否则返回 400。只检查你发送的各方,已验证的数据计入汇款人一方。错误信息位于 travel_rule_details.originator_data 或 travel_rule_details.beneficiary_data 之下,例如 "EU TFR requires the originator name." 或 "FATF Recommendation 16 requires the beneficiary wallet address.": 对于汇款人,检查会读取你的应用在 data_sharing_fields 中共享的字段,因为这些是通道实际发送的全部内容;收款人则按你发送的内容进行检查。当转账只有依靠你不共享的字段才能满足监管要求时,400 错误会先说明该监管制度的要求,然后列出你的设置所共享的字段。 官方证件号码为 national_id(或 document_number),客户身份识别号码为 customer_identification(或 vendor_data),出生日期为 date_of_birth。在检查之前,空的 beneficiary_data.wallet_address 会由 counterparty.payment_method.account_id 填充。若 UTXO 提现的收款输出是 Didit 从 travel_rule_details.utxo 推断出的,则视为已包含该地址。不适用 Travel Rule 的 Lightning 转账不做检查。

Travel Address

Travel Address 是一个紧凑的编码字符串,指向某个 VASP 的入站 TRP 查询 endpoint。它从不暴露原始 URL 或任何钱包地址。 开启 Travel Rule 后,Didit 会生成您自己的 travel_address(在设置中以只读方式返回),以便您将其分享给通过 TRP 通道联系您的其他 VASP。 您的每个地址簿钱包还会获得一个单独的 receiving_travel_address。发送到该地址的查询会指明对应的钱包,因此 Didit 无需通过账户号或户名来查找钱包。 Didit 的公共 TRP 主机目前尚不响应其他 VASP,因此在该主机能够响应之前,无法通过 TRP 接收转账。请参阅 Travel Rule 网络。 当您知道交易对手的 Travel Address 时,请将其存入收款方的地址簿条目。这样,Didit 会直接通过 TRP 路由该收款人的转账,而不会退回到电子邮件。 Didit 会验证您存入地址簿条目或在 originating_vasp 中发送的 Travel Address。每个地址都必须以 ta 开头,并解码为带有 t=i 的查询 URL。因此,ta... 这样的占位符会返回 400。 交易中的 beneficiary_data.travel_address 不做验证。如果它无法解码,则跳过 TRP 通道。 编码方式为带 ta 前缀的 Base58Check:包含端点主机和路径(路径始终带有查询参数对 t=i),加上四字节的双重 SHA-256 校验和,并进行 base58 编码。一个真实地址如下所示,长度约为 100 个字符:
Didit 验证 Travel Address 时,如果值不是格式正确且校验和有效的地址,将返回 400 和 "Invalid travel address."。 请从您自己的设置响应中获取真实地址,或直接向交易对手索取。

无需网络凭证的测试

您无需 GTR、TRUST、VerifyVASP 或 Sygna 的会员资格即可测试不依赖会员资格的路径。您仍需要所测应用的 Didit API 密钥。
  • 沙盒出站: 从沙盒应用提交 travelRule 交易。通过阈值和自托管钱包检查后,Didit 测试 VASP 会在 Didit 内部按您根据收款钱包或姓名选择的场景作出响应:接受、拒绝、姓名不匹配、无法访问、超时或自托管。不会有任何网络、电子邮件或其他 Didit 客户收到任何内容。
  • 沙盒入站: 让测试 VASP 通过 触发测试 VASP 入站转账 向您发送转账,或自行使用 注册入站 Travel Rule 转账 登记一笔转账。测试未知钱包、未验证钱包、收款人姓名不匹配,以及已验证且匹配的钱包。这些测试会执行真实的入站决策,但不会联系任何网络。
  • 两个受控的生产环境应用: 在您自有的两个生产环境应用之间使用 INTERNAL 通道。接收方应用可被发现,并通过签名消息或测试入账证明其对目标钱包的控制权。您也可以使用受控的 TRP 交易对手。这样无需商业网络凭证即可测试双方交换。生产环境应用可能产生正常费用和通知,因此请使用您可控的测试身份和交易对手。
有关每个场景及其确切结果,请参阅在沙盒中测试 Travel Rule。沙盒或本地协议测试成功,并不能验证商业网络的凭证、会员资格或生产环境互通性。这些需要经授权的网络沙盒,或使用有效会员凭证进行受控的生产环境交换。

发送转账

在 POST /v3/transactions/ 上发起转账,设置 transaction_category 为 travelRule(或 travel_rule),并附加 travel_rule_details 对象(别名:travelRule)。 travel_rule_details 块本身是可选的,但一旦附加该块,travel_rule_details.status 即为必填项:缺少该字段的块会返回 400。 当您的应用已启用 Travel Rule 时,Didit 会忽略您发送的 status 值,并自行推进信息交换:
  1. 如果金额低于您配置的 threshold_amount,转账会立即变为 NOT_APPLICABLE,不进行任何协商。
  2. 如果交易对手的付款方式将目的地声明为自托管钱包(payment_method.method_type: "unhosted_wallet"),则不尝试任何通道,转账直接进入 UNCONFIRMED_OWNERSHIP,并自动生成钱包所有权小组件(参见已声明的自托管钱包)。
  3. 否则,按优先级顺序运行各通道,第一个能够触达交易对手的通道承载信息交换:
    • INTERNAL:恰好有一个其他 Didit 客户为 beneficiary_data.wallet_address 持有签名消息或测试存款证明,且该证明是在钱包上次更换持有人之后生成的。您自己的应用从不计入。当您的终端用户在钱包所有权小组件中选择了某个 Didit 网络成员时,只有该成员的证明才计入。该客户的应用须为生产环境(非沙盒),已开启 Travel Rule,已设置 is_discoverable,并且是您在发送 counterparty_vasp_lei 或 counterparty_vasp_name 时指定的 VASP。仅自行声明、以截图作为证明、未经验证或只存在于地址簿中的钱包,永远不会通过 INTERNAL 收到任何内容。
    • TRP:转账的资产在该网络上具有数字代币标识符映射(参见 TRP 资产标识符),并且负载中包含 beneficiary_data.travel_address,或目的地自身的地址簿条目保存了该地址,或交易对手可通过目录(依据 counterparty_vasp_lei 或 counterparty_vasp_name)解析出带有 TRP endpoint 的记录。
    • GTR、TRUST、VERIFYVASP、SYGNA:您已在 Marketplace 中为该网络连接了自己的成员资格,且交易对手能解析为网络 ID(通过显式字段或目录条目,参见交易对手解析字段)。 Didit 目前尚未在这些网络上持有平台成员资格(正以服务提供方身份入驻),因此目前 disabled_networks 不会改变此步骤。
    • EMAIL:提供了 beneficiary_data.counterparty_vasp_email,或 counterparty_vasp_name 能解析为带有合规邮箱的目录条目。
  4. 如果没有任何通道能够解析交易对手,Didit 会运行交易对手发现流程。开启 vasp_attribution_enabled 后,该流程包括区块链分析归因:目的钱包会被解析为其所属的 VASP,归因得到的名称会写入 beneficiary_data.counterparty_vasp_name(仅当其为空时)以及目录,然后通道重新运行一次。因此,归因到某个 VASP,且该 VASP 的目录条目带有 TRP endpoint、网络 ID 或合规邮箱的钱包,会在这第二轮中完成路由。
  5. 如果交易对手仍未解析,转账会进入 COUNTERPARTY_VASP_NOT_FOUND。对于转出转账,Didit 会(在启用 auto_wallet_verification 时)自动生成钱包所有权小组件,使转账仍可作为自托管钱包转账完成。待获得更完整的交易对手数据后,您可以使用 action: "resend" 稍后重新运行路由。
第 1 步和第 2 步在请求内部完成。第 3 至第 5 步在响应返回后立即运行:转账返回时状态为 AWAITING_COUNTERPARTY,且 protocol: null,每个结果都会通过一条 travel_rule.status.updated Webhook 送达。

TRP 资产标识符

TRP 通过 ISO 24165 数字代币标识符(DTI)来标明转账资产。 一个 DTI 只标识单条区块链上的一种代币,因此多链代币在每个网络上各有一个 DTI。 Didit 对以下资产通过 TRP 发送转账: USDC 的标识符与该代币发行方在其 MiCA 白皮书中公布的标识符一致。 对于多链代币,转账必须在 transaction_details.crypto_params.crypto_chain 中指明其网络(例如 CELO、BASE、OP、ARB 或 POL)。 未指明网络,或网络没有映射时,转账不会通过 TRP 发送,Didit 会尝试其余通道:先尝试互操作网络,再尝试邮件。 USDT 尚未映射。 没有 DTI 映射的代币(例如企业自有的稳定币),需要其发行方在 ISO 24165 注册机构注册 DTI,每种代币在每条区块链上各注册一个。 DTI 生成后,请联系 Didit 支持,提供每个 DTI、其所在区块链以及代币的小数位数,Didit 会添加该映射。 带有已映射的、按网络区分的 DTI 的入站 TRP 查询,会按该代币的货币、以代币小数位表示的金额以及网络进行记录。

交易对手发现

仅携带地址的转账,只要有人能识别其交易对手,仍能抵达该交易对手。 在判定出站转账无法路由之前,Didit 会按以下顺序进行查询,并在第一个识别出具有路由的 VASP 的步骤处停止: 转账的 discovery 字段列出了每个已运行的步骤及其 outcome(match、miss 或 skipped)、机器可读的 reason、找到的 vasp 和 rail,以及时间戳。 你或终端用户选择的 VASP 优先于所有自动步骤:发现过程永远不会用它自己的猜测替换它。 如果没有任何步骤指定交易对手,转账会进入 COUNTERPARTY_VASP_NOT_FOUND 状态;如果指定了某个 VASP,但其路由都无法被你的应用访问,则进入 COUNTERPARTY_VASP_NOT_REACHABLE 状态。 随后,转账会带有 reason(awaiting_end_user、no_directory_match、directory_match_no_route,或终端用户所选成员尚未证明钱包所有权时的 picked_member_without_proven_wallet),以及 next_actions 列表: 组件链接即为终端用户执行操作时的 url。 当钱包所有权操作待处理时,交易的 action_required 块(类型为 wallet_ownership)会携带相同的 reason 和 next_actions,因此已经遵循 action_required 的客户端无需额外工作即可显示选择器。

交易对手解析字段

Didit 掌握的关于交易对手的所有信息都来自 travel_rule_details.beneficiary_data。 以下字段驱动通道解析,均为可选:

链的结构形式

在账户型链(EVM 链、Solana、Tron)上,转账会将资金从一个地址转移到另一个地址,Didit 直接从交易中读取两个钱包。 其他三种结构需要更多信息,Didit 为其解析出的结果会体现在转账的 chain_details 中(在账户型链上为空,即 {})。 chain_details.originator 和 chain_details.beneficiary 各自包含 address、其 memo 以及来源 source;匹配和路由会优先从这里读取钱包。

UTXO 转账

比特币、莱特币、比特币现金或狗狗币交易会花费来自任意数量地址的输入,并支付任意数量的输出,其中部分输出会作为找零退回给发送方。 将输入和输出作为 travel_rule_details.utxo 发送(金额以该币种自身的单位表示,为十进制字符串),Didit 会推断你未声明的内容:
  • 汇款人:若你发送了 originator_data.wallet_address,则使用它;否则使用贡献金额最多的输入地址(source: largest_input)。
  • 收款人:使用已声明的钱包;否则使用唯一一个不作为找零退回给输入地址的输出(only_non_change_output);再否则使用支付转账金额的那个输出(amount_match)。
随后,该转账会携带:
chain_details.warnings 会标记不一致之处:declared_originator_not_an_input、declared_beneficiary_not_an_output、beneficiary_output_ambiguous(无法区分出任何单一输出)和 beneficiary_output_amount_differs。 在其他任何链上使用 utxo 会返回 400,且每个列表最多包含 1,000 条记录。 已报告的入金使用相同的 utxo 对象(参见 入金后 sunrise 注册)。

Memo 与标签网络

在 XRP、Stellar(XLM)、EOS、Cosmos(ATOM)和 Hedera(HBAR)上,交易所会在同一个共享地址上接收所有客户的款项,并通过目标标签(destination tag)或 memo 来区分他们。 因此,memo 是钱包的一部分:请在参与方上以 payment_method.memo 发送,或在 originator_data / beneficiary_data 中以 memo 发送(别名 destinationTag),Didit 会同时比对地址和 memo。
  • 带有 memo 的地址簿条目只匹配指定该 memo 的转账。不带 memo 的条目匹配整个地址。未指定 memo 的转账永远不会匹配带有 memo 的条目:在共享地址上,没有标签的入金不属于任何人。
  • XRP X 地址内含标签:Didit 会将其拆分为经典地址和标签(source: x_address),因此以任一形式注册的钱包都能匹配另一形式的转账。
  • 共享地址上的每个 memo 在该交易中都是一种独立的付款方式。
  • 各网络的接受范围:XRP 目标标签为 0 到 4294967295 之间的整数(接受 JSON 数字);Stellar memo 最多 28 字节文本、64 位 ID 或十六进制的 32 字节哈希;EOS 最多 256 字节,Cosmos 最多 256 个字符,Hedera 最多 100 字节。在没有 memo 的链(Bitcoin、EVM 链、Solana、Tron、Litecoin、Bitcoin Cash、Dogecoin、Lightning)上使用 memo 会返回 400。

Lightning

Lightning 付款没有链上收款地址:付款方持有一个付款请求。 在 bitcoin 或 Lightning 加密转账中,payment_method.account_id 可以是该付款请求,Didit 无需连接任何网络即可据此识别收款方: 收款方会作为账户保存,并保存为 chain_details.beneficiary(source: invoice_payee),所在链为 LIGHTNING;请求中的内容则保存在 chain_details.lightning 中。 如果请求未指定收款方,出站转账会变为 NOT_APPLICABLE,原因记录在 chain_details.not_applicable_reason 以及其 timeline 中,取值为 LIGHTNING_NO_PAYEE_IDENTIFIER、LIGHTNING_BOLT12_BLINDED_PAYEE 或 LIGHTNING_LNURL_NAMES_NO_PAYEE 之一。 只有在 bitcoin 链上、LIGHTNING 链上,或未指定链时,某个值才会被识别为 Lightning(Lightning Address 仅限 bitcoin 或 LIGHTNING 链);在其他任何链上,它都是该链自身的地址。
只有通过该客户已用签名消息或测试入金证明其控制权的钱包,INTERNAL 通道才能触达另一位 Didit 客户;目前这类证明仅支持 Bitcoin、EVM 链、Solana 和 Tron。 因此,在 memo 网络、Lightning、Litecoin、Bitcoin Cash 和 Dogecoin 上,转账永远不会通过 INTERNAL 触达另一位 Didit 客户。 memo、标签和 Lightning 匹配仍然适用于您自己的地址簿:发往您钱包的入站转账、已报告的入金以及 TRP 查询。

更新汇款人钱包

提现通常以客户的主钱包名义申报,但实际广播时使用的则是持有币的任意地址。 请使用 PATCH /v3/transactions/{transaction_id}/travel-rule/ 记录资金实际转出的钱包:
  • 仅适用于出站转账,且绝不适用于 CANCELLED 或 EXPIRED 状态的转账(返回 409)。
  • 若已知转账的 UTXO 输入,则该钱包必须是其中之一(否则返回 400)。在 memo 网络上,还需同时发送 memo。
  • 该操作仅修改记录:不会再次向交易对手发送任何内容,状态保持不变。chain_details.originator 会变为新钱包,并带有 source: updated;timeline 会记录之前和新的钱包;该转账对应的 INTERNAL 转账也将以相同方式更新。

区块链分析归属

如果您只提供一个钱包地址,Didit 仍然可以查明另一方是谁。 如果没有任何通道能够路由该转账,Didit 会将目标钱包与区块链分析归属数据进行比对。这与驱动 加密交易筛查 的分析相同,能够识别哪些钱包属于哪些交易所和托管机构。 归属分析仅对同时携带目标钱包和 chain 的出站转账执行(参见 交易对手解析字段);若没有链,则跳过该步骤。 当钱包归属于已知实体时,Didit 会:
  1. 在转账上记录归属信息:填入 beneficiary_data.counterparty_vasp_name(若您未提供该字段),并且转账的元数据中包含一个 vasp_attribution 块,其中包含实体名称、实体类型、国家/地区,以及 source: "blockchain_analytics"。
  2. 将该实体添加到 VASP 目录 中(或与已有条目匹配),以确保归属信息在各次转账之间保持稳定。
  3. 使用归属名称重新运行一次通道路由:若目录条目已包含 TRP 端点,转账将立即完成路由,而不会进入 COUNTERPARTY_VASP_NOT_FOUND。
归属调用同时也是一次完整的加密筛查:交易会获得完整的筛查结果,包括风险评分、钱包风险类别和网络快照,效果与加密监控已运行时完全相同。交易的 custom_values.aml_screening_trigger 会被设置为 travel_rule_attribution,以便您看到此次筛查是由 Travel Rule 路由所触发的。 若加密监控已对本交易中的同一钱包进行过筛查,则复用已存储的结果,不会再次调用分析接口,也不会再次收费。 归属查询绝不会阻止交易创建:若分析查询失败,或您的余额不足以支付该查询费用,转账将直接进入 COUNTERPARTY_VASP_NOT_FOUND,且本次尝试不收取任何费用。 当 action: "resend" 时,将复用先前记录的归属结果,而不再重新查询。 使用 设置 中的 vasp_attribution_enabled: false 可关闭整个步骤。 有关归属识别调用的计费方式,请参阅 定价。 当 Travel Rule 已禁用时,travel_rule_details(包括你提供的 status,无论是旧版还是当前版本)仍会记录在交易上,但只是被动记录,不会调度任何通道。 你可以用此功能回填已通过自有流程跟踪的合规数据。 被动的出站转账不会发起任何交换,因此按 Transaction Screening 计费,而不计入 Travel Rule 计费项。 启用 Travel Rule 后,此请求会通过 EMAIL 通道路由,因为它指定了交易对手的合规邮箱,而之前的任何通道都无法触达收款人:
响应(为突出关键字段已作删减):
  • originator_data 即你发送的内容,因为示例中的主体没有已通过的 KYC 验证;对于已验证的用户,Didit 会根据已验证数据构建该字段(参见 已验证数据与来源)。 EMAIL 通道只会向收件人展示你在 data_sharing_fields 中共享的汇款人字段。
  • beneficiary_data.chain 为 ETH,因为请求中未指定链,所以 Didit 根据币种确定了该值。
  • status 为 APPROVED,因为没有规则对该交易采取任何操作;你自己的规则可能会设置其他状态。
  • 合规联系人会收到领取链接。联系人回复后,转账可能完成、因姓名匹配失败,或被拒绝;若对方未回复,则会过期(参见 邮件领取)。
protocol 仍为 null,因为通道是在响应之后选定的(例如,当你提供了 counterparty_vasp_email 时选定 EMAIL)。选定后,获取交易 会显示该值,此后每个 travel_rule.status.updated Webhook 都会在 rail 中携带它。 如果收款钱包属于另一位已证明控制该钱包的 Didit 客户,INTERNAL 通道会在响应后立即完成整个交换,且该 Webhook 已报告 COMPLETED(或 COUNTERPARTY_MISMATCHED_DATA)。姓名不匹配时,你的转账状态为 COUNTERPARTY_MISMATCHED_DATA,另一位客户不会收到任何内容。 若未提供 counterparty_vasp_email,且通道和归属识别都无法触达收款人,转账稍后会以 COUNTERPARTY_VASP_NOT_FOUND 结束,并在交易上带有一个 wallet_ownership 操作。
这笔交易内嵌的 travel_rule 对象包含转账自身的字段(uuid、status、protocol、required、obligations_count、originator_data、beneficiary_data、metadata)、Didit 已解析并比对的内容(chain_details、name_match、data_match、mismatched_fields,以及脱敏字段 data_masked 和 data_unmasked),以及说明转账当前进展的字段:direction、rail、counterparty_vasp、delivery、discovery、reason 和 next_actions(参见为什么转账会卡住)。 GET /v3/transactions/ 的每一行都带有同样的数据块;对于没有转账的交易,则为 null。 下文的专用转账端点同样会返回这些字段,另外还会返回 ivms_version、ownership_confirmed、deadline_at、timeline 和 created_at,但不返回 obligations_count 或 metadata。
要结束一笔已在链上广播的 COMPLETED 出站转账:
此操作要求该转账为 COMPLETED 状态的出站转账,否则 API 返回 409。 成功后,出站转账及其 INTERNAL 通道的对应转账都会变为 FINISHED,且交易的 payment_txn_id 会被设为你提供的哈希值。 在 TRP 通道上,Didit 还会将该哈希值发送到交易对手的确认回调。 若要取消尚未进入终态的转账,请向同一端点发送 {"action": "cancel"}。 INTERNAL 通道的对应转账也会被取消;在 TRP 通道上,一旦交易对手批准了查询,Didit 会将取消信息发送到其确认回调。 已处于 FINISHED、CANCELLED 或 EXPIRED 状态的转账返回 409。 既未提供 payment_txn_id、也未提供受支持的 action 的请求返回 400。 对于通过 GTR、VERIFYVASP 或 SYGNA 发送的转账,Didit 会在响应之后将链上哈希(或取消信息)报告给网络,并采用相同的重试机制;响应中的 delivery 会显示该消息。 若要重试一笔未能送达交易对手的出站转账(即当前处于 COUNTERPARTY_VASP_NOT_FOUND、COUNTERPARTY_VASP_NOT_REACHABLE 或 NOT_ENOUGH_COUNTERPARTY_DATA 状态的转账),请先完善交易对手数据,例如为目标钱包条目添加 travel_address,为交易对手的目录条目添加联系人,或将该 VASP 编入目录。 然后向同一端点发送 {"action": "resend"}。 Didit 会重新开始确认期限,并使用转账上存储的数据,从头重新排队路由流程。响应会显示转账回到 AWAITING_COUNTERPARTY 状态(其 timeline 中会有 resend queued),结果将通过 travel_rule.status.updated Webhook 送达。 若较早的尝试仍在运行,则重新发送请求会在该尝试结束后再发送。 其他状态的转账,或入站转账,返回 409。
若发现流程未能确定交易对手,你可以自行指定:发送 {"action": "beneficiary_vasp", "beneficiary_vasp": "<directory VASP id>"}(id 取自 GET /v3/travel-rule/vasps/)。 转账会被路由至该 VASP 并重新发送。 只有处于 COUNTERPARTY_VASP_NOT_FOUND、COUNTERPARTY_VASP_NOT_REACHABLE 或 NOT_ENOUGH_COUNTERPARTY_DATA 状态的出站转账才接受此操作;其他任何状态返回 409,未知 id 返回 404。

为什么转账会卡住

处于 COUNTERPARTY_VASP_NOT_FOUND 或 COUNTERPARTY_VASP_NOT_REACHABLE 状态的转账会说明其卡住的原因以及下一步的操作,且每次读取其交易时都会返回这些信息。 GET /v3/transactions/{transaction_id}/ 的 travel_rule 对象、POST /v3/transactions/ 的 201 响应,以及 GET /v3/transactions/ 的每一行都包含该信息,通过转账端点返回的转账对象中也包含该信息:
  • reason 是机器可读的原因,其他状态下为 ""。
  • next_actions 列出可推动转账继续的操作,其他状态下为 []。
  • delivery 是转账需要向对方发送的最新消息,包含 kind、status(QUEUED、SENDING、RETRYING、DELIVERED 或 FAILED)、rail、attempts、last_error、next_attempt_at 和 delivered_at;若无需向对方投递,则为 null。
  • discovery 记录 Didit 查找交易对手的过程,每个已执行的步骤对应一条:step、outcome(match、miss 或 skipped)、reason、vasp、rail 和 at。
email_undeliverable 和 delivery_failed 来自失败的投递,且仅出现在 COUNTERPARTY_VASP_NOT_REACHABLE 状态下。 失败的投递会优先决定 reason,因此 Didit 已找到的交易对手,绝不会被报告为未找到。 其余四个原因来自查找记录,两种状态下均可出现。 重新发送会推动转账继续,因此其 reason 会被清空。 由失败投递引起的状态变更,其时间线条目在 reason 下带有相同的值。 若邮件服务商拒收发往上文示例转账合规邮箱的邮件,该交易的 travel_rule 块(节选)如下:
此处 delivery 与 reason 一致,因为发送本身被拒。 提醒邮件被拒或之后才收到退信时,delivery.status 仍为 DELIVERED:首封邮件确已发出。 要了解转账停滞的原因,应查看 reason,而非 delivery。 要修复此问题,请重新提供交易对手的合规邮箱,然后重新发送:
update_compliance_email 会将该地址保存为本笔转账的 beneficiary_data.counterparty_vasp_email:它仅属于本笔转账,不会加入任何目录条目或联系人列表。 状态不变,时间线新增 compliance email updated 条目。在重新发送并将请求发往新地址之前,转账的 reason: email_undeliverable 保持不变。 只有处于 COUNTERPARTY_VASP_NOT_FOUND、COUNTERPARTY_VASP_NOT_REACHABLE 或 NOT_ENOUGH_COUNTERPARTY_DATA 状态的出站转账才接受此操作;其他转账返回 409,缺少或格式错误的 compliance_email 返回 400。

已声明的自托管钱包

当你的客户告知目标方是其本人的自托管(非托管)钱包时,请在交易上声明该钱包,而不是让路由自行查找,结果发现背后并无 VASP:将交易对手的支付方式类型设置为 unhosted_wallet。
此声明会完全跳过路由:
  • 不会尝试任何通道,因为没有可与之交换数据的交易对手 VASP,转账将直接创建为 UNCONFIRMED_OWNERSHIP 状态。
  • 当 auto_wallet_verification 开启时(默认开启),Didit 会自动生成一个与该交易绑定的钱包所有权验证组件会话,并在交易的 action_required 块中返回该会话;SDK 会在客户端提交时自动启动该组件。
  • 客户证明对该钱包的控制权后,转账会执行收款人姓名比对,并推进至 COMPLETED 状态(比对失败则进入 COUNTERPARTY_MISMATCHED_DATA)。
这是以 API 形式实现的欧盟 TFR 自托管钱包义务:验证非托管钱包的所有权,而不是与交易对手 VASP 交换数据。 该声明读取自出站转账的目标端、以及入站转账的来源端的支付方式,两种情况下,读取的都是交易对手一方。 已声明为非托管的转账已处于最终的无通道路径,因此 UNCONFIRMED_OWNERSHIP 不是可重新发送的状态:请完成所有权证明(或取消),而不是调用 action: "resend"。

接收

确认钱包归属

转账会在以下两种情况下停留在 UNCONFIRMED_OWNERSHIP 状态:
  • 入站转账匹配到一条尚未验证归属的地址簿条目。
  • 交易对手的钱包已声明为自托管钱包(counterparty.payment_method.method_type: "unhosted_wallet"),适用于出站提现或入站存款。参见已声明的自托管钱包。
您的应用需要确认或拒绝该转账:
请求体接受 confirmed(必填,布尔值)和可选的 wallet_address。 该接口只接受处于以下任一状态的转账。对于其他状态,接口返回 409,响应为 {"detail": "Transfer is not awaiting ownership confirmation."}:
  • UNCONFIRMED_OWNERSHIP,两个方向均适用。
  • 入站转账处于 ON_HOLD。
  • 入站 TRP 转账处于 UNCONFIRMED_OWNERSHIP、ON_HOLD 或 COUNTERPARTY_MISMATCHED_DATA,以便合规官手动处理交易对手的查询。
对于 Didit 自行创建的转账(INTERNAL 通道、抢先登记,或已声明的自托管钱包):
  • confirmed: true 会将匹配的地址簿条目标记为已验证归属,然后按该条目的 holder_name 进行姓名匹配:通过则为 COMPLETED,不通过则为 COUNTERPARTY_MISMATCHED_DATA。 INTERNAL 通道的对应方(如有)会得到相同结果。 对于已声明的自托管钱包,confirmed: true 表示您的客户已核实交易对手钱包的控制人,并完成转账(COMPLETED),无论出站还是入站。 若入站转账的存款已结算,则会直接进入 FINISHED。
  • confirmed: false 会将转账双方都更新为 COUNTERPARTY_VASP_GENERAL_DECLINE。
  • 系统只按地址在您自己的地址簿中查找匹配条目,不涉及链。 对于入站 ON_HOLD 转账,若没有匹配条目,则会根据转账的 beneficiary_data.wallet_address 创建条目,并标记为已验证。 已声明的自托管钱包是例外:该钱包会按下文所述,以已验证归属的状态登记到您的地址簿中。 其他情况下,若条目不存在,则返回 409,响应为 {"detail": "wallet address entry no longer available"}。已删除的条目也会返回同样的结果。
对于入站 TRP 转账,同一调用用于回复交易对手的查询:
  • confirmed: true 需要一个用于返回的付款地址,按以下顺序取值:请求中的 wallet_address、匹配的条目、beneficiary_data.wallet_address。若三者都没有,请求返回 400,响应为 {"wallet_address": ["wallet_address is required to approve."]}。Didit 会创建或验证该条目,向交易对手发送查询结果回调,设置 ownership_confirmed,并将转账更新为 COMPLETED。
  • confirmed: false 会发送拒绝结果,并将转账更新为 COUNTERPARTY_VASP_GENERAL_DECLINE。
  • 若无法访问交易对手的回调端点,请求返回 502,转账保持当前状态。若为批准操作,地址簿条目仍会被创建或标记为已验证。
对于已声明的自托管钱包,您需要验证的钱包属于交易对手:出站提现时为提现的目标地址,入站存款时为来源钱包(即汇款人的钱包)。Didit 会将该钱包以已验证归属的状态添加到地址簿中,并以交易对手的姓名(入站存款时为汇款人的姓名)进行匹配。若地址簿中该地址已登记为其他持有人的姓名,则转账改为 COUNTERPARTY_MISMATCHED_DATA。 若转账未指定任何交易对手钱包,请在请求体中传入 wallet_address。若转账和请求中都没有提供地址,请求将被拒绝,并返回 400。
  • 已在其网络上得到应答的网络转账(VerifyVASP 转账,或已裁定的 GTR 或 Sygna Bridge 转账)返回 409(参见来自网络的转账)。
响应为上文所述的完整转账对象。 新的 INTERNAL 转账不会在此等待:它只会送达已证明钱包归属的客户。 在该规则生效之前已在等待的旧 INTERNAL 转账,会一直隐藏汇款人的信息,直到您证明对钱包的控制权(通过签名消息或测试存款)。在此之前确认该转账将返回 409。拒绝该转账仍然有效。 当交易对手回复该钱包为自托管钱包时(目前只有 Didit Test VASP 在沙盒中给出此答复),确认操作会以收款人的姓名将该钱包添加到您的地址簿,并进行姓名匹配:匹配则完成转账,并将钱包标记为已验证。

来自网络的转账

Didit 还可以接收交易对手通过 GTR、VERIFYVASP 或 SYGNA 发送的 Travel Rule 转账。 接收功能由 Didit 按网络分别开启,目前尚未开启任何网络:还需要各网络登记 Didit 的端点,而 Didit 目前尚未加入这些网络。 TRUST 转账无法接收。 网络开启后,其投递的消息按以下方式处理:
  • 路由。 当消息包含您在该网络上所连接会员身份的参与者代码时,消息会送达您的应用。只有当您是唯一一位证明了收款钱包归属的在用 Didit 客户时,发往 Didit 自身会员身份的消息才会送达您。其他消息一律拒绝,因此任何客户都不会收到他人的转账。
  • 决策。 Didit 会在您的应用中创建入站转账,并按照 TRP 查询的方式进行裁定:钱包匹配、归属验证、姓名匹配以及 inbound_auto_accept。
  • 仅处理一次。 网络会反复重发消息,直到得到应答。重复的消息会获得首次消息相同的应答,且不会重复创建或裁定任何转账。
  • 您的审核,适用于 GTR 和 SYGNA。 等待您处理的转账(UNCONFIRMED_OWNERSHIP、ON_HOLD 或 COUNTERPARTY_MISMATCHED_DATA)需通过 POST .../travel-rule/ownership/ 进行裁定:confirmed: true 表示批准(若转账未指定钱包,需传入 wallet_address),confirmed: false 表示拒绝。Didit 会在响应之后,按相同的重试机制向网络应答。已应答的转账再次操作将返回 409。
  • VERIFYVASP 不支持事后应答。 VerifyVASP 会在其提出询问时即获得应答,因此需要您审核的转账会被立即拒绝,之后无法再裁定(返回 409)。

脱敏的交易对手数据

在确认钱包所有权之前,入站转账中的交易对手个人数据会以脱敏形式返回,而不是直接省略。 每个单词保留首字母,钱包、链和 VASP 路由信息保持可读。 data_masked 为 true,交易详情、列表和 CSV 导出中的交易对手信息同样脱敏。 确认所有权后,将显示真实数据,同时 data_unmasked 记录审计条目:
reason 可为 ownership_confirmed、wallet_proof、address_book_match、own_verified_wallet、inquiry_approved(您已批准 TRP 查询,或已批准 GTR 或 Sygna 消息)、known_payment_method(您的记录中该终端用户的钱包已作出响应)或 travel_address(每个钱包的 Travel Address 指明了该钱包)。 INTERNAL 入站转账从创建时起即带有 data_unmasked,并带有 reason: wallet_proof,因为只有证明了钱包的收款方才会收到该记录。 actor 为控制台用户的邮箱或 API 密钥标签;自动决策时为空。 Travel Rule 转账日志报告(CSV 和 PDF)在确认所有权之前,同样对入站转账的姓名进行脱敏。您向监管机构提交的报告,例如 goAML XML 和监管报告 PDF,包含交易对手的真实数据。

不匹配反馈

COUNTERPARTY_MISMATCHED_DATA 转账现在会列出存在差异的字段。 data_match 保存比对结果,mismatched_fields 列出这些字段。 两者只包含字段名称和比对结果,绝不包含字段值,因此在数据脱敏时仍可读:
时间线条目会列出字段名称,例如 “beneficiary date of birth does not match wallet holder”。 TRP 在不匹配后发出的拒绝会告知发起方 VASP 哪些字段存在差异,例如 “Beneficiary data does not match the wallet holder: name”。 对方 VASP 获知的信息是有意限制的:姓名不一致时,只报告姓名这一字段(mismatched_fields: ["name"],其他所有字段为 not_compared);姓名一致后,所有存在差异的字段都会被列出。这适用于 INTERNAL 交换中的发送方一侧,以及 TRP 拒绝。 双方均缺失的姓名显示为 not_compared,不视为不匹配;国家按其所指代的国家进行比对,因此 ES 与 ESP 视为一致。

姓名匹配分数

每个经过姓名比对的转账都带有 name_match,做出判定的时间线条目会在其 detail 旁边携带同一对象:
  • score 是两个完整姓名的相似度,范围为 0 到 100;任一姓名为空时为 0。matched 是按 strictness 得出的结果,因此两者可能不一致:FUZZY 仅根据其自身的相似度比率 0.85 作出判定。
  • matched_names 是转账姓名中在对方姓名里找到的单词;mismatched_names 是任一方拥有而另一方缺少的单词。
  • method 可为 none、exact_token、token_subset、token_containment 或 sequence_ratio,分别对应 NONE、STRICT、DEFAULT、CONTAINS 和 FUZZY。
  • compared_with 可为 wallet_holder(该钱包记录的持有人)或 counterparty_vasp(交易对手在邮件回复页面给出的姓名,或 Didit 测试 VASP 的回复)。
  • 转账结果以 data_match 为准,它会比对所有字段,因此转账可能为 COUNTERPARTY_MISMATCHED_DATA,而 name_match.matched 仍为 true。
  • name_match 会出现在 Travel Rule 端点返回的转账对象中,以及交易中嵌入的 travel_rule 中;在未比对姓名之前为 null。转账列表和 Webhook 不包含该字段。
  • 当双方处于脱敏状态时,以及在 INTERNAL 交换的另一位客户的副本上,姓名会被隐藏。

消息与证件请求

两家 VASP 可以在 Didit 内解决有争议的转账,无需通过邮件。 GET 和 POST /v3/transactions/{transaction_id}/travel-rule/messages/ 用于列出和发送转账的消息:
  • kind 为 MESSAGE(默认值)或 DOCUMENT_REQUEST。证件请求至少需要 requested_documents 中的一项(最多 10 项);消息则需要 body(最多 5000 个字符)或一个文件。
  • reply_to 指向同一转账中的较早消息。对方回复中若附带证件,则会满足其所回应的证件请求,并在该消息上设置 fulfilled_at。您自己的回复不会满足您自己的请求。
  • 使用 multipart 发送时,通过 files 最多可附加 5 个文件,每个文件最大 10 MB,格式为 PDF、PNG、JPEG 或 WebP。Didit 会检查每个文件的实际内容,而不仅是其声明的类型;任何其他文件(无论其声明的类型如何)都会使请求针对 files 返回 400(“Attach PDF, PNG, JPEG or WebP files only.”)。
  • 每笔转账最多包含 100 条消息,其中最多 20 条可带附件(每条最多 5 个文件),双方合计计算;超出任一上限时,请求返回 400。消息附件不计入交易本身的证件。
  • 消息支持 INTERNAL 和 EMAIL 通道。在 INTERNAL 通道中,另一位 Didit 客户会在其一侧的配对转账中看到该消息。在 EMAIL 通道中,系统会向交易对手发送邮件,对方通过领取门户作出回复。若通知邮件无法发送,消息仍会保存,请求返回 201。
  • 以下情况请求返回 409,并在 detail 中注明原因:经由 TRP、GTR、TRUST、VerifyVASP 或 Sygna 传输的转账(这些协议不支持消息);尚无交易对手的转账;数据与钱包持有人不匹配的 INTERNAL 转账(收款方未收到任何内容);收款方尚未证明对钱包的控制权的 INTERNAL 转账(在其证明之前,双方均受此限制);交易对手已不再拥有合规邮箱地址的 EMAIL 转账;以及领取链接已过期或转账已关闭的 EMAIL 转账。
  • 交易对手回复时不会触发任何 Webhook。请读取消息端点。
  • 告知交易对手有新消息的邮件以英文发送。

地址簿

注册您控制的钱包,使入站转账(INTERNAL 通道、入站 TRP 查询,以及存款后注册)能够与之匹配。使用 POST/GET /v3/travel-rule/wallet-addresses/ 以及 PATCH/DELETE /v3/travel-rule/wallet-addresses/{entry_uuid}/ 进行管理。
PATCH 接受 holder_name、holder_vendor_data、entity_type 和 travel_address,且只返回这四个字段。 DELETE 删除该条目(返回 204)。其地址随即释放,可重新登记,并立即停止匹配新的转账。
地址匹配不区分大小写,在备注网络上还包括 memo,并受 chain 限定。 转账携带链信息时,只有当条目的 chain 与之相同(不区分大小写)或为空时,条目才会匹配。 链名称按文本比较,不会做翻译,因此存储为 ethereum 的条目不会匹配链为 ETH 的转账。 出站转账的链依次取自 beneficiary_data.chain、transaction_details.crypto_params.crypto_chain、custom_properties.crypto_chain,然后是币种(例如 ETH;对于 USDT 和 USDC,则由 payment_reference_id 推断出链)。仅当 Didit 能识别该链时才会设置。充值后登记的条目则取其 chain 字段,并转为小写。 入站 TRP 查询不考虑链:它们按地址匹配;若查询未指定钱包,则按收款人姓名与您已验证的条目匹配。 POST .../travel-rule/ownership/ 同样仅按地址匹配。 多个条目匹配时,INTERNAL 通道和充值后登记会优先选择已验证所有权的条目,其次选择最早的条目;出站 TRP 查找则取存有 Travel Address 的最早条目。 入站 TRP 查询和所有权 endpoint 会取任一匹配条目,因此请尽量为每个地址只保留一个条目。 当同一地址在其他多个应用中存在已验证条目时,INTERNAL 通道将完全不匹配任何条目。

批量导入钱包

使用 POST /v3/travel-rule/wallet-addresses/import/ 可在一次调用中导入最多 10,000 个钱包。数据格式可以是 JSON({"entries": [...]} 或纯数组),也可以是 UTF-8 编码、不超过 5 MB、带表头行的 CSV 文件。 每一行通过 address、address_hash(小写地址的 SHA-256,64 位十六进制或 44 位 base64 字符),或两者同时指定钱包,并可包含上述任意条目字段。若只发送哈希,即可在不披露地址的情况下登记钱包。它会像其他条目一样匹配发往该地址的转账,并可通过钱包所有权组件予以证明。
导入是幂等的,并按发送顺序报告每一行的结果:created、existing(相同的钱包、链和 memo 已在名录中,保持不变)、duplicate(与前面某行重复,由 duplicate_of_row 指明)或 failed(附带其 errors)。 单行错误不会影响其他行:没有行失败时返回 200,有行失败时返回 207,并在 total、created、existing、duplicate 和 failed 中给出计数。 CSV 中的空单元格视为未发送,导入程序不读取的列会被忽略,因此来自其他工具的导出文件可原样导入。 在 GET /v3/travel-rule/transfers/ 中,每一行除两个钱包外,还包含 originator_memo 和 beneficiary_memo。

针对无法触达的交易对手的邮件领取

当没有任何协议通道能够触达交易对手时,Didit 会回退到 EMAIL:向 beneficiary_data.counterparty_vasp_email 发送一次性领取链接。若未提供该邮箱,则根据 beneficiary_data.counterparty_vasp_name,从 VASP 目录注册表中解析出邮箱。 收件人无需 Didit 账户或 API 密钥,链接中的令牌即为身份验证。 请求的发送方式如下:
  • 发往正确的地址。 您传入的 counterparty_vasp_email 是唯一收件人。否则,Didit 最多向三个地址发送:交易对手的联系人中未退信的地址(先是您自己的联系人,然后是平台联系人,之前已回复过的联系人优先),若仍有空位,则再发送至目录条目的合规邮箱。每个地址各收到一封邮件。
  • 以您的名义。 邮件由 Didit 的地址发出,发件人显示为“您的法定名称 via Didit”,语言依据交易对手所在司法辖区确定(未知时使用英语)。链接会以该语言打开回复页面。您不会收到副本,请通过转账的时间线跟进。
  • 附带提醒。 在交易对手回复之前,Didit 会在截止时间前 72、24 和 6 小时提醒对方。提醒至少间隔上次请求或提醒后的 12 小时,且绝不会在截止时间之后发送。
  • 处理退信。 退信或垃圾邮件投诉会将其所触达的联系人标记为无效,并注明原因,转账时间线中也会记录。平台联系人随后对所有 Didit 客户均无效;您应用自己的联系人仅对您的应用无效。当 Didit 的邮件投递对某个地址完全停止发送时(在永久退信、垃圾邮件投诉或取消订阅之后),该地址上的每个联系人都会被标记为无效(suppressed);恢复向该地址发送后,这些联系人会重新变为有效。当没有可发送的地址时,转账变为 COUNTERPARTY_VASP_NOT_REACHABLE,并在时间线中记录接收邮件服务器给出的原因。您传入的 counterparty_vasp_email 因为是唯一收件人,若出现永久退信或垃圾邮件投诉,会立即导致上述结果;而临时退信(soft_bounce)若出现在该地址或目录条目自身的合规邮箱上,则请求保持开放,并继续发送提醒。
该链接会打开一个托管页面,展示待处理的信息交换,并为收款方调用以下两个公开 endpoint。 以上方的示例转账为例,领取信息如下:
reference 为转账的 uuid。originator_data 以及由其构建的 IVMS 101 ivms_request 仅包含您在 data_sharing_fields 中共享的汇款人字段;姓名和钱包始终包含在内。当您未发送换算后的法币值时,fiat_amount 和 fiat_currency 为空;contact 返回链接中 ?contact= 的值;decline_reasons 列出 decline_reason 可接受的值。当交易对手持有有效的 Didit 加入邀请时,join_invitation.eligible 为 true;邀请链接本身仅通过电子邮件发送。 该 endpoint 原样返回存储的金额,因此保留完整的 18 位小数,而不是交易详情对象所使用的截断格式。
decision 的值为 accept 或 decline。 选择 accept 时,提交的 beneficiary_name 会按您的姓名规则与转账的 beneficiary_data.name 进行比对:匹配则状态为 COMPLETED,否则为 COUNTERPARTY_MISMATCHED_DATA。交易对手也可以改为通过 ivms_response 发送完整的 IVMS 101 响应;此时其中的收款人姓名优先于 beneficiary_name。 选择 decline 时,转账状态变为 COUNTERPARTY_VASP_GENERAL_DECLINE。交易对手可从 decline_reasons 中选择一个 decline_reason,并附上 decline_detail(最多 512 个字符,当原因为 other 时必填)。您转账的时间线会记录这些信息,例如 counterparty declined: The beneficiary is not our customer。 响应为结果 {"status": "..."};拒绝时另外返回 decline_reason。交易对手作出答复后,两个 endpoint 均返回 410。 对于未知的 token,两个 endpoint 返回 404;时限结束后返回 410,即转账已离开 AWAITING_COUNTERPARTY 状态,或确认截止时间(自创建或最后一次重新发送起的 confirmation_timeout_hours)已过。 交易对手通过领取链接使用 GET 和 POST /v3/travel-rule/pickup/{token}/messages/ 读取和回复。无需 API 密钥,且仅接受 PDF、PNG、JPEG 或 WebP 附件;链接过期或转账关闭后,返回 410。 您发送的消息会将您的 VASP 名称显示为 author 和附件的 uploaded_by,而不会显示背后的个人或 API 密钥。

未匹配的存款

入站存款可能早于发起方 VASP 的 Travel Rule 数据到达。 在数据到达之前,此类存款将保持为 AWAITING_COUNTERPARTY 或 NOT_ENOUGH_COUNTERPARTY_DATA 状态。 使用具有 transactions 权限的 API 密钥列出仍在等待的存款:
响应使用与 GET /v3/travel-rule/transfers/ 相同的行格式,仅限于等待发起方 VASP 数据的入站存款。 当数据以单独收到的消息形式到达时,请自行将两者配对:
{transaction_uuid} 为该存款。 transaction_id 为所收到的 Travel Rule 消息对应的交易。 该调用返回 { "deposit": ..., "message": ... }。 当任一交易已不存在时返回 404;当任一方已进入后续状态时,返回 409 及 travel_rule_match_conflict(“This deposit can no longer be matched.”)。

存款后的 sunrise 登记

当加密货币存款在任何 Travel Rule 信息交换发生之前已在链上完成结算时(例如发送方 VASP 无法联系,或您需要回填历史存款),请使用 POST /v3/travel-rule/inbound/ 事后登记该存款。
originating_vasp.travel_address 必须是真实且校验和有效的 Travel Address;占位符会返回 400,并附带 "Invalid travel address."。 originating_vasp.lei 必须为空,或为 LEI 格式的 20 个字符(前 18 位为字母或数字,后 2 位为数字);其他任何值都会返回 400,并附带 "Invalid LEI: expected 20 alphanumeric characters (ISO 17442)."。 Didit 仅校验此格式,不校验 ISO 17442 的校验位。 Didit 会创建一笔入账的 travelRule 交易(如果你已提交过相同哈希和钱包的入账充值,且该充值尚无 Travel Rule 转账,则复用该充值),并根据地址及其 memo,在你的钱包地址簿中解析该转账:
  • 没有匹配条目 -> ON_HOLD。 使用 POST .../travel-rule/ownership/ 解析它:confirmed: true 会将该钱包以已验证状态添加到你的地址簿中,并执行姓名匹配;若匹配成功,转账先变为 COMPLETED,再变为 FINISHED。
  • 条目存在但所有权未经证明 -> UNCONFIRMED_OWNERSHIP。
  • 收款人姓名与条目的 holder_name 不一致 -> COUNTERPARTY_MISMATCHED_DATA。
  • 条目已验证且姓名匹配 -> COMPLETED,随后立即变为 FINISHED(该充值已完成结算)。
对于上文示例中已登记的已验证地址簿条目,响应如下:
新交易的 txn_id 为 tr-in- 加上 txid 的前 80 个字符,再加上由 txid 和钱包计算出的 12 位哈希。 当本次调用登记了该充值时,created 为 true(HTTP 201);当相同的 txid 和 wallet_address 已登记时,则为 false(HTTP 200),此时原有转账原样返回。 在已验证条目的路径上,两次状态转换都在端点响应之前完成,因此同步响应已显示终态 FINISHED,中间的 COMPLETED 步骤仍会记录在转账的 timeline 中。 每次状态转换都会触发一个 travel_rule.status.updated Webhook(COMPLETED 和 FINISHED 各触发一次)。 若 Didit 创建了新交易,则先发送 transaction.created,之后再发送这些事件。 登记不收取任何 Travel Rule 或监控费用。 启用加密货币监控且 chain 为 Didit 可筛查的链时,新创建的充值也会被筛查,并按 Wallet Verification & Screening 费率计费一次。

钱包所有权小组件

若要将转账移出 UNCONFIRMED_OWNERSHIP,或在任何转账到达之前预先验证钱包,请通过 POST /v3/travel-rule/widget-session/ 生成托管的钱包所有权小组件,并将客户引导至返回的 url。该小组件通过消息签名(包括 EVM 智能合约账户(通过 ERC-1271 和 ERC-6492))、Satoshi test、截图或自我声明来证明对钱包的控制权,然后将匹配的地址簿条目标记为已验证,以便交易所继续处理。 截图是例外:它本身永远无法验证钱包,因此你的合规团队需要审核截图,并使用 POST .../travel-rule/ownership/ 确认处于 UNCONFIRMED_OWNERSHIP 的转账。 有关完整流程、证明方法,以及小组件必须在真实浏览器中打开、绝不能在移动端 SDK 的 webview 内打开这一重要说明,请参阅钱包所有权小组件。

目录

GET /v3/travel-rule/vasps/ 用于搜索 VASP 目录:即共享目录条目以及 Didit 网络 的成员。每一行都会说明您的应用目前如何联系该 VASP。
search 可匹配名称或别名片段、精确匹配的 LEI,或域名(counterparty.example 或其上的 URL)。使用以下参数缩小结果范围: Didit 网络成员不参与评分,因此 risk 和 responsiveness 仅返回目录条目。结果按名称排序,并通过 limit(默认值为 50)和 offset 进行分页。未知的网络、国家/地区代码、风险等级或响应度状态会返回 400,并指明出错字段。GET /v3/travel-rule/vasps/{vasp_id}/ 通过 id 返回一行数据。您自己的 VASP 资料永远不会出现在您自己的结果中。 dd_status、dd_score、dd_score_breakdown、dd_assessed_at、dd_score_semantic、risk_level、responsiveness 和 essential_checks 承载目录条目的共享尽职调查评估。decision、entity_screening 和 questionnaires 是您的应用对该 VASP 的自有记录,其他客户看不到。关于各字段的含义,参见 交易对手尽职调查;应使用交易对手规则字段据此设置门控,而不是在代码中内联分支判断。Didit 网络成员不参与评分:dd_status 为 COMPLETED,dd_score 为 null,risk_level 为空,明细也为空。

路由

routes 列出您的应用可向该 VASP 投递的方式,顺序即路由阶梯的尝试顺序;至少有一个为 available 时,reachable 为 true:
  • TRP:当条目带有目录已验证的 TRP endpoint 时。
  • GTR、TRUST、VERIFYVASP、SYGNA:当某个网络以某个代码列出该 VASP 时。仅当您的应用目前可以通过该网络发送时,路由才为 available(via: own_membership 表示您自己已连接的成员身份,via: didit_membership 表示 Didit 的成员身份)。否则路由为 unavailable,并附带 reason: no_membership 或 reason: network_switched_off,绝不会显示为联系该 VASP 的方式。Didit 自有的网络成员身份尚未上线,因此目前网络路由仅在您通过 Marketplace 连接的成员身份下可用。
  • EMAIL:当该条目有合规联系人时。
  • INTERNAL:适用于 Didit 网络成员。
TRISA 列表会出现在 networks 下,告诉您该 VASP 在 TRISA 上的身份,但 Didit 没有 TRISA 通道,因此它永远不会成为路由。 沙盒应用仅向 Didit 测试 VASP 发送,因此对它而言没有可用的目录路由:每条路由均为 unavailable 且附带 reason: sandbox_application,每一行的 reachable: false,reachable=true 不返回任何行。

品牌及其实体

通过多个受监管实体运营的品牌是一行数据,其 entities 为接收其转账的法律实体;实体行通过 umbrella 指回其所属品牌。指定品牌的转账会发往其某一实体,从所有实体中选择:优先选择 beneficiary_data.counterparty_vasp_jurisdiction 中声明的司法辖区内的实体;否则选择与目的钱包关联的区块链分析归因所指向的实体;若未声明司法辖区,则选择品牌下唯一的实体。只有在选定实体后,才要求该实体可达;若不可达,转账绝不会改发到其他实体或品牌本身。当没有实体符合条件时(两者同样符合,或声明的司法辖区不属于任何一个实体),使用品牌自身的路由;若没有品牌路由,转账将返回 COUNTERPARTY_VASP_NOT_FOUND。究竟由哪个法律实体接收汇款人的数据,绝不是猜测的结果,也绝不是由哪个实体恰好有联系人来决定的。 若多个条目以相同方式命名,例如共用同一商号的集团公司,则以同一规则加以区分:选择声明的司法辖区内的条目,否则选择区块链分析归因所关联的条目。若两者均无法确定其一,则不使用任何条目,这些信息视为未指明任何目录条目。

联系人

contacts 是 EMAIL 通道发送邮件的地址。scope: platform 的联系人服务于所有 Didit 客户:由 Didit 筛选维护(source: staff),或该 VASP 自有域名下的某个地址通过其回复链接回应了请求(source: learned)。scope: application 的联系人仅对您的应用私有:您添加的联系人(source: application),以及 VASP 自有域名之外、回应过您请求的地址(source: learned)。转账时,会先向您应用自己的联系人发送邮件,其次是曾经回复过的平台联系人(已设置 verified_at),最后是其他联系人。 使用交易对手联系人 API 管理您应用自己的联系人:
  • GET /v3/travel-rule/counterparty-contacts/ 列出您的应用可以发送到的所有联系人,包括平台联系人和退信的联系人,按最新排序,并通过 limit 和 offset 分页。可使用 ?counterparty= 加目录条目 id 进行筛选;不是 UUID 的值会返回 400。
  • POST 添加一个私有联系人(counterparty、email,可选 name),返回 201。若您已为该条目添加过相同的地址,则返回该联系人。未知条目返回 400("No directory entry with this id.")。
  • DELETE /v3/travel-rule/counterparty-contacts/{contact_uuid}/ 删除您自己的一个联系人(返回 204)。平台联系人无法删除,返回 404。
被退信或被投诉的联系人会带有 is_invalid: true,并附带 invalid_reason(hard_bounce、soft_bounce、spam_complaint 或 suppressed)、invalid_detail 和 invalid_at,此时 EMAIL 通道会跳过该联系人。对于平台联系人和通过 API 密钥添加的联系人,created_by 为空。

条目如何进入目录

  • ESMA 的 MiCA 加密资产服务提供商临时登记册,每周读取一次:包括每家提供商的名称、LEI 和母国成员国。
  • 公开的 TRISA 目录,每周读取一次:包括每位成员是谁、其所在国家/地区及其 TRISA 列表项。目录连续三周不再显示的列表项将被移除。
  • 全球 LEI 登记册用于补充条目的 LEI、其他法定名称及国家/地区,并可根据条目在其所在国家/地区的准确法定名称查找该条目的 LEI。
  • 区块链分析归因 用于添加或匹配拥有目标钱包的 VASP,并将归因得到的名称保留为别名。
  • Didit 工作人员负责整理条目,包括已核实的路由标识符和网络登记信息、合规联系人、别名、品牌及其实体、已合并的重复条目以及隐藏条目。
客户就交易对手报告的数据,例如入站的 originating_vasp 或旅行地址,仅保留在该客户的转账记录中,绝不会更改共享条目。条目按 LEI 优先匹配,其次按准确名称或别名匹配,并以补充信息的方式丰富现有条目,而不是重复创建。

Didit 网络

您的 VASP 资料属于 Didit 网络,因此只有同时满足以下所有条件时,其他 Didit 客户才能在目录和终端用户的 VASP 选择器中找到它:
  • 您的应用处于生产环境(非沙盒),且已开启 Travel Rule;
  • is_discoverable 为 true,并且已设置 legal_name;
  • 已设置并确认 compliance_email:使用 POST /v3/travel-rule/settings/compliance-email/confirmation/ 发送确认邮件,然后打开邮件中的链接。更改该地址需要重新确认;
  • Didit 未将该应用标记为测试、演示或内部应用。
INTERNAL 通道本身会在您已验证的钱包上完成投递,如 发送转账 中所述:它只要求您的应用处于生产环境、已开启 Travel Rule 并且 is_discoverable,而不要求列表中的其他条件。 GET /v3/travel-rule/settings/ 返回 didit_network:其中包含 listed 和 compliance_email_confirmed,以及在 missing 中列出的每个仍未满足的条件(travel_rule_off、sandbox_application、not_discoverable、legal_name_missing、compliance_email_missing、compliance_email_unconfirmed、excluded_by_staff、internal_organization)。

路由标识符

当您的转账通过 counterparty_vasp_lei 或 counterparty_vasp_name 指定交易对手时(也可以使用别名),出站路由会查询目录条目。每个条目针对其可触达的每个网络带有一个标识符,以及一个已验证的 TRP 端点及其合规联系人;routes 显示您的应用可以使用其中的哪些。您始终可以通过传入 交易对手解析字段 中的显式字段,为单笔转账绕过目录。

交易对手尽职调查

在您客户的资金转入另一家 VASP 之前,您需要确认该 VASP 是谁,以及您是否接受它。对交易对手的尽职调查分为两个层面:
  • 共享评估。 每条目录记录都带有尽职调查评分、风险等级、响应状态和核心检查报告。这些结果由 Didit 根据平台自身的数据计算,因此每位客户看到的数值都相同。
  • 您自己的记录。 您对该 VASP 的决策、对它进行的制裁筛查和负面新闻筛查,以及您与它交换的尽职调查问卷,仅属于您的应用。其他客户看不到这些记录,它们也不会改变共享记录。
无论是目录记录还是 Didit 网络成员,您的自有记录都适用。请使用目录显示的 id 来引用它们。

评分与风险等级

dd_score 的范围是 0 到 100,分数越高越安全。每个结果都会在 dd_score_semantic 中说明这一点,其值始终为 higher_is_safer。risk_level 是评分所在的区间: 评分是七个组成部分的总和。dd_score_breakdown 以 {points, max, reason, detail} 的形式列出每个部分:max 是该部分的权重,reason 是可供您翻译的机器可读代码,detail 是一行英文说明。 分值四舍五入到一位小数,总分四舍五入到整数。history 与响应能力读取的是同一批请求,但没有时间窗口:COMPLETED 或 FINISHED 的交换算作成功,EXPIRED、COUNTERPARTY_MISMATCHED_DATA 或 COUNTERPARTY_VASP_GENERAL_DECLINE 的交换算作失败。取消是发送方自己的行为,从不计入。 当与该条目的交换完成、结束、过期、出现数据不匹配或被拒绝时,当条目被刷新或整理时,以及在每周目录刷新中的每个条目上,Didit 都会重新计算评估。dd_assessed_at 表示上一次计算的时间;尚未评估的条目没有 dd_assessed_at,其 dd_score 为 0,risk_level 为空,因此请以 risk_level 为准,而不要依据原始分数判断。Didit 网络成员不参与评分:其 dd_score 为 null,risk_level 为空,dd_score_breakdown 也为空。

核心检查

essential_checks 是 Didit 对每条目录记录执行的四项检查的简要报告。这些检查仅使用平台已验证的来源,从不使用客户报告的数据。 checks 中的每项检查都会报告其 status(pass、fail,或当没有可用来源能够判定时为 unknown)、机器可读的 reason,以及一行英文 detail。passed、failed、unknown 和 total 统计检查数量,level 为 essential,checked_at 表示报告的生成时间。essentials 组成部分计算已决检查中通过的比例,因此 unknown 检查既不计入该条目的加分,也不计入减分。在每周目录刷新首次检查某条目之前,报告为空;对于 Didit 网络成员,报告始终为空。

响应能力

responsiveness 表示该 VASP 是否回应 Travel Rule 请求:
total 统计过去 90 天内,Didit 客户向该 VASP 发起且结果已决的请求数量;answered 统计其中获得回应的请求数量。
  • 计入: 通过网络或协议通道发送的请求,以及发送至共享地址的邮件请求。共享地址指条目的合规地址或平台联系人。
  • 从不计入: 发送至某位客户输入的地址,或客户私人联系方式的邮件请求。该交换只保留在该客户自己的转账历史中,不会为所有其他客户标记该 VASP。
  • 获得回应: COMPLETED、FINISHED、COUNTERPARTY_VASP_GENERAL_DECLINE 或 COUNTERPARTY_MISMATCHED_DATA。拒绝或数据不匹配也是一种回应,说明该 VASP 已参与交换。
  • 未获回应: EXPIRED。
  • 不计入任何一类: 其他所有状态。CANCELLED 请求是发送方自己的行为;COUNTERPARTY_VASP_NOT_REACHABLE 可能是发送方一侧的故障;仍在进行中的请求尚未有结果。
Didit 网络成员在 Didit 内部作出响应,始终显示 UNKNOWN,且计数为零。对无响应的交易对手采取行动时,可使用无响应策略或 travel-rule-counterparty-unresponsive 预设。

您对交易对手的决策

使用 PUT /v3/travel-rule/vasps/{vasp_id}/decision/ 记录贵合规团队对某交易对手的结论:
  • 该决策仅对您的应用可见:其他客户永远看不到,它也绝不会改变共享条目。
  • 决策本身不产生任何效果,也绝不会改变转账的路由方式。它通过 counterparty_dd_status 规则字段作用于您的交易:安装预设,或基于该字段编写您自己的规则。
  • 对某品牌作出的决策适用于其每个尚无自身决策的实体,该实体的 inherited_from 会显示该品牌。对实体作出的决策会覆盖该实体的品牌决策。
  • GET 返回适用的决策,或 {"decision": null}。DELETE 会清除您自己的决策,并返回之后适用的决策:对实体而言是品牌决策,否则为 null。若您的应用对该交易对手没有自己的决策,则返回 404。
  • reason 为可选项,最多 255 个字符,每次 PUT 都会替换它。decided_by 是最近一次作出或修改决策的控制台用户;若由 API 密钥操作,则为空。

交易对手筛查

交易对手筛查会将交易对手 VASP 本身作为公司,对照制裁和负面新闻进行检查。它需主动开启并收费:在您的设置中使用 counterparty_screening_enabled 开启。关闭期间,不会进行任何筛查,也不会计费。
  • 计费。 每次新的筛查都会按贵组织的企业 AML 筛查价格收费。GET /v3/travel-rule/vasps/{vasp_id}/screening/ 免费返回该 price、fresh_days 以及筛查是否为 enabled。距今不满 30 天的筛查视为有效:POST 会以 200 和 outcome: reused 再次返回该结果,且不收费,除非您发送 refresh: true。新的筛查以 201 和 outcome: screened 返回。沙盒应用从不进行筛查,也从不收费。
  • 自动筛查。 开启筛查后,Didit 还会在外发转账开始时、即您的规则评估交易之前,对该转账所涉的交易对手进行筛查,复用与计费规则相同。该处的拒绝或失败绝不会导致转账失败。
  • 结果。 当没有需要关注的可能匹配时,status 为 Approved;若存在可能的制裁或负面新闻匹配,则为 In Review 或 Declined。当有效筛查的结果为 In Review 或 Declined 时,flagged 为 true。
  • 效果。 只要您对某交易对手的最新筛查已被标记且筛查保持开启,您的规则中 counterparty_risk_level 即为 HIGH,因此一旦安装,travel-rule-counterparty-high-risk 预设会保留其转账。目录中的共享 risk_level 不会改变。
  • 隐私。 该筛查仅对您的应用可见:其他客户永远看不到,它也绝不会改变共享条目。目录会以 entity_screening 显示您最新的一次筛查。
  • 拒绝情况。 筛查关闭、应用为沙盒应用,或同一交易对手的筛查正在进行时,返回 409。余额不足以支付价格时,返回 403 及 code: insufficient_credits。筛查无法完成时,返回 502。以上情况均不会产生任何费用。

尽职调查问卷

请求交易对手提供尽职调查答复,使用 Didit 的标准问卷。POST /v3/travel-rule/vasps/{vasp_id}/questionnaires/ 会将问卷发送至交易对手记录在案的合规邮箱,并附上一个通往答复页面的一次性链接:
  • 发送至何处。 sent_to 必须是记录在案的合规邮箱:对于目录条目,可以是其合规邮箱,或贵应用在 contacts 中看到的联系人;对于 Didit 网络成员,则为其已确认的合规邮箱。若省略该字段,则使用发给交易对手的 Travel Rule 邮件所用的地址,依次为贵方自己的联系人、平台联系人,然后是条目的合规邮箱。Didit 绝不会把问卷发送到其他任何地方;若交易对手没有记录在案的合规邮箱,则返回 400。
  • 作答。 该链接会打开 /v3/travel-rule/questionnaires/{token}/,这是供交易对手人员使用的页面,无需账户或 API 密钥。对方需回答每个问题,每题最多 2,000 个字符(不适用时填写 N/A),并提交一次。交易对手也可以向同一链接发送 {"answers": {"<question id>": "<answer>"}}。已使用、已被替换或已超过截止时间的链接会显示过期页面。邮件和页面已翻译;问题本身始终为英文,以确保其含义在各语言间保持一致。
  • 截止时间。 交易对手有 30 天时间作答(expires_at)。答复保持有效 365 天(valid_until),在此期间 current 为 true。超过截止时间仍未作答的问卷,以及超过有效期的答复,都会变为 EXPIRED。
  • 每个交易对手仅保留一份未完成问卷。 新发送的问卷会替换您先前发给同一交易对手但尚未作答的问卷:旧问卷变为 EXPIRED,其链接失效。同一邮箱每分钟只能接收一封邮件;发送更频繁的请求会返回 429。
  • 读取答复。 GET /v3/travel-rule/vasps/{vasp_id}/questionnaires/ 会按从新到旧的顺序列出您与该交易对手的问卷;作答后,answers 以问题 ID 为键。目录以 questionnaires 显示这些问卷。它们仅对您的应用可见。
表单版本 1 包含以下十二个问题:

与单一交易对手的转账

GET /v3/travel-rule/transfers/?counterparty={vasp_id} 会按目录中显示的 id,按最新排序列出您应用中与某一交易对手之间的 Travel Rule 转账:即交易对手为该目录条目的转账,或与该 Didit 网络成员之间的 INTERNAL 交换。无效的 id 值会返回 400。 每一行在 status 之后紧跟 reason:即转账自身的 reason。因此无需打开每笔转账,列表即可区分被退回的合规邮件与没有路由的交易对手。

Sunrise 与无响应策略

转账过期时(即在 AWAITING_COUNTERPARTY 状态下已超过 confirmation_timeout_hours),由 timeout_outcome 决定其交易的处理方式。两项设置可让您针对超时的两种常见原因进行区别处理: 两者均可设为 HOLD、REJECT 或 PROCEED,含义与 timeout_outcome 相同;也可设为空字符串,以跟随 timeout_outcome。两者默认均为空,因此在您设置之前不会有任何变化:
首先适用的一项决定结果:
  1. sunrise_policy:已设置,且交易对手的司法管辖区位于 sunrise_jurisdictions 中。
  2. non_responsive_policy:已设置,且交易对手为 UNRESPONSIVE。
  3. timeout_outcome:其他所有情况,包括转给 Didit 网络成员或没有目录条目的交易对手的转账。
sunrise_jurisdictions 为只读,当前为 ["CO", "KH", "VN"]。只有这些国家/地区被视为处于 sunrise 期间:其他任何司法管辖区,以及空白或未知的司法管辖区,均跟随 timeout_outcome,因此交易对手绝不会意外适用您的 sunrise 策略。已过期转账的时间线会注明所适用的结果,例如 sunrise_policy=PROCEED (counterparty jurisdiction CO does not enforce the Travel Rule yet)。过期后,您的规则仍会运行,因此在 PROCEED 下,诸如 EU TFR 的 tr_eu_expired_review 之类的规则仍可将交易转入审核。

规则字段与预设

四个 规则 字段记录您的应用所掌握的、交易的 Travel Rule 交换所抵达的交易对手信息:即其目录条目;若为 INTERNAL 交换,则为接收该交换的 Didit 客户。若交换未抵达任何已知交易对手,则各字段均为空。 travel_rule 套件中的五个预设作用于上述字段。您可以在 Business Console 中从 Transactions → Rules → Library 安装,也可以使用规则库 API 安装: 这五项预设仅适用于 Travel Rule 交易。

Webhook

将一个 Webhook 目标订阅到 travel_rule.status.updated 后,您的应用中每笔转账的每次状态变更都会通知到该目标,包括出站和入站转账,也包括 INTERNAL 通道的各段。 路由在交易创建接口返回之后才运行,因此 COUNTERPARTY_VASP_NOT_FOUND、COUNTERPARTY_VASP_NOT_REACHABLE 等结果,以及立即完成结算的 INTERNAL 交换,都通过此事件送达,而不会出现在创建响应中。
在选择通道之前,rail 为空。 对于同一笔交易,Didit 会先发送 transaction.created,然后才发送 travel_rule.status.updated。当 Didit 创建交易时(您调用 POST /v3/transactions/、sunrise 注册、收到入站 TRP 询问,或创建 INTERNAL 通道的入站段),它会先发送 transaction.created。 每个事件都独立投递和重试,因此一个需要重试的 transaction.created 可能晚于状态事件到达。请以 transaction_id 作为处理程序的关键字段;当状态事件指向您尚未见过的交易时,请读取该交易。 通过 TRUST 发送的转账不会收到 COMPLETED 事件:TRUST 不会返回 Didit 可读取的任何内容,因此除非发送失败或您取消,其最后一个事件为 EXPIRED。通过 GTR、VERIFYVASP 和 SYGNA 发送时,事件会跟随 Didit 从网络读取到的回复。 沙盒应用同样会发送此事件,并带有 "environment": "sandbox"。被 Didit Test VASP 应答的转账会带有 rail: "TEST_VASP"、test_vasp: true 和 test_vasp_scenario。 完整的事件目录、签名验证和重试策略,请参阅 Webhook 指南。

定价

Travel Rule 费用为每次启动的出站信息交换 $0.02,在交易创建时收取一次,之后该信息交换经历多少次状态变更都不再重复收取。resend 不会再次收费。
  • 适用于启用了 Travel Rule 的应用中的出站 travelRule 交易,且金额不低于您的 threshold_amount,因此 Didit 会为其发起托管信息交换。转账到自托管钱包,或转账到您用户已验证的自有钱包,同样计费,其所有权证明即构成该信息交换。
  • 其他带有 Travel Rule 数据的出站交易,按标准交易筛查计费。您的套餐包含一定的每月交易额度,超出部分按 $0.001 计费。这包括:低于阈值的转账、Travel Rule 不适用的闪电网络支付,以及在 Travel Rule 关闭时被动记录的转账。每笔交易只按其中一项计费,绝不会两项同时计费。
  • 入站 travelRule 交易不收取 Travel Rule 或监控费用。这包括 Didit 通过 INTERNAL 通道在收款人应用上创建的入站段、入站 TRP 询问,以及充值后注册。
  • 免费加入 Travel Rule 的应用,在通过 POST /v3/travel-rule/workspace/billing/ 开启出站计费之前,其出站 travelRule 交易两项费用均不收取;接收始终免费。
  • 沙盒应用从不收费。
  • Travel Rule 费用标价为 $0.02,超出额度的交易筛查标价为 $0.001。每笔交易按其所计入的项目价格收费。
  • 如果同一笔交易同时运行加密货币 AML/钱包筛查(例如启用了监控的加密货币入站充值,其 currency_kind: "crypto"),该筛查将按标准钱包验证与筛查费率单独计费,不包含在 Travel Rule 费用中。
  • 交易对手筛查为可选功能,单独计费,按每次筛查的企业 AML 筛查价格计算;距今不满 30 天的筛查结果可免费复用。决策、问卷以及目录的尽职调查评估均不收费。

归属分析定价

区块链分析归属需要向分析服务商查询该钱包一次,您始终可获得该次查询的完整结果:
  • 加密货币监控已对本笔交易的钱包进行过筛查:复用已存储的结果。一次分析调用,一笔钱包验证与筛查费用(即加密货币监控已产生的那一笔)。归属分析不再增加任何费用。
  • 加密货币监控未运行:Didit 只进行一次所需的分析调用,并完整返回其结果。该交易按标准钱包验证与筛查费率收费(使用 Didit 托管分析服务时为 $0.15),并获得完整的加密货币筛查输出,包括风险评分、钱包风险类别和网络快照,而不仅仅是 VASP 名称。用量明细项会标注 travel_rule_attribution 触发器,以便说明该笔费用的来源。
  • 自带分析密钥:这里适用与使用自带密钥的加密货币监控相同的平台费用(每次调用 $0.02)。底层查询费用由您的服务商直接向您收取。
  • 失败的查询从不收费。重新发送时会复用已记录的归属结果,不会再次调用或收费。沙盒应用从不收费。
因此,需要归属分析的出站转账费用为 $0.02(Travel Rule)加一笔钱包验证与筛查费用。两项产品同时启用时,分析调用及其费用只发生一次。

EU TFR 规则包

travel_rule_eu_tfr 规则包内置四条预设规则,专为欧盟 TFR 义务而设计。 与其他所有预设规则包一样,请在 Business Console 中前往 Transactions → Rules → Library 启用该规则包。 这些规则会在每个相关的状态转换时触发,包括转账创建时、所有权确认时、收到邮件领取响应时,以及到期扫描程序运行时。因此,一笔始终无法完成的转账仍会进入合规审核,而不会悄无声息地完成结算。

为什么在单一平台上效果更好

Travel Rule 合规本质上是身份问题,只是披上了支付的外衣,而 Didit 已经掌握了身份信息:
  • 手边即有已验证的数据。 每笔转账的主体都通过 vendor_data 与 Didit 在入驻时验证过的 KYC 档案相关联(证件 OCR、活体检测、人脸比对),因此您可以在同一平台上基于已验证字段构建 originator_data。 对于拥有已通过 KYC 验证的用户,Didit 传输的是已验证的身份信息,而不是您输入的值(参见已验证数据与来源)。
  • 针对高风险转账的加强型生物识别。 规则可以暂停任何高额转账,直到用户通过将用户当前的生物特征与入驻时采集的人脸进行比对的生物识别复核。这是在提款时应对账户接管的最有力手段。参见实际示例。
  • 统一的设备图谱。 通过 SDK 提交的转账与 KYC 会话携带相同的设备信息,因此”新设备 + 高金额 + 首次收款方”只需一条规则即可实现,无需数据仓库关联查询。
  • 筛查、规则、案件与交易所集中于一处。 用于识别交易对手 VASP 的钱包筛查,与您的规则和分析人员所用的筛查结果相同,即一次收费、一个控制台、一条审计轨迹。
  • 公开定价。 每次出站兑换 $0.02,无用量分级,无需联系销售。

FAQ

交换如何运作

Didit 自己执行交换。 当您提交 travelRule 转账时,Didit 会实时发现交易对手,通过承载这些数据的通道将汇款人和收款人数据发送给接收方 VASP,并且只有在交易对手一方确认后,才会将转账标记为 COMPLETED。这是托管式握手,而不是结算后的日志。 除 TRUST 外,所有通道都会处理交易对手的应答,TRUST 只负责发送,因此通过它的转账会过期,而不会完成。通过 GTR、VERIFYVASP 和 SYGNA 时,Didit 会从网络的响应中读取应答,或每 5 分钟轮询一次。目前,这些网络上的交换尚未在实际网络中完成过。通过 TRP 时,如果交易对手没有立即给出应答,则需要 Didit 的公共 TRP 主机,而该主机尚未上线(参见 Travel Rule 网络)。 Didit 还会保存每笔交换的完整记录和合规状态(包括 13 个状态的 生命周期、Webhook 以及审计追踪)。 如果您希望通过自己的流程运行 Travel Rule,Didit 也可以被动记录数据,将 Didit 作为您唯一的记录系统(参见下方关于被动记录的问题)。 两种模式均可使用:在 设置 中设置 is_enabled: true 后,主动交换即会运行(默认为 false)。在此之前,Didit 会被动记录数据。
它是原生的。Didit 运行自己的 Travel Rule 协议(TRP)实现,该实现将在公共主机上线后部署于 trp.didit.me(目前尚未响应,因此交易对手今天无法通过 TRP 与您连接)。Didit 还直接实现了行业网络协议,包括 GTR(全球 Travel Rule)、TRUST、VerifyVASP 和 Sygna Bridge(原生支持,包括 Sygna 的 ECIES 加密 IVMS 101 和签名的许可请求)。Didit 并非某个第三方互操作性层的转售商。要连接位于特定会员网络上的交易对手,必然需要通过该网络进行,因为 Travel Rule 中并不存在单一的通用通道。但发现、握手、验证和记录保存均由 Didit 执行。 目前,每个网络通道都需要您自己的会员资格,而 TRUST 只负责发送。请参见 概览。
原生实现的网络与协议,按严格的优先级依次尝试:INTERNAL(两个 VASP 都在 Didit 上)、TRP(OpenVASP Travel Rule Protocol)、GTR、TRUST、VerifyVASP、Sygna Bridge,以及面向没有相关工具的交易对手的 EMAIL 备用方式。 目前,网络通道需要您自己的会员资格,TRUST 只负责发送,并且尚未开放通过网络接收。请参见 Travel Rule 网络。 CODE、TRISA、Notabene 和 Veriscope 以申请访问卡片的形式出现在 Didit 的 Marketplace 中,尚未集成。 完整的路由表请参见 Didit 如何路由交换,每个网络目前可触达的范围请参见 Travel Rule 网络。
我们推荐以 TRP 作为基础:它不需要共享会员资格。共享您的 Travel Address 后,任何支持 TRP 的 VASP 都可以联系您。当交易对手只能通过地址识别时,只有在已归属的目录条目已经具备 TRP endpoint 时,区块链分析归属 才会将其路由到 TRP。 在出站方向,Didit 会通过 TRP 发送 TRP 资产标识符 中列出的资产。如果交易对手没有立即应答,则需要 Didit 的公共 TRP 主机,而该主机尚未上线。 对于会员网络,请根据交易对手的运营地区进行选择:GTR 的全球覆盖范围较广,TRUST 主要面向美国 VASP,VerifyVASP(现也运营 Sygna Bridge)在亚洲的覆盖范围较强。 是的,目前您需要自己的会员资格。Didit 尚未持有这些网络的平台会员资格,目前正在作为服务商接入。 在 Marketplace 中连接您的会员资格。您不会被限制在单一网络上。 请注意,TRUST 只负责发送,因此通过它的转账不会完成;并且目前尚无任何网络上的交换在实际网络中完成过。
通过一条解析链:先是另一位证明了对该钱包拥有控制权的 Didit 客户(INTERNAL 通道),然后是您自己的 地址簿(用于查找已存储的 Travel Address),再是协议和网络通道,最后是 区块链分析归属。 如果转账只携带目标钱包,Didit 会将其与区块链分析数据进行比对,以识别交易所或托管服务的归属,并将其记录在 VASP 目录 中。只有当该目录条目已经具备路由(例如 TRP 端点)时,转账才会自动路由;否则它会以 COUNTERPARTY_VASP_NOT_FOUND 结束,并记录交易对手的名称。当路由存在后,您可以重新提交,例如在您为该钱包的地址簿条目存储交易对手的 travel_address 之后(适用于 TRP 资产标识符 中列出的资产)。

定价与牌照

Travel Rule 是一款独立的按用量计费产品。 它不包含在身份验证中。 **每笔开始的出站交换收费 $0.02**([公开定价](#定价),无阶梯价格,无需联系销售)。 当路由需要进行区块链分析查询以识别交易对手 VASP 时,该查询按一次计费,费率为 [归属费率](#归属分析定价):托管模式起价 $0.15,若您已有现成的服务商密钥则为 $0.02。 如果加密货币监控已经筛查过同一钱包,则不会再次计费。 低于您阈值的转账,或在 Travel Rule 关闭时记录的转账,将改按交易筛查计费。入站转账(例如 Didit 在收款人一侧创建的入站转账)不收取 Travel Rule 费用。
不会。 travelRule 交易只计一笔费用:当它开始出站交换时收取 Travel Rule 费用($0.02),否则按标准交易筛查收费。区块链分析查询只计一次:如果加密货币监控已经对该交易的目标钱包进行过筛查,归属 会复用已存储的结果,不产生额外费用。 Didit 在收款人一侧创建的入站转账分支永远不会收取 Travel Rule 费用。
可以。Didit 的 KYT 与交易监控、AML 和制裁筛查、区块链分析钱包风险以及 Travel Rule 功能均已在 docs.didit.me 上公开记录,您可以在监管备案中引用这些页面。如果您需要针对特定申请量身定制的正式产品能力说明(例如 AIFC/AFSA、MiCA 或其他 VASP 牌照申请),请联系您的 Didit 客户团队,并说明监管机构要求的格式。

运营与数据

这些转账会立即返回 NOT_APPLICABLE:不会尝试任何通道,也不会有任何身份数据离开 Didit。 该交易按标准交易筛查计费,而不是按 Travel Rule 费用计费。 Didit 会将阈值与金额换算为您应用默认货币后的数值进行比较。 如果 Didit 无法换算金额,则不应用阈值,该转账将进行信息交换。 欧盟 TFR 没有最低限额,因此欧盟 CASP 应将 threshold_amount 保持为 0.00。
转账会停留在 AWAITING_COUNTERPARTY,直到 confirmation_timeout_hours 到期,随后清理程序会将其转为 EXPIRED,并将您的 timeout_outcome 应用于底层交易:HOLD 表示转人工审核,REJECT 表示拒绝,PROCEED 表示不做任何改动。预设规则 tr_eu_expired_review 还会将每次到期情况提示给您的分析人员。若交易对手完全不接收消息,情况则不同:Didit 会重试,在第六次失败后,转账会转为 COUNTERPARTY_VASP_NOT_REACHABLE(请参阅投递与重试)。
可以,这就是 EMAIL 通道。对方的合规联系人会收到一次性取件链接,可在托管页面上确认或拒绝此次信息交换,无需 Didit 账户、无需 API 密钥,也无需任何集成。对于在任何信息交换成为可能之前就已结算的存款,请使用存款后 sunrise 注册。
将目标声明为自托管钱包(payment_method.method_type: "unhosted_wallet")。Didit 会跳过 VASP 路由,转而通过钱包所有权组件收集您的客户控制该钱包的证明,证明方式包括消息签名、Satoshi 测试、截图或自我声明。这就是欧盟 TFR 自托管钱包义务的 API 实现形式。
是的。 在您一方确认钱包所有权之前,入站转账中交易对手的个人数据会被遮盖,转账对象和交易中的交易对手方同样如此(请参阅交易对手数据遮盖)。 邮件取件页面仅显示转账摘要(发起方 VASP 名称、金额、目标钱包),绝不显示个人 payload。 通道交换通过 HTTPS 进行,此外,网络通道(GTR、TRUST、VERIFYVASP、SYGNA)还会使用接收方 VASP 的公钥对 IVMS payload 进行加密。
可以。在禁用 Travel Rule 的情况下,您提交的任何 travel_rule_details(包括调用方提供的 status,无论是当前版本还是旧版)都会被动记录在交易中:不会调度任何通道,也不会进行任何协商。您可以借此补录数据,或在保留单一记录系统的同时运行自己的流程。
请使用已开启 Travel Rule 的沙盒应用。沙盒会跳过规则、计费,以及 transaction.created 和 transaction.status.updated Webhook。所有出站信息交换都会通过 TEST_VASP 通道发送至Didit 测试 VASP,它会在 Didit 内部按您选择的场景作出响应:接受、拒绝、姓名不符、无法连接、超时或自托管。您将收到标记为 environment: sandbox 的 travel_rule.status.updated Webhook,且不会有任何消息送达真实的交易对手。 对于入站转账,可让测试 VASP 通过触发测试 VASP 入站转账向您发送转账,或使用 POST /v3/travel-rule/inbound/ 登记一笔转账;两种方式均会根据您的钱包地址簿进行判定,结果为 ON_HOLD、UNCONFIRMED_OWNERSHIP、COUNTERPARTY_MISMATCHED_DATA,或先 COMPLETED 再 FINISHED。 若要与另一个真实应用进行双方信息交换,请在 INTERNAL 通道上使用您自己的两个生产环境应用:接收方应用必须可被发现,并通过签名消息或测试存款证明其对目标钱包的控制权。

后续步骤

钱包所有权组件

通过签名、Satoshi 测试、截图或自我声明,证明客户控制某个钱包。

互操作性

面向交易对手、供其他 VASP 联系您的端点:TRP、回调、邮件取件和 sunrise。

网络

每个通道和网络目前可连接的范围,以及哪些仍需等待成员资格。

在沙盒中测试

上线前,针对 Didit 测试 VASP 运行每种结果。

提交交易

如何在 Create Transaction payload 中包含 Travel Rule 数据。

规则库

完整的预设规则目录,包括 Travel Rule 规则包。

Webhook

订阅 travel_rule.status.updated 及所有其他事件类别。

控制台指南

在交易详情视图中查看 Travel Rule 状态。
最后修改于 2026年11月7日