> ## 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: руководство по тестированию

> Проверьте все исходы Travel Rule в песочнице Didit: принятие, отказ, несовпадение имени, недоступность, таймаут и некастодиальные кошельки.

Приложение в песочнице обменивается данными 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` | Travel Address на хосте `.test`, он недоступен |
| `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`, сеть, через которую отправляет ваше приложение, или контакт комплаенса), перевод направляется в тестовый VASP; если маршрута нет, перевод завершается со статусом `COUNTERPARTY_VASP_NOT_FOUND`, как и в продакшн-приложении.

| Сценарий | Суффикс имени | Кошелёк (ETH) | Завершается |
| - | - | - | - |
| `accept` | нет | `0xc00c4cd93ff83953ce3347b33656d68ab8f35cfb` | `COMPLETED`, затем `FINISHED` после того, как вы передадите `payment_txn_id` |
| `decline` | `Decline` | `0x7694c5b0213859ef409107853a36ff7c85835f18` | `COUNTERPARTY_VASP_GENERAL_DECLINE` |
| `name_mismatch` | `Name Mismatch` | `0x501b7a0886e31f516aaf54fa99107d2377bd2d3e` | `COUNTERPARTY_MISMATCHED_DATA` по вашему правилу проверки имён (при `NONE` перевод завершается) |
| `not_reachable` | `Not Reachable` | `0xf0e986c1a1c3ae41629bf5cdcee0a67dd1eb0cce` | `COUNTERPARTY_VASP_NOT_REACHABLE` после реального графика повторных попыток (через 30 секунд, затем через 2, 10, 30 и 60 минут, всего около часа и 45 минут), после чего его можно отправить повторно |
| `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`, а в списке переводов получателем VASP указан `Didit Test VASP`. Отслеживайте перевод в webhook `travel_rule.status.updated` или получите его через `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/ru/transaction-monitoring/wallet-ownership-widget.md) (создаётся для вас, пока включён `auto_wallet_verification`) или [`POST .../travel-rule/ownership/`](https://docs.didit.me/ru/management-api/travel-rule/confirm-ownership) с `{"confirmed": true}`: кошелёк добавляется в вашу адресную книгу под именем получателя, и решение о переводе принимается по совпадению имён. Совпадение завершает перевод и помечает кошелёк как верифицированный; `{"confirmed": false}` отклоняет его.

## Входящие переводы от тестового VASP

Чтобы проверить принимающую сторону, попросите тестовый VASP отправить вам перевод через `POST /v3/travel-rule/test-vasp/inbound/`. Укажите один из кошельков вашего приложения из собственной [адресной книги](https://docs.didit.me/ru/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`: он называет человека, с которым не совпадает ни один владелец. |
| `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/ru/transaction-monitoring/travel-rule.md#режимы-проверки-владения) | `UNCONFIRMED_OWNERSHIP` | `UNCONFIRMED_OWNERSHIP` |
| Подтверждена | `COMPLETED`, если включён `inbound_auto_accept`, иначе `ON_HOLD` | `COUNTERPARTY_MISMATCHED_DATA` (при правиле имени `NONE`, как для `accept`) |

Примите решение по ожидающему переводу через [`POST .../travel-rule/ownership/`](https://docs.didit.me/ru/management-api/travel-rule/confirm-ownership), как и для реального: `{"confirmed": true}` завершает его, а `{"confirmed": false}` отклоняет.

Депозит, который вы сами регистрируете через `POST /v3/transactions/`, тестовый VASP не отправлял. Он остаётся в статусе `AWAITING_COUNTERPARTY` и ждёт своего VASP-отправителя, а в его хронологии указан endpoint выше. Webhook по нему не отправляется, пока не истечёт срок `confirmation_timeout_hours`. [`POST /v3/travel-rule/inbound/`](https://docs.didit.me/ru/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/ru/integration/sandbox-testing.md#мониторинг-транзакций-в-песочнице): правила не проверяются, `transaction.created` и `transaction.status.updated` не отправляются, и списания не производятся.

## Что песочница не подтверждает

* Что реальный контрагент, членство в сети или публичный TRP-хост Didit работают. Ни один из них не вызывается.
* Что ваши учётные данные сети действительны. Подключённое членство подтверждается его первым боевым обменом.
* [Маршруты каталога](https://docs.didit.me/ru/transaction-monitoring/travel-rule.md#каталог) реальных VASP: в приложении песочницы каждый маршрут показывает `unavailable` с `reason: sandbox_application`, а у каждой строки `reachable: false`.

Подробнее о том, что каждый канал охватывает в продакшне сегодня, см. в разделе [Сети Travel Rule](https://docs.didit.me/ru/transaction-monitoring/travel-rule-networks.md).


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