> ## 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.

# Travel Rule 沙盒测试指南

> 在 Didit 沙盒中，通过 Test VASP 端到端测试 Travel Rule 的各种结果：接受、拒绝、姓名不符、无法访问、超时以及自托管钱包。

沙盒应用只与一个交易对手交换 Travel Rule 数据：**Didit Test VASP**，这是平台内置的测试 VASP。它会按照你的要求回应每笔转账，并通过与处理真实交易对手相同的代码来处理这些转账，因此你可以在上线前观察一次交换的每个状态、时间线条目和 Webhook。

沙盒中你发送的任何内容都不会离开 Didit。不会联系任何网络、电子邮件收件人或其他 Didit 客户，也不会产生任何费用。

## 开始之前

1. 使用 **沙盒**应用的 API 密钥。生产环境的应用永远不会连接到测试 VASP。
2. 使用法定名称开启 Travel Rule：

```bash theme={null}
curl -X PUT https://verification.didit.me/v3/travel-rule/settings/ \
  -H "x-api-key: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"is_enabled": true, "legal_name": "Example CASP Sandbox"}'
```

3. 可选地为 Webhook 目标订阅 `travel_rule.status.updated`。沙盒会投递该事件，并标记 `"environment": "sandbox"`。

## Didit Test VASP

`GET /v1/sandbox/scenarios/` 会返回测试 VASP 的资料以及其 `travel_rule` 对象中的所有场景，因此你的测试可以读取触发值，而无需硬编码。

| 字段 | 值 |
| - | - |
| `legal_name` | `Didit Test VASP` |
| `lei` | `DIDITESTVASP00000001`，格式正确但未注册 |
| `jurisdiction` | `GB` |
| `compliance_email` | `didit.test` 下的一个地址，从不发送邮件 |
| `travel_address` | `.test` 主机下的一个 Travel Address，永远无法访问 |
| `network_codes` | 永远不会被调用的测试代码 |
| `default_scenario` | `accept` |
| `inbound_scenarios` | `["accept", "name_mismatch"]` |

所有值均为测试数据。测试 VASP 不是任何 Travel Rule 网络的成员，沙盒中的任何结果都不表明真实的交易对手或网络可以被访问。

## 出站场景

沙盒应用中每一笔需要交换的出站 `travelRule` 交易都会发送到测试 VASP。通过收款人地址（不区分大小写）或格式为 `Didit Test VASP <suffix>` 的收款人名称来选择结果；两者都设置时，以钱包为准。两者都未设置，或后缀不在下表中，转账将完成（`accept`）。

无需交换的转账永远不会到达测试 VASP：低于你的 `threshold_amount` 的转账、发往你用户自己已验证钱包的转账，以及你声明为自托管的交易对手钱包的转账。你或你的终端用户从目录中手动选择的交易对手 VASP，会按正式应用所采用的路由进行判断：若其条目具有路由（已验证的 `TRP` endpoint、你的应用所使用的网络，或合规联系人），转账将发送到测试 VASP；若没有路由，转账将以 `COUNTERPARTY_VASP_NOT_FOUND` 结束，与正式应用的行为一致。

| 场景 | 名称后缀 | 钱包（ETH） | 结束于 |
| - | - | - | - |
| `accept` | 无 | `0xc00c4cd93ff83953ce3347b33656d68ab8f35cfb` | `COMPLETED`，在你报告 `payment_txn_id` 后变为 `FINISHED` |
| `decline` | `Decline` | `0x7694c5b0213859ef409107853a36ff7c85835f18` | `COUNTERPARTY_VASP_GENERAL_DECLINE` |
| `name_mismatch` | `Name Mismatch` | `0x501b7a0886e31f516aaf54fa99107d2377bd2d3e` | `COUNTERPARTY_MISMATCHED_DATA`，由你的名称规则判定（若为 `NONE` 则完成） |
| `not_reachable` | `Not Reachable` | `0xf0e986c1a1c3ae41629bf5cdcee0a67dd1eb0cce` | 按真实重试计划（30 秒，然后是 2、10、30 和 60 分钟，共约 1 小时 45 分钟）之后变为 `COUNTERPARTY_VASP_NOT_REACHABLE`，之后可重新发送 |
| `timeout` | `Timeout` | `0xb63a1b1d4bee82d109332187cbf5b657eb7da498` | 在其一分钟截止时间之后的第一次逾期检查时变为 `EXPIRED`，即约 15 分钟内；随后你的 `timeout_outcome` 生效 |
| `self_hosted` | `Self Hosted` | `0x33dcc2a7e69cf965f7f4eaf6ba657bcb078a2b65` | `UNCONFIRMED_OWNERSHIP`，记录钱包的所有权证明后变为 `COMPLETED` |

```bash theme={null}
curl -X POST https://verification.didit.me/v3/transactions/ \
  -H "x-api-key: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "sbx-tr-accept-001",
    "transaction_category": "travelRule",
    "transaction_details": {
      "direction": "outbound",
      "action_type": "transfer",
      "amount": "0.25",
      "currency": "ETH",
      "currency_kind": "crypto"
    },
    "subject": { "entity_type": "individual", "vendor_data": "user-042", "full_name": "Jane Doe" },
    "travel_rule_details": {
      "status": "AWAITING_COUNTERPARTY",
      "beneficiary_data": {
        "wallet_address": "0xc00c4cd93ff83953ce3347b33656d68ab8f35cfb",
        "name": "Carlos Ruiz"
      }
    }
  }'
```

转账的 `rail` 为 `TEST_VASP`，转账列表中将 `Didit Test VASP` 列为收款方 VASP。你可以通过 `travel_rule.status.updated` Webhook 跟踪它，或读取 `GET /v3/transactions/{transaction_id}/`。

* **`name_mismatch`** 会将你发送的收款人名称与测试 VASP 返回的持有人名称进行比较，并按收款人实体类型的名称规则判定（`matching_rules.individual.name` 或 `matching_rules.company.name`，在你设置之前，它们遵循 `name_matching_strictness`）。转账以及作出判定的时间线条目会带有 `name_match`（其中 `compared_with: "counterparty_vasp"`）以及 `data_match`，其中 `mismatched_fields: ["name"]`。
* **`not_reachable`** 在重试期间让转账保持 `AWAITING_COUNTERPARTY`，其 `delivery.status` 为 `RETRYING`，`last_error` 为 `test VASP is not answering`，随后将其变为 `COUNTERPARTY_VASP_NOT_REACHABLE`。之后发送 `{"action": "resend"}` 可再次运行该转账。
* **`self_hosted`** 会让测试 VASP 回应该钱包为自托管。使用[钱包所有权组件](https://docs.didit.me/zh/transaction-monitoring/wallet-ownership-widget.md)（当 `auto_wallet_verification` 开启时为你生成）或 [`POST .../travel-rule/ownership/`](https://docs.didit.me/zh/management-api/travel-rule/confirm-ownership) 并附带 `{"confirmed": true}` 记录证明：该钱包会以收款人名称添加到你的地址簿中，名称比对结果决定转账。匹配则完成转账并将钱包标记为已验证；`{"confirmed": false}` 则拒绝该转账。

## 测试 VASP 的入站转账

要测试接收端，请让测试 VASP 通过 `POST /v3/travel-rule/test-vasp/inbound/` 向您发送一笔转账。指定您应用自有[地址簿](https://docs.didit.me/zh/transaction-monitoring/travel-rule.md#地址簿)中的一个钱包：该笔转账由与真实转账相同的入站流程决定，并依据您的地址簿、所有权模式和姓名规则进行判定。

```bash theme={null}
curl -X POST https://verification.didit.me/v3/travel-rule/test-vasp/inbound/ \
  -H "x-api-key: YOUR_SANDBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "beneficiary_wallet_address": "0xYourDepositWallet",
    "scenario": "accept",
    "reference": "sbx-inbound-001"
  }'
```

| 字段 | 说明 |
| - | - |
| `beneficiary_wallet_address` | 必填，最多 128 个字符。请使用您自己地址簿中的钱包之一：任何其他钱包都会被记为 `ON_HOLD`。 |
| `scenario` | `accept`（默认）：测试 VASP 指定该钱包的持有人本人。`name_mismatch`：测试 VASP 指定的是持有人均不认可的人。 |
| `chain`, `amount`, `currency` | 可选。默认值分别为 `ETH`、`1` 和 `ETH`。 |
| `reference` | 可选，最多 128 个字符。再次发送相同的 `reference` 会返回第一次的响应（`201`），且不会记录任何新内容。 |

成功时（`201`）的响应包含 `transaction_id`、`txn_id`、`scenario`、`travel_rule_status`、`detail`、`test_vasp: true` 以及 `travel_rule` 转账对象。生产应用会收到 `400`（`"The Didit Test VASP is only available on sandbox applications."`）；其他 `scenario` 值会收到 `400`；关闭 Travel Rule 的应用会收到 `409`。

| 您的钱包条目 | `accept` | `name_mismatch` |
| - | - | - |
| 该链上没有 | `ON_HOLD` | `ON_HOLD` |
| 您的[所有权模式](https://docs.didit.me/zh/transaction-monitoring/travel-rule.md#所有权验证模式)下未证明所有权 | `UNCONFIRMED_OWNERSHIP` | `UNCONFIRMED_OWNERSHIP` |
| 已验证 | 若 `inbound_auto_accept` 已开启则为 `COMPLETED`，否则为 `ON_HOLD` | `COUNTERPARTY_MISMATCHED_DATA`（姓名规则为 `NONE` 时，与 `accept` 相同） |

对于等待中的转账，请使用 [`POST .../travel-rule/ownership/`](https://docs.didit.me/zh/management-api/travel-rule/confirm-ownership) 进行决定，方式与真实转账相同：`{"confirmed": true}` 会完成转账，`{"confirmed": false}` 会拒绝转账。

您通过 `POST /v3/transactions/` 自行报告的存款并非测试 VASP 发出的：它会保持 `AWAITING_COUNTERPARTY` 状态，等待其发起方 VASP，其时间线会指向上述端点。它在 `confirmation_timeout_hours` 到期后才会触发 Webhook，到期前不会触发任何 Webhook。[`POST /v3/travel-rule/inbound/`](https://docs.didit.me/zh/management-api/travel-rule/register-inbound) 仍会像在生产应用上一样，将存款后登记与您的地址簿进行匹配并完成结算。

## 沙盒中的 Webhook

`travel_rule.status.updated` 会在沙盒应用的每次状态变化时触发，并带有 `"environment": "sandbox"`。测试 VASP 已作答的转账还会带有 `rail: "TEST_VASP"`、`test_vasp: true` 和 `test_vasp_scenario`。沙盒的其余部分仍按[沙盒中的交易监控](https://docs.didit.me/zh/integration/sandbox-testing.md#沙盒中的交易监控)所述运行：不评估规则，不发送 `transaction.created` 和 `transaction.status.updated`，也不产生任何费用。

## 沙盒无法证明的内容

* 真实交易对手、网络成员资格或 Didit 公共 TRP 主机是否可用。这些都不会被联系。
* 您的网络凭证是否有效。已连接的成员资格需通过首次实际交换来证明。
* 真实 VASP 的[目录](https://docs.didit.me/zh/transaction-monitoring/travel-rule.md#目录)路由：在沙盒应用上，每条路由都会显示 `unavailable`，并带有 `reason: sandbox_application`，每一行都为 `reachable: false`。

各通道在生产环境中当前可以连接的范围，请参阅 [Travel Rule 网络](https://docs.didit.me/zh/transaction-monitoring/travel-rule-networks.md)。


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