重复 txn_id 错误
症状。 提交交易时会返回 400,并在 transaction_id 字段中显示 A transaction with this transaction_id already exists.;当两个完全相同的请求同时竞争时,则返回 409。
原因。 txn_id(即您发送的 transaction_id)在每个应用中必须唯一。Didit 会拒绝使用相同 transaction_id 的第二笔交易,且不会返回已有记录。
解决方法。
- 在您的系统中以确定的方式生成
txn_id(例如使用您自己的交易数据库 ID)。 - 在重试时若因重复的
transaction_id收到400或409,请先查询已有交易,而不是重新提交:使用首次响应中的uuid,通过GET /v3/transactions/{uuid}/读取该交易;或者使用transaction.createdWebhook 中与您的txn_id一同返回的transaction_id(即 Didit uuid)。 - 如果不是重试请求,请为新交易分配独立的
transaction_id。
规则未触发
症状。 您创建了一条应当匹配的规则,但没有交易在rule_runs[] 中显示 matched: true。
原因与解决方法。
- 应用处于沙盒模式:沙盒应用会跳过规则评估、AML 筛查、计费,以及
transaction.created和transaction.status.updatedWebhook。启用后,Travel Rule 交换仍会针对 Didit Test VASP 运行,并投递标记为environment: sandbox的travel_rule.status.updatedWebhook。无论您的规则处于何种模式,rule_runs都会返回空值,分数保持为0,交易状态保持APPROVED,除非某个即将过期的 Travel Rule 转账应用了您的timeout_outcome。请检查交易响应中的environment:值为"sandbox"表示该交易从未被评估。关于上线前如何验证规则,请参阅沙盒中的交易监控。 - 规则模式为
DISABLED或TEST:请在 Rules → [rule] → Mode 中检查。只有ACTIVE规则会参与评分;TEST规则会进行评估,但不影响状态。 - 范围过滤器排除了该交易:例如,范围设置为
transaction_type = finance时,将无法匹配travelRule交易。 - 聚合时间窗口短于所需时长:例如,只有 15 笔交易时,“30 天内 20 笔交易”规则不会匹配。
- 条件字段为 null(空值):例如,规则检查
counterparty.country_code,但您未发送交易对手信息。 - 货币换算:规则按
amount_in_default_currency设定阈值;如果应用的默认货币与交易货币不同,换算后的金额可能低于阈值。
规则对所有交易都触发
症状。 某条规则在 90% 以上的交易上触发,您的审核队列不堪重负。 原因。 条件过于宽泛,或阈值过低。 解决方法。- 添加
scope过滤器,缩小适用范围(例如仅限出站交易、仅限特定交易类型)。 - 提高阈值(金额、频次计数)。
- 将规则设为
TEST模式运行一周,分析rule_runs以查看匹配率,并在重新启用前收紧条件。
加密货币筛查超时
症状。 交易已完成且status: APPROVED,但 provider_results[] 数组中某个钱包、交易哈希或加密货币筛查提供方显示 status: FAILED。
原因。
- 提供方 API 短暂不可用。
- 查询超时(通常约为 10 秒)。
- 交易不会因提供方问题而失败:富化属于尽力而为。
- 如果某个提供方反复失败,请查看其状态页面或提交支持工单。
- 可考虑在 Settings → Transaction Monitoring → Providers 中配置提供方偏好,将请求路由到其他提供方。
IP 富化缺失
症状。 交易的applicant.ip_enrichment 为空或不完整。
原因。
- 提交内容中没有
applicant.device.ip。 - IP 为私有或保留地址,不可路由。
- 所有富化提供方暂时不可用。
- 在客户端或服务端获取提交者的 IP,并在每笔交易中传递。
- 仅使用可路由的 IP:Didit 会静默跳过私有地址段。
- 在控制台中检查 Settings → Status,查看提供方健康状态。
Webhook 签名不匹配
症状。 您的 endpoint 因签名不匹配而拒绝事件。 原因。- 原始请求体被修改(JSON 以不同的空白字符重新序列化)。
- 密钥错误。
- 多个目标使用相同 URL:不同目标的签名各不相同。
- 基于原始请求体签名,而不是解析后的 JSON。许多框架都提供原始请求体中间件。
- 若密钥泄露,请轮换密钥:Webhook destinations → [destination] → Rotate secret。
- 每个 URL 只保留一个目标,以避免密钥混淆。
Webhook 未送达
症状。 交易正在创建,但 Webhook 从未送达。 原因。- 目标的
enabled为false。 - URL 无法从公网访问。
- 目标因连续失败而被自动禁用。
- 事件不在
subscribed_events中。
- 发送测试事件:Webhook destinations → [destination] → Send test。
- 查看最近的投递记录:Webhooks → [destination] → Deliveries。可以看到 4xx/5xx 响应及其响应体和响应头。
- 重新启用已被禁用的目标。
货币换算结果似乎有误
症状。amount_in_default_currency 与您预期的汇率不符。
原因。
- 汇率为
txn_date当日的市场中间价。 - 补录的交易使用该日期的历史汇率。
- 部分非主流外汇币种的更新频率较低。
- 展示时使用
amount和currency(原始币种)。 - 仅将
amount_in_default_currency用于内部规则阈值判断。 - 如需审计,交易记录会固定保存评估时所用的换算汇率。
交易对手与我的黑名单不匹配
症状。 您按vendor_data 将某企业加入了黑名单,但与该交易对手相关的一笔交易仍然通过了。
原因。
- 交易请求体中的交易对手没有
vendor_data,仅以外部快照形式存储。 vendor_data的大小写不一致。
- 当交易对手是您平台上的实体时,始终传入
counterparty.vendor_data。 - 所有地方使用相同的大小写,因为
vendor_data区分大小写。
AWAITING_USER 交易卡住
症状。 由于用户从未完成整改会话,交易停留在AWAITING_USER 状态。
原因。
- 用户未打开整改会话 URL。
- 整改会话已过期。
- 该交易是 Travel Rule 转账,并由
travel-rule-pending-action等库规则将其转入AWAITING_USER:Didit 不会为 Travel Rule 交易创建默认的整改会话,因此除非规则指定了自己的整改工作流,否则没有可投递的链接。
- 交易响应中的
remediation_session_url就是需要投递的链接,请将其重新发送给用户。 - 对于 Travel Rule 交易,请在 Travel rule 标签页中处理该转账,然后自行更改交易状态,因为处理转账本身不会使交易退出
AWAITING_USER状态。 - 整改会话遵循与 KYC 快速入门 相同的模式,请订阅完成事件的 Webhook。
- 如果整改始终未完成,请在您自己的系统中设置超时,将长期未完成的交易置为过期状态。
创建时的速率限制
症状。 高并发突发流量期间返回429 Too Many Requests。
解决方法。
- 遵守
Retry-After响应头。 - 针对突发流量在客户端进行限流。
- 如需在已验证的生产流量下提高限额,请联系支持团队。
后续步骤
集成指南
完整的集成模式。
规则
规则评估的工作原理。
Webhook
Webhook 机制。