> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# 交易监控集成：KYT API

> Didit KYT 架构与最佳实践：实时与批量、交易双方、幂等性、历史数据导入、Webhook。每月包含 1,000 次，之后每次 $0.001。

本指南涵盖交易监控的完整集成范围。[快速入门](https://docs.didit.me/zh/transaction-monitoring/quickstart.md)可帮助您先跑通流程，本页则帮助您完成生产环境上线。

## 架构

```mermaid theme={null}
sequenceDiagram
    participant You as Your platform
    participant Didit as Didit API
    participant Rules as Rule engine
    participant AML as AML providers
    participant Webhook as Your webhook

    You->>Didit: POST /v3/transactions/ (txn_id, parties, amount)
    Didit->>Didit: IP enrichment (inline)
    Didit->>AML: Screen wallet or transaction hash + address
    AML-->>Didit: Hits / clean
    Didit->>Rules: Evaluate all active rules
    Rules-->>Didit: Score + matched rules + actions
    Didit-->>You: Transaction record with status
    Didit->>Webhook: transaction.created
    Didit->>Webhook: transaction.status.updated (if async rules)
```

## 身份验证

使用标准的 `x-api-key` 请求头。会话与实体使用相同的密钥。请参阅 [API 身份验证](https://docs.didit.me/zh/getting-started/api-authentication.md)。

## 提交交易

仅有一个 endpoint：`POST /v3/transactions/`。完整的数据结构请参阅[提交交易](https://docs.didit.me/zh/transaction-monitoring/transactions.md)。

**最简 payload：**

```json theme={null}
{
  "transaction_id": "tx-0001",
  "transaction_category": "finance",
  "transaction_details": {
    "direction": "outbound",
    "amount": "500.00",
    "currency": "EUR"
  },
  "subject": { "entity_type": "person", "vendor_data": "user-42", "full_name": "John Doe" },
  "counterparty": { "entity_type": "company", "full_name": "Acme Corp" }
}
```

**包含支付方式、设备上下文和自定义属性的更丰富 payload：**

```json theme={null}
{
  "transaction_id": "tx-0002",
  "transaction_at": "2026-04-16T10:00:00Z",
  "transaction_category": "finance",
  "transaction_details": {
    "direction": "outbound",
    "amount": "12500.00",
    "currency": "USD",
    "action_type": "withdrawal"
  },
  "subject": {
    "entity_type": "person",
    "vendor_data": "user-42",
    "full_name": "John Doe",
    "country_code": "US",
    "device_context": {
      "fingerprint": "fp-9f2c...",
      "user_agent": "Mozilla/5.0 ...",
      "browser_family": "Chrome",
      "platform": "web",
      "network_context": { "ip_address": "203.0.113.5" }
    },
    "payment_method": {
      "method_type": "bank_account",
      "account_id": "US12345678901234567890",
      "issuing_country": "US"
    }
  },
  "counterparty": {
    "entity_type": "company",
    "vendor_data": "biz-acme",
    "full_name": "Acme Corp",
    "country_code": "US",
    "payment_method": {
      "method_type": "bank_account",
      "account_id": "US09876543210987654321",
      "issuing_country": "US"
    }
  },
  "custom_properties": {
    "invoice_id": "INV-2026-00042",
    "category": "b2b_goods"
  }
}
```

每个顶层字段都接受 camelCase 别名（`txnId`、`txnDate`、`type`、`info`、`applicant`、`props`、`travelRule`、`includeCryptoScreening`），SDK 传输格式与 snake\_case 格式最终写入的位置相同。

## 参与方建模

每笔交易都必须包含 `subject`（您的客户，即您监控的参与方），并可选择包含 `counterparty`（交易的另一方）。两者各自带有 `payment_method`，以及可选的 `device` 上下文。

在响应中，它们以 `parties` 数组返回，角色分别为 `APPLICANT` 和 `COUNTERPARTY`。未包含 `vendor_data` 的参与方会以外部快照（`kind: EXTERNAL`）的形式存储，且不关联任何实体。

参与方字段请参阅[交易 payload](https://docs.didit.me/zh/transaction-monitoring/transactions.md)。

## 幂等性

`txn_id`（即您发送的 `transaction_id`）在每个应用内唯一。
重复提交已存在的 `transaction_id` 会返回 `400`，并在 `transaction_id` 字段上附带 `A transaction with this transaction_id already exists.`。若两个相同请求并发到达，第二个请求会收到 `409`。
两种响应都不会返回已存在的交易。
遇到 `transaction_id` 重复导致的 `400` 或 `409` 时，请先查询已存在的交易，而不是重新提交：使用第一次响应中的 `uuid`，通过 [`GET /v3/transactions/{uuid}/`](https://docs.didit.me/zh/management-api/transactions/get) 读取该交易；或者使用 `transaction.created` Webhook 在您的 `txn_id` 旁附带的 `transaction_id`（即 Didit uuid）。

**提交前务必在您的系统中生成 `txn_id`**，不要依赖 Didit 生成的 ID 来实现幂等性。可以使用您自己的数据库 ID、UUID，或交易字段的哈希值。

## 实时与批量

* **实时**：推荐大多数场景使用。交易在您的系统中发生的那一刻即提交，规则同步执行并返回决策结果。
* **批量 / 回填**：用于历史数据导入，请传入过去的 `txn_date`。规则仍会执行，并可能触发 Webhook。若要避免回填时触发规则，请在控制台的 CSV 导入中勾选 "dry ingest" 标记。

## 历史数据导入

若您要从其他交易监控系统迁移：

1. 将历史交易导出为 CSV 文件。
2. 在控制台中使用 *Transactions → Import history*（或通过 API 循环提交），并传入过去的 `txn_date`。
3. 导入完成后再启用规则，或使用 "dry ingest" 跳过规则评估。

> [!WARNING]
>
> 对历史规则评估要审慎。若将 6 个月的历史数据输入 "30 天内 20 笔转账" 规则，将一次性产生数千条警报。

## Webhook

请订阅以下事件：

* `transaction.created`：每笔提交的交易。
* `transaction.status.updated`：状态变更（例如分析师将状态从 `IN_REVIEW` 改为 `APPROVED`，或异步 AML 检查更新了分数）。

完整详情请参阅 [TM Webhook](https://docs.didit.me/zh/transaction-monitoring/webhooks.md)。

```typescript theme={null}
app.post('/webhooks/didit-tm', (req, res) => {
  if (!verifySignature(req)) return res.status(401).end();

  const { webhook_type, status, txn_id } = req.body;
  if (webhook_type === 'transaction.status.updated' && status === 'DECLINED') {
    suspendTransaction(txn_id);
  }
  res.status(200).end();
});
```

## 处理状态

| 状态 | 处理方式 |
| - | - |
| `APPROVED` | 正常处理该交易。 |
| `IN_REVIEW` | 暂缓处理该交易，直至分析师审核或自动复检得出结果。 |
| `DECLINED` | 拒绝该交易，并向用户显示通用错误信息。 |
| `AWAITING_USER` | 用户必须先完成操作，交易才能结算。请读取 `action_required` 对象，并将其中的 `url` 发送给用户（SDK 可[自动处理此流程](https://docs.didit.me/zh/transaction-monitoring/sdk-transaction-submission.md#用户所需操作)）。 |

请参阅 [TM 状态](https://docs.didit.me/zh/transaction-monitoring/statuses.md)。

## 将交易关联到实体

为每个参与方都传入 `vendor_data`。其好处如下：

* 每笔交易都会汇总到用户或企业档案中。
* 频次规则和行为规则拥有完整的历史数据可供评估。
* 封禁实体的状态会自动应用于其后续交易。

缺少 `vendor_data` 不会报硬性错误，交易将以外部快照形式存储，但您将失去实体级汇总功能。

## 补救会话

当规则操作将交易转为 `AWAITING_USER` 状态时，Didit 会自动创建一个**补救会话**，即针对同一 `vendor_data` 的标准托管验证会话。
自定义规则始终在操作本身中指定工作流。对于内置规则库中的规则，工作流会依次回退到 [交易设置中的补救工作流](https://docs.didit.me/zh/transaction-monitoring/settings.md#补救工作流)、您应用的生物识别认证工作流（前提是主体已存储参考人脸），然后是您应用的默认工作流。
Travel Rule 交易不适用此自动回退，其待处理操作为钱包所有权证明。
交易（响应、之后的每次读取以及每个 Webhook）会在规范的 `action_required` 块中包含该信息：

```json theme={null}
{
  "status": "AWAITING_USER",
  "action_required": {
    "type": "verification_session",
    "url": "https://verify.didit.me/session/...",
    "session_id": "11111111-2222-3333-4444-555555555555",
    "session_token": "SESSION_TOKEN",
    "status": "Not Started"
  },
  "remediation": {
    "session_id": "11111111-2222-3333-4444-555555555555",
    "session_token": "SESSION_TOKEN",
    "url": "https://verify.didit.me/session/...",
    "status": "Not Started"
  }
}
```

`remediation` 为向后兼容而保留；`action_required` 是规范块（它也包含 [Travel Rule](https://docs.didit.me/zh/transaction-monitoring/travel-rule.md) 转账的 `wallet_ownership` 操作）。
仅有 `wallet_ownership` 操作本身不会改变交易状态：交易会保持规则赋予的任何状态，通常为 `APPROVED`。因此，应检查每个响应中的 `action_required`，而不仅是 `AWAITING_USER` 状态下的响应。

用户完成验证。对于**生物识别认证**工作流，即将经过活体检测的自拍照与其原始 KYC 入驻时采集的人脸进行比对，这是 [高价值交易](https://docs.didit.me/zh/transaction-monitoring/sdk-transaction-submission.md#示例：为高额提现进行生物识别升级验证) 最强的升级验证方式。
会话得出决策后，交易会自动跟随该决策：`APPROVED`（`decision_reason_code: user_action_approved`）、`DECLINED`（`user_action_declined`）或 `IN_REVIEW`（`user_action_in_review`），并触发 `transaction.status.updated` Webhook。

> [!NOTE]
>
> 除 KYB 外，可以选择任何工作流类型。
> 生物识别认证工作流（以及人脸比对先于身份证件验证运行的工作流）要求主体已拥有一张在某次验证通过后存储的参考人脸。没有参考人脸的用户会改为进入您应用的默认工作流，并且交易上会记录一条说明，注明已作替换。

## 最佳实践

| 实践 | 原因 |
| - | - |
| 始终传递 `vendor_data` | 支持汇总。 |
| 使用您自己的 `txn_id` | 幂等性。 |
| 同时订阅 `transaction.created` 和 `transaction.status.updated` | 捕获异步状态变化（例如分析师审核结果）。 |
| 合理设置规则阈值 | 阈值越低，告警越多；阈值越高，遗漏的风险越多。参见 [风险评分](https://docs.didit.me/zh/transaction-monitoring/risk-scoring.md)。 |
| 在控制台中监控规则运行次数 | 发现从不触发的规则（配置错误）或触发所有交易的规则（过于宽松）。 |
| 上线前在 TEST 模式下测试规则 | 参见 [规则](https://docs.didit.me/zh/transaction-monitoring/rules.md)。 |

## 速率限制

参见 [速率限制](https://docs.didit.me/zh/integration/rate-limiting.md)。交易创建是吞吐量最高的 endpoint 之一，典型限制为每秒数百次请求。请谨慎处理突发流量。

## 后续步骤

> [card] [交易](https://docs.didit.me/zh/transaction-monitoring/transactions.md)
>
> 完整 payload 参考。

> [card] [规则](https://docs.didit.me/zh/transaction-monitoring/rules.md)
>
> 规则的评估方式。

> [card] [Webhook](https://docs.didit.me/zh/transaction-monitoring/webhooks.md)
>
> 事件目录。

> [card] [故障排查](https://docs.didit.me/zh/transaction-monitoring/troubleshooting.md)
>
> 常见集成问题。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.