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

# Песочница Didit: тестовые данные, сценарии и документы

> Тестируйте Didit в песочнице: сценарии, магические значения, arm-эндпоинт, тестовые документы и OTP-коды. Без PII и оплаты.

Песочница Didit аналогична тестовым картам Stripe или шаблонам документов Sumsub: она позволяет воспроизвести любой результат верификации детерминированно, без обращения к реальным провайдерам, реальным персональным данным и без списания с вашего баланса.

> [!NOTE]
>
> Источником истины для этих данных является `serialize_catalog()` в сервисе верификации, который отдаётся в реальном времени по адресу `GET /v1/sandbox/scenarios/`. Копия, проверенная на отсутствие расхождений, генерируется в `docs/sandbox/SANDBOX_REFERENCE.md` в репозитории `service-didit-verification` командой `pipenv run python scripts/generate_sandbox_reference.py`. Эта страница дублирует данный справочник. Если что-то здесь кажется устаревшим, всегда ориентируйтесь на эндпоинт каталога в реальном времени. Эндпоинт каталога требует авторизации: передайте ваш API-ключ в заголовке `x-api-key`, как и при любом другом вызове, или токен сессии, если вы читаете его изнутри запущенной сессии.

## Модель среды

Песочница — это **режим на уровне приложения** (`ApplicationDetail.mode == SANDBOX`), по той же логике, что и тестовый режим в Stripe. Пока сессия выполняется в песочнице приложения:

* Каждый внешний провайдер (OCR, AML, сравнение лиц, проверка живости, NFC, телефон, email, IP, POA, проверка по базам данных, ИИ для работы с документами) **имитируется**: к третьим сторонам никогда не обращаются.
* **Проверка живости работает точно так же, как в продакшн-среде.** Сценарий с активной проверкой живости запускает настоящую активную съёмку в песочнице, как в размещённом потоке, так и при передаче в веб через нативные SDK, чтобы вы могли протестировать тот опыт, который получат ваши пользователи. Симулируется только **результат** проверки живости, задаваемый сценарием или магическим значением, а в отчёте фиксируется метод, который настроен в вашем сценарии.
* **Пользовательские домены работают только в продакшне.** Приложение песочницы не может добавить [пользовательский домен](https://docs.didit.me/ru/console/custom-domain.md); сессии песочницы всегда выполняются на домене размещённой страницы верификации по умолчанию.
* Сессии **никогда не тарифицируются**, а проверка баланса пропускается.
* Для каждого приложения действует квота **500 операций создания сессий за 24 часа**.
* Сообщения webhook содержат `"environment": "sandbox"` (сессии продакшна содержат `"environment": "live"`).
* Размещённый поток передаёт среду сессии, чтобы интерфейс мог предупредить пользователей о том, что не следует загружать реальные персональные данные.
* **Результаты никогда не зависят от пикселей**: извлечённые данные и статусы берутся из сценария или магического значения. Сами захваченные медиафайлы (документы, селфи, видео, файлы POA) действительно сохраняются, точно так же, как в сессии продакшна.

## Мониторинг транзакций в песочнице

Песочница работает **по модели сессии**: она имитирует провайдеров, которых вызывала бы сессия верификации. У мониторинга транзакций нет провайдера для имитации, поэтому приложение в песочнице работает иначе: транзакция сохраняется, но **ничего из того, что принимает решение, проверяет, отправляет уведомления или выставляет счёт, с ней не выполняется**.

Транзакция, созданная в приложении песочницы, сохраняется и возвращается как обычно, но с ней не происходит следующее:

* **Нет оценки по правилам.** `rule_runs` пуст, независимо от режима ваших правил. Правило `ACTIVE` в приложении песочницы никогда не срабатывает, поэтому транзакция остаётся `APPROVED` с оценкой `0`, и оповещение или кейс не создаются.
* **Нет AML- и скрининга кошельков.** `provider_results` пуст даже для криптотранзакций в приложении с включённым мониторингом.
* **Нет событий webhook.** Ни `transaction.created`, ни `transaction.status.updated` для транзакции песочницы не доставляются.
* **Нет биллинга.** Событие использования записывается по цене `0.0000`, и ваш баланс не меняется.

Каждый ответ по транзакции содержит поле `environment` (`"live"` или `"sandbox"`), поэтому пустой `rule_runs` никогда не бывает неоднозначным: `"sandbox"` означает, что правила не оценивались, а не то, что ни одно из них не сработало. Business Console сообщает то же самое в карточке *Risk & decision* транзакции вместо простого «Правила не оценивались».

> [!NOTE]
>
> **Travel Rule: единственное исключение из правила «ничего не выполняется».** В приложении с включённым Travel Rule транзакция `travelRule` в песочнице всё равно запускает движок обмена: создаётся запись о переводе, и она проходит через свои статусы.
> Песочница никогда не связывается ни с кем за пределами Didit.
> Её единственный контрагент, [Didit Test VASP](https://docs.didit.me/ru/transaction-monitoring/travel-rule-sandbox.md), встроен в платформу: никакое сообщение комплаенса не доходит до реального контрагентского VASP через один из каналов (`TRP`, подключённую вами сеть, электронную почту или `INTERNAL`), скрининг атрибуции контрагентского VASP не выполняется, а отмена никуда не отправляет сообщений контрагенту.
> События webhook `travel_rule.status.updated` доставляются и помечаются `"environment": "sandbox"`.
>
> **Исходящая**: транзакция `travelRule`, которую вы отправляете.
> Сначала выполняется проверка `threshold_amount`. В песочнице она применяется только тогда, когда вы передаёте `transaction_details.amount_in_default_currency`, потому что песочница не конвертирует валюты. Без этого поля каждый перевод в песочнице считается выше порога.
> Если на перевод никто не отвечает, он истекает через `confirmation_timeout_hours`, и тогда к транзакции применяется ваш `timeout_outcome`.
> Выше порога обычная проверка объявленного некастодиального кошелька работает как обычно: перевод на [объявленный некастодиальный кошелёк](https://docs.didit.me/ru/transaction-monitoring/travel-rule.md#объявленные-некастодиальные-кошельки) переходит в `UNCONFIRMED_OWNERSHIP` без отправки чего-либо. Завершить его в песочнице можно через [виджет подтверждения владения кошельком](https://docs.didit.me/ru/transaction-monitoring/wallet-ownership-widget.md) или через [подтверждение владения](https://docs.didit.me/ru/management-api/travel-rule/confirm-ownership.md), если целевой кошелёк уже есть в адресной книге кошельков.
> Любой другой перевод выше порога направляется в Didit Test VASP по каналу `TEST_VASP`. Он отвечает внутри Didit сценарием, который вы выбираете по кошельку или имени получателя: перевод завершается, отклоняется, данные не совпадают, переходит в `COUNTERPARTY_VASP_NOT_REACHABLE`, истекает (тогда к транзакции применяется ваш `timeout_outcome`) или ждёт подтверждения владения кошельком. Все сценарии см. в [Test Travel Rule в песочнице](https://docs.didit.me/ru/transaction-monitoring/travel-rule-sandbox.md).
>
> **Входящая**: `POST /v3/travel-rule/inbound/`. Регистрация никогда не отправляет сообщение по каналу, поэтому в ней ничего не моделируется: песочница сопоставляет поступление с вашей адресной книгой кошельков и завершает его синхронно, точно так же, как продакшн-среда. Результатом становится реальный исход, а не `AWAITING_COUNTERPARTY`: `ON_HOLD` (совпадения в адресной книге нет), `UNCONFIRMED_OWNERSHIP` (совпавшая запись не прошла проверку владения), `COUNTERPARTY_MISMATCHED_DATA` (имя получателя не совпадает с владельцем кошелька) или `COMPLETED`, затем `FINISHED` (найдена проверенная запись).
> Чтобы получить перевод от Didit Test VASP, используйте [Запустить входящий перевод от Test VASP](https://docs.didit.me/ru/management-api/travel-rule/trigger-test-vasp-inbound.md) с одним из кошельков вашей адресной книги.

### Сценарии Test VASP для Travel Rule

Каталог `travel_rule.scenarios` перечисляет эти исходящие сценарии. Задайте имя получателя ниже для исходящей транзакции `travelRule` после включения Travel Rule в приложении песочницы. Проверки порога и объявленного некастодиального кошелька, описанные выше, выполняются первыми.

| Сценарий | Имя получателя | Результат |
| - | - | - |
| `accept` | `Didit Test VASP` | `COMPLETED` |
| `decline` | `Didit Test VASP Decline` | `COUNTERPARTY_VASP_GENERAL_DECLINE` |
| `name_mismatch` | `Didit Test VASP Name Mismatch` | `COUNTERPARTY_MISMATCHED_DATA` |
| `not_reachable` | `Didit Test VASP Not Reachable` | `COUNTERPARTY_VASP_NOT_REACHABLE` после повторных попыток доставки |
| `timeout` | `Didit Test VASP Timeout` | `EXPIRED`, когда проверка истечения срока выполняется после одноминутного дедлайна |
| `self_hosted` | `Didit Test VASP Self Hosted` | `UNCONFIRMED_OWNERSHIP` |

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

[Триггер входящего перевода Test VASP](https://docs.didit.me/ru/management-api/travel-rule/trigger-test-vasp-inbound.md) принимает в поле `scenario` только значения `accept` и `name_mismatch`.

> [!NOTE]
>
> **Как проверить правило перед запуском в продакшн.** Используйте [Backtest](https://docs.didit.me/ru/transaction-monitoring/rules-api.md#создание-бэктест-активация): он повторно применяет правило к вашей реальной истории транзакций и сообщает `evaluated` / `matched` / `affected_entities`, не меняя статус ни одной транзакции. Сочетайте его с режимом `TEST` в продакшн-приложении: правило в режиме `TEST` оценивает каждую новую продакшн-транзакцию и фиксирует, что оно бы сопоставило, не меняя оценку или статус. Когда селективность вас устроит, переключите правило в `ACTIVE`.

## Как переключаться между live и песочницей

Live и песочница - это **отдельные приложения**, поэтому тестовый трафик и продакшн-данные никогда не смешиваются. У каждого приложения есть `mode` со значением `live` или `sandbox`:

* Используйте API-ключ приложения в режиме **sandbox**, чтобы получать смоделированные сессии без списания средств, в которых результат можно задать.
* Используйте API-ключ приложения в режиме **live** для реальных верификаций.

Поле `sandbox_scenario` (при создании сессии и в отдельном AML API), а также эндпоинты симуляции принимаются только в приложениях песочницы. В live-приложениях они отклоняются.

## Песочница в размещённом процессе верификации

Сессии, созданные в приложении песочницы, показывают дополнительный интерфейс в размещённом процессе верификации (по `url`, который возвращает `POST /v3/session/`):

* **Баннер песочницы внутри карточки.** На каждом экране внутри карточки показан баннер "Только тестовые данные - реальных вызовов нет". Так всегда видно, что сессия не обращается к реальным провайдерам и не затрагивает ваш баланс. Записанные медиафайлы сохраняются так же, как для любой сессии, поэтому используйте образцы документов и тестовые данные, а не настоящие документы, удостоверяющие личность, и персональные данные.
* **Выбор сценария до начала процесса.** До начала съёмки карточка предлагает выбрать тестовый результат: сначала выберите результат, затем триггер для него. После подтверждения вызывается `POST /v3/session/{session_id}/sandbox/arm/` (см. [Активация (или повторная активация) сессии перед стартом процесса](#3-предварительная-настройка-или-повторная-настройка-сессии-до-начала-верификации) ниже), после чего процесс продолжается с уже применёнными магическими значениями этого сценария.
* **Полоса образцов документов.** Непосредственно под компонентом загрузки и съёмки документов расположена строка образцов документов песочницы (до 3). Нажмите на образец, чтобы использовать его вместо реальной загрузки.

Сессии песочницы сохраняют **реальные** записанные медиафайлы: документы, селфи, видео проверки живости и файлы подтверждения адреса загружаются и хранятся точно так же, как для live-сессии. *Извлечённые* данные (поля верификации личности, оценки совпадения лиц, результаты проверки живости и подобные) и сам результат сессии (одобрена / на проверке / отклонена) задаются сценарием или магическим значением и никогда не выводятся из записанных медиафайлов. В Business Console разделы с извлечёнными данными сессии песочницы помечаются чипом **Смоделированные данные**, чтобы проверяющие сразу видели, какие части сессии реальные, а какие заданы сценарием.

## Сценарии

Каждый сценарий представляет собой именованный набор магических значений. Передайте его slug в `sandbox_scenario` при создании сессии (или в endpoint симуляции), чтобы воспроизвести нужный результат.

| Slug | Заголовок | Статус по умолчанию | Описание |
| - | - | - | - |
| `approve` | Happy path: все функции одобряют | Одобрена | Поведение песочницы по умолчанию: каждая замоканная функция возвращает успешный результат APPROVED. Статус сессии становится APPROVED. |
| `decline_aml_hit` | AML: политически значимое лицо | Отклонена | Мок AML возвращает одно совпадение, и сессия отклоняется на функции AML. Совпадение использует ту же [схему Hit](https://docs.didit.me/ru/core-technology/aml-screening/report-aml-screening.md#поля-для-каждого-совпадения), что и рабочие провайдеры AML: поля `url`, `match_score`, `risk_score`, `review_status`, `properties`, `pep_matches[]` и `score_breakdown` заполнены, и записывается журнал с предупреждением POSSIBLE\_MATCH\_FOUND. |
| `decline_document_expired` | Верификация личности: документ просрочен | Отклонена | Мок верификации личности возвращает паспорт, срок действия которого истёк. Сессия отклоняется на верификации личности, и записывается журнал предупреждения DOCUMENT\_EXPIRED. |
| `decline_minimum_age` | Верификация личности: возраст ниже минимального по политике | Отклонена | Мок верификации личности возвращает дату рождения, из которой пользователю примерно 10 лет. Проверка возраста в продакшн-среде выдаёт MINIMUM\_AGE\_NOT\_MET, и сценарий отклоняет сессию. |
| `decline_mrz_validation` | Верификация личности: ошибка контрольной суммы MRZ | Отклонена | Мок верификации личности возвращает паспорт с повреждённой контрольной суммой MRZ. Валидатор MRZ в продакшене выдаёт MRZ\_VALIDATION\_FAILED, и сессия отклоняется. |
| `decline_could_not_recognize_document` | Верификация личности: документ не читается | Отклонена | Мок верификации личности возвращает пустой ответ. Продакшен выдаёт COULD\_NOT\_RECOGNIZE\_DOCUMENT и передаёт его в SDK. |
| `decline_face_match_low_similarity` | Сравнение лиц: сходство ниже порога отклонения | Отклонена | Мок сравнения лиц возвращает низкую оценку. Продакшен выдаёт LOW\_FACE\_MATCH\_SIMILARITY, и настройка действий узла сценария отклоняет сессию. |
| `decline_database_no_match` | Проверка по базам данных: совпадений нет во всех сервисах | Отклонена | Каждый выбранный сервис базы данных возвращает NO\_MATCH. Продакшен выдаёт DATABASE\_VALIDATION\_NO\_MATCH, и сценарий отклоняет сессию. |
| `decline_phone_high_risk` | Телефон: зарезервированный тестовый номер высокого риска | Отклонена | Мок проверки телефона блокирует верификацию (зарезервированный тестовый диапазон). Проверка телефона завершается со статусом BLOCKED и выдаёт HIGH\_RISK\_PHONE\_NUMBER. |
| `decline_email_breach` | Электронная почта: совпадение в базе утечек | Отклонена | Мок проверки утечек электронной почты возвращает одно совпадение по адресу. Проверка электронной почты выдаёт BREACHED\_EMAIL\_DETECTED. |
| `decline_ip_blocklist` | Анализ IP: адрес в списке блокировки | Отклонена | Мок анализа IP отклоняет местоположение с IP\_ADDRESS\_IN\_BLOCKLIST. Сессия отклоняется на анализе IP. |
| `decline_poa_address_mismatch` | POA: адрес не совпадает с указанным | Отклонена | Мок POA отклоняет подтверждение адреса с ADDRESS\_MISMATCH\_WITH\_PROVIDED. Сессия отклоняется на POA. |
| `decline_liveness_attack` | Проверка живости: обнаружена атака на лицо | Отклонена | Мок пассивной проверки живости обнаруживает признак атаки на лицо и выдаёт LIVENESS\_FACE\_ATTACK. Сессия отклоняется на проверке живости. |
| `decline_nfc_chip_not_verified` | NFC: чип ePassport не верифицирован | Отклонена | Мок ePassport возвращает чип, подпись SOD/DG которого не проходит проверку целостности. Продакшен выдаёт NFC\_CHIP\_NOT\_VERIFIED, и сессия отклоняется на NFC, если сценарий отклоняет сессию из-за неверифицированных чипов. |
| `decline_nfc_trust_anchor_missing` | NFC: доверенный корневой сертификат выдающей страны недоступен | Отклонена | Мок ePassport возвращает чип, подписанный DSC, CSCA страны выдачи которого отсутствует в хранилище доверия. Продакшен выдаёт NFC\_TRUST\_ANCHOR\_MISSING, и сессия отклоняется, если сценарий отклоняет сессию из-за неверифицированных чипов. |
| `decline_document_ai_unreadable` | Document AI: документ не читается | Отклонена | Мок Document AI не возвращает читаемых полей. Продакшн выдаёт DOCUMENT\_AI\_UNREADABLE\_DOCUMENT, и после исчерпания лимита повторных попыток документ получает статус отклонённого. |
| `review_aml_possible_match` | AML: возможное совпадение требует проверки | На проверке | Мок AML возвращает совпадение с более низкой уверенностью. Сессия переходит на проверку, и записывается журнал POSSIBLE\_MATCH\_FOUND уровня предупреждения, который аналитик должен обработать. |
| `review_face_match_borderline` | Сравнение лиц: пограничное сходство | На проверке | Мок сравнения лиц возвращает оценку между порогами проверки и отклонения. Сессия переходит на проверку по сравнению лиц. |
| `review_document_borderline_age` | Верификация личности: несовершеннолетний отправлен на проверку | На проверке | Мок верификации личности возвращает дату рождения, указывающую на возраст ниже настроенного в сценарии минимального возраста. Параметр minimum\_age\_action сценария установлен в REVIEW, а не DECLINE, поэтому сессия переходит на проверку на верификации личности вместо отклонения. |
| `review_poa_partial_match` | POA: частичное совпадение адреса | На проверке | Мок POA возвращает адрес, который только частично совпадает с указанным. Сессия переходит на проверку подтверждения адреса. |
| `review_database_partial_match` | Проверка по базам данных: частичное совпадение | На проверке | Сервисы баз данных возвращают частичные совпадения по имени и дате рождения. Сессия переходит на проверку по базам данных. |
| `decline_kyb_registry_mismatch` | KYB: данные реестра не совпадают | Отклонена | Мок реестра возвращает компанию, регистрационные данные которой не совпадают с ожидаемыми. Сессия верификации бизнеса отклоняется на проверке реестра. |
| `review_kyb_registry_partial` | KYB: данные реестра частично совпадают | На проверке | Мок реестра возвращает компанию, название которой только частично совпадает. Сессия верификации бизнеса переходит на проверку реестра. |

Сценарии `review_*` нужны, чтобы протестировать UX ручной проверки (очередь проверки в консоли, webhook `In Review`, действия проверяющего «одобрить» и «отклонить») без входных данных, которые приводят к отклонению. Два сценария `kyb_*` выше задают `expected_details.registration_number` вместо `expected_details.first_name`: они применяются только к сессиям верификации бизнеса (KYB).

## Магические значения

Магическое значение — это конкретное входное значение, которое заставляет одну имитируемую функцию выдать определённый риск. Чтобы его вызвать, задайте поле ввода равным магическому значению (напрямую или через сценарий).

| Функция | Поле ввода | Магическое значение | Риск | Описание |
| - | - | - | - | - |
| AML | `user_email` | `sandbox+aml_hit@didit.test` | `POSSIBLE_MATCH_FOUND` | AML: политически значимое лицо (PEP); мок AML возвращает одно совпадение, сессия отклоняется на этапе AML. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_EXPIRED` | `DOCUMENT_EXPIRED` | OCR: документ с истекшим сроком действия; сессия отклоняется на этапе верификации личности. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MINIMUM_AGE_NOT_MET` | `MINIMUM_AGE_NOT_MET` | OCR: дата рождения указывает, что пользователь младше минимального возраста, заданного в настройках; сессия отклоняется. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MAXIMUM_AGE_EXCEEDED` | `MAXIMUM_AGE_EXCEEDED` | OCR: извлечённая дата рождения указывает на возраст, превышающий максимальный возраст, заданный политикой. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_NUMBER_FORMAT_MISMATCH` | `DOCUMENT_NUMBER_FORMAT_MISMATCH` | OCR: извлечённый номер документа не соответствует ожидаемому формату (регулярное выражение из реестра документов). |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_PERSONAL_NUMBER_FORMAT_MISMATCH` | `PERSONAL_NUMBER_FORMAT_MISMATCH` | OCR: извлечённый личный номер не проходит проверку формата из реестра документов. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` | `DOCUMENT_NOT_SUPPORTED_FOR_APPLICATION` | OCR: тип извлечённого документа не входит в политику `documents_allowed` приложения. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_FULL_NAME_MISMATCH_WITH_PROVIDED` | `FULL_NAME_MISMATCH_WITH_PROVIDED` | OCR: имя в документе не совпадает с именем, которое клиент заранее указал в `expected_details`, при разнице выше порога совпадения имени. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_GENDER_MISMATCH_WITH_PROVIDED` | `GENDER_MISMATCH_WITH_PROVIDED` | OCR: извлечённый пол не совпадает с `expected_details.gender`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOB_MISMATCH_WITH_PROVIDED` | `DOB_MISMATCH_WITH_PROVIDED` | OCR: извлечённая дата рождения не совпадает с `expected_details.date_of_birth`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_COUNTRY_MISMATCH_WITH_PROVIDED` | `COUNTRY_MISMATCH_WITH_PROVIDED` | OCR: страна выдачи не совпадает с `expected_details.country` (или `id_country`). |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_NATIONALITY_MISMATCH_WITH_PROVIDED` | `NATIONALITY_MISMATCH_WITH_PROVIDED` | OCR: извлечённое гражданство не совпадает с `expected_details.nationality`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_IDENTIFICATION_NUMBER_MISMATCH_WITH_PROVIDED` | `IDENTIFICATION_NUMBER_MISMATCH_WITH_PROVIDED` | OCR: извлечённый номер документа, личный или налоговый номер не совпадает с `expected_details.identification_number`. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_COULD_NOT_RECOGNIZE_DOCUMENT` | `COULD_NOT_RECOGNIZE_DOCUMENT` | OCR-конвейер возвращает пустой или нераспознаваемый результат; в продакшн-среде возникает ошибка COULD\_NOT\_RECOGNIZE\_DOCUMENT. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MRZ_NOT_DETECTED` | `MRZ_NOT_DETECTED` | OCR: документ предполагает наличие MRZ, но конвейер не смог её найти. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MRZ_VALIDATION_FAILED` | `MRZ_VALIDATION_FAILED` | OCR: MRZ найдена, но не прошла проверку контрольной суммы или формата. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` | `MRZ_AND_DATA_EXTRACTED_FROM_OCR_NOT_SAME` | OCR: поля идентификации из MRZ не совпадают с полями, извлечёнными из визуальной зоны (VIZ). |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_BARCODE_NOT_DETECTED` | `BARCODE_NOT_DETECTED` | OCR: документ предполагает штрихкод, но он не найден. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_BARCODE_VALIDATION_FAILED` | `BARCODE_VALIDATION_FAILED` | OCR: штрихкод расшифрован, но не прошёл перекрёстную проверку полей. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_QR_NOT_DETECTED` | `QR_NOT_DETECTED` | OCR: документ предполагает QR-код, но он не найден. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_QR_VALIDATION_FAILED` | `QR_VALIDATION_FAILED` | OCR: QR-код расшифрован, но не прошёл перекрёстную проверку полей. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DATA_INCONSISTENT` | `DATA_INCONSISTENT` | OCR: проверки внутренней согласованности полей VIZ дают противоречивые результаты. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_SIDES_MISMATCH` | `DOCUMENT_SIDES_MISMATCH` | OCR: лицевая и оборотная стороны document\_name не относятся к одному документу. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_NAME_NOT_DETECTED` | `NAME_NOT_DETECTED` | OCR: из документа не удалось извлечь ни имя, ни фамилию. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DATE_OF_BIRTH_NOT_DETECTED` | `DATE_OF_BIRTH_NOT_DETECTED` | OCR: класс документа предполагает наличие даты рождения, но извлечь её не удалось. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_EXPIRATION_DATE_NOT_DETECTED` | `EXPIRATION_DATE_NOT_DETECTED` | OCR: класс документа предполагает наличие срока действия, но извлечь его не удалось. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_DOCUMENT_NUMBER_NOT_DETECTED` | `DOCUMENT_NUMBER_NOT_DETECTED` | OCR: не удалось извлечь ни номер документа, ни личный номер. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_COULD_NOT_DETECT_DOCUMENT_TYPE` | `COULD_NOT_DETECT_DOCUMENT_TYPE` | OCR: классификатор не смог отнести снимок к поддерживаемому типу документа. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_PORTRAIT_IMAGE_NOT_DETECTED` | `PORTRAIT_IMAGE_NOT_DETECTED` | OCR: конвейер не смог выделить область с портретом на документе. |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_UNPARSED_ADDRESS` | `UNPARSED_ADDRESS` | OCR — в документе есть поле адреса, но геокодирование или разбор не вернули пригодных данных. |
| DATABASE\_VALIDATION | `expected_details.first_name` | `SANDBOX_DB_NO_MATCH` | `DATABASE_VALIDATION_NO_MATCH` | Проверка по базам данных — все государственные и реестровые сервисы возвращают NO\_MATCH; сессия отклоняется по результату проверки по базам данных. |
| FACEMATCH | `expected_details.first_name` | `SANDBOX_FACE_LOW_MATCH` | `LOW_FACE_MATCH_SIMILARITY` | Сравнение лиц — оценка сходства ниже порога отказа; сессия отклоняется по результату сравнения лиц. |
| PHONE | `phone_number` | `+15005550009` | `HIGH_RISK_PHONE_NUMBER` | Телефон — зарезервированный недоставляемый тестовый номер повышенного риска; мок проверки телефона возвращает ошибку. |
| EMAIL | `user_email` | `sandbox+breach@didit.test` | `BREACHED_EMAIL_DETECTED` | Электронная почта — база утечек возвращает совпадение по этому адресу. |
| LOCATION | `expected_details.first_name` | `SANDBOX_IP_BLOCKLIST` | `IP_ADDRESS_IN_BLOCKLIST` | Анализ IP — IP-адрес вызывающей стороны находится в списке блокировки приложения; сессия отклоняется по результату анализа IP. |
| PROOF\_OF\_ADDRESS | `expected_details.first_name` | `SANDBOX_POA_ADDRESS_MISMATCH` | `ADDRESS_MISMATCH_WITH_PROVIDED` | POA — адрес в загруженном документе не совпадает с адресом, который клиент заполнил в `expected_details`; сессия отклоняется по результату POA. |
| LIVENESS | `expected_details.first_name` | `SANDBOX_LIVENESS_ATTACK` | `LIVENESS_FACE_ATTACK` | Проверка живости — мок пассивной проверки живости обнаруживает признак атаки на лицо; сессия отклоняется по результату проверки живости. |
| NFC | `expected_details.first_name` | `SANDBOX_NFC_CHIP_NOT_VERIFIED` | `NFC_CHIP_NOT_VERIFIED` | NFC — мок электронного паспорта возвращает чип, подпись SOD/DG которого не проходит проверку целостности; в продакшне выдаётся NFC\_CHIP\_NOT\_VERIFIED, и сессия отклоняется, если сценарий отклоняет непроверенные чипы. |
| NFC | `expected_details.first_name` | `SANDBOX_NFC_TRUST_ANCHOR_MISSING` | `NFC_TRUST_ANCHOR_MISSING` | NFC — DSC связан с CSCA, которого нет в хранилище доверенных сертификатов; в продакшне выдаётся NFC\_TRUST\_ANCHOR\_MISSING и применяется настроенное действие для непроверенного чипа. |
| DOCUMENT\_AI | `expected_details.first_name` | `SANDBOX_DOCUMENT_AI_UNREADABLE` | `DOCUMENT_AI_UNREADABLE_DOCUMENT` | Document AI — извлечение не возвращает читаемых полей; в продакшне выдаётся DOCUMENT\_AI\_UNREADABLE\_DOCUMENT, и документ получает статус «отклонён», когда исчерпан лимит повторных попыток. |
| AML | `user_email` | `sandbox+aml_review@didit.test` | `POSSIBLE_MATCH_FOUND` | AML — возможное совпадение, которое требует ручного разбора; сессия переходит в статус «На проверке». |
| FACEMATCH | `expected_details.first_name` | `SANDBOX_FACE_BORDERLINE_MATCH` | `LOW_FACE_MATCH_SIMILARITY` | Сравнение лиц — пограничное сходство между порогами проверки и отказа; сессия переходит в статус «На проверке». |
| ID\_VERIFICATION | `expected_details.first_name` | `SANDBOX_OCR_BORDERLINE_AGE` | `MINIMUM_AGE_NOT_MET` | OCR — возраст ниже минимального, но сценарий отправляет на проверку, а не отклоняет при несоответствии минимальному возрасту; сессия переходит в статус «На проверке». |
| DATABASE\_VALIDATION | `expected_details.first_name` | `SANDBOX_DB_PARTIAL_MATCH` | `DATABASE_VALIDATION_PARTIAL_MATCH` | Проверка по базам данных — личность совпадает, но имя и дата рождения совпадают лишь частично; сессия переходит в статус «На проверке». |
| PROOF\_OF\_ADDRESS | `expected_details.first_name` | `SANDBOX_POA_PARTIAL_MATCH` | `ADDRESS_MISMATCH_WITH_PROVIDED` | POA — адрес в загруженном документе частично совпадает с указанным адресом; сессия переходит в статус «На проверке». |
| KYB\_REGISTRY | `expected_details.registration_number` | `SANDBOX-KYB-MISMATCH` | `KYB_REGISTRY_DATA_MISMATCH_WITH_EXPECTED` | KYB - данные компании в реестре не совпадают с ожидаемыми реквизитами; сессия отклоняется. |
| KYB\_REGISTRY | `expected_details.registration_number` | `SANDBOX-KYB-REVIEW` | `KYB_REGISTRY_DATA_PARTIAL_MATCH_WITH_EXPECTED` | KYB - данные компании в реестре частично совпадают; сессия переходит в статус «На проверке». |

## Поиск без документов и идентификационные кошельки

Приложения в песочнице могут включить все идентификационные кошельки из каталога стран, в том числе кошельки, недоступные в продакшн-приложениях.
Сценарий `approve` по умолчанию имитирует подтверждённую личность без входа во внешний кошелёк.
Результат сохраняется в сессии, после чего выполняется следующий шаг сценария.
Песочница не проверяет реальные учётные данные кошелька и не взимает плату за имитируемые попытки.

Запросы поиска по-прежнему проверяют введённые поля и используют настроенный лимит попыток, по умолчанию равный одной попытке.
Для проверки повторных попыток и правил перехода к резервному варианту используйте следующие сценарии:

| Сценарий | Имитируемый результат |
| - | - |
| `lookup_partial_match` | Частичное совпадение в реестре; учитывается в лимите попыток. |
| `lookup_no_match` | Реестр отвечает без совпадения; учитывается в лимите попыток. |
| `lookup_provider_error` | Реестр не отвечает; пользователю предлагается повторить попытку, а после трёх неотвеченных попыток применяется резервный сценарий при ошибке провайдера. |
| `wallet_cancelled` | Пользователь отменяет вход в кошелёк. |
| `wallet_timeout` | Время входа в кошелёк истекает. |
| `wallet_provider_error` | Не удаётся выполнить вход в кошелёк. |

В зависимости от настройки страны сбои кошелька приводят к переходу к съёмке документа или к отказу.
Завершённые попытки поиска учитываются отдельно, поэтому две разрешённые попытки дают два результата до перехода к резервному варианту.
Всё использование песочницы остаётся бесплатным.

## Проверка банковского счёта

Песочница для шага банковской верификации предлагает [оба способа](https://docs.didit.me/ru/core-technology/bank-verification/verification-methods.md) в каждой стране, в порядке, заданном шагом, на имитируемом сервисе без банка и без оплаты.
При порядке по умолчанию человек начинает со входа в банк и выбирает **Введите реквизиты счёта**, чтобы выполнить [проверку счёта](https://docs.didit.me/ru/core-technology/bank-verification/account-check.md); задайте `bank_method_order` как `["account_lookup", "open_banking"]`, чтобы начать с неё.
Последние четыре символа введённого счёта определяют ответ; все окончания и действительный счёт для каждого формата см. в разделе [Проверка в песочнице](https://docs.didit.me/ru/core-technology/bank-verification/account-check.md#тестирование-в-песочнице).
[API проверки счёта](https://docs.didit.me/ru/standalone-apis/bank-account-check.md) для ключа песочницы возвращает ответы по тем же окончаниям.

## Los documentos de muestra

> [!WARNING]
>
> Nunca subas documentos de identidad reales en el sandbox. Usa en su lugar los documentos de muestra integrados.

El flujo alojado ofrece tres documentos de muestra, uno por tipo de documento:

| País | Tipo de documento |
| - | - |
| España | Documento nacional de identidad |
| Argentina | Pasaporte |
| Polonia | Permiso de conducir |

Toca una muestra de la tira para usarla en lugar de una captura real. Los datos extraídos y el resultado de la sesión siempre provienen del escenario o valor mágico seleccionado, así que cualquier muestra funciona con cualquier escenario.

## Identidad de muestra: pruebas de `expected_details`

Cada documento del sandbox se fabrica a partir de una identidad **fija**.
Los valores extraídos son los mismos en cada sesión y nunca se derivan de la fecha actual, así que puedes rellenar `expected_details` con ellos y comprobar de principio a fin el manejo de las comprobaciones de comparación de campos y de las advertencias.
Pasa los valores que se indican abajo y las comprobaciones de comparación se superan; pasa cualquier otro valor y se activa a propósito la advertencia `*_MISMATCH_WITH_PROVIDED` correspondiente.

Las fechas son comunes a todos los documentos de muestra:

| Campo | Valor |
| - | - |
| `date_of_birth` | `1990-06-15` |
| Fecha de emisión | `2025-06-15` |
| Fecha de caducidad | `2035-06-15` |

El resto de la identidad depende del documento que uses:

| `sandbox_sample` | Documento | `first_name` | `last_name` | `gender` | `nationality` | `id_country` | `identification_number` |
| - | - | - | - | - | - | - | - |
| *(predeterminado, sin muestra seleccionada)* | ePassport de Brasil | `GUSTAVO` | `MATSUMOTO` | `M` | `BRA` | `BRA` | `YC531181` |
| `spain-id-card-2021` | Documento nacional de identidad de España | `CARMEN` | `ESPAÑOLA ESPAÑOLA` | `F` | `ESP` | `ESP` | `CAA000000` |
| `argentina-passport-2009` | Pasaporte de Argentina | `MARIA VICTORIA` | `VILLAREAL` | `F` | `ARG` | `ARG` | `AAF794880` |
| `poland-driving-license-2019` | Permiso de conducir de Polonia | `JAN` | `KOWALSKI` | no aparece en este documento | `POL` | `POL` | `SP005/89/5` |

```json theme={null}
{
  "workflow_id": "<your-workflow-uuid>",
  "expected_details": {
    "date_of_birth": "1990-06-15",
    "gender": "M",
    "nationality": "BRA",
    "identification_number": "YC531181"
  }
}
```

`first_name` y `last_name` son la excepción: el sandbox repite en el documento fabricado los nombres que envías en `expected_details`, así que la comparación de nombres se supera con cualquier nombre.
Usa el valor mágico `SANDBOX_OCR_FULL_NAME_MISMATCH_WITH_PROVIDED` para probar una discrepancia de nombre, y `SANDBOX_OCR_DOB_MISMATCH_WITH_PROVIDED` para una discrepancia de fecha de nacimiento.

> [!NOTE]
>
> Si tu flujo restringe `documents_allowed` a un país o tipo de documento que excluye el ePassport de Brasil, el sandbox fabrica en su lugar un documento del primer país permitido, así que `nationality`, `id_country` y el nombre del documento siguen a ese país. Las fechas indicadas arriba no cambian.

### Lo que el documento fabricado no incluye

El documento fabricado es la plantilla genérica del país y tipo de documento permitidos, así que los campos que solo proporciona un documento real emitido por el Estado quedan vacíos. El que importa para el enrutamiento es la **región / estado de EE. UU.** (`kyc.region`): un permiso de conducir o una identificación de EE. UU. del sandbox no tiene estado, así que una condición de bifurcación como `Region equals IL` nunca se cumplirá en el sandbox y, si tampoco se cumple ninguna otra rama del nodo, el flujo toma la rama de respaldo del nodo (la rama sin condiciones). Esto no es una revisión ni un fallo de la rama: la condición simplemente no tiene nada que leer. Un campo ausente también hace fallar `not equals` y `not in`; consulta [cómo leen las condiciones de bifurcación los datos de la sesión](https://docs.didit.me/ru/console/workflows.md#как-условия-ветвей-считывают-данные-сессии) para ver la diferencia entre un campo ausente y una cadena vacía.

Para probar un flujo que depende del estado en el sandbox, decide la bifurcación a partir de un valor que controles en la sesión y no a partir del documento:

* Envía el estado en `metadata` al crear la sesión (por ejemplo, `"metadata": {"credential_state": "IL"}`) y bifurca según `metadata.credential_state`. Los metadatos se evalúan en el sandbox exactamente igual que en producción.
* Conserva la condición `kyc.region`, derivada del documento, para el tráfico en producción si también necesitas que el documento demuestre el estado; en modo producción la región se lee del documento real.

Lo demás del enrutamiento es idéntico a producción: el grafo del flujo, las condiciones de bifurcación, los valores de `metadata` y `expected_details`, los nodos de acción y los nodos de estado se ejecutan de verdad. El sandbox nunca envía una sesión a revisión por su cuenta: una sesión del sandbox termina En revisión solo cuando el flujo la dirige allí (un escenario `review_*`, un valor mágico asignado a una acción de revisión o un nodo de estado en el grafo).

## Códigos OTP y suscripción al envío de correos

* **OTP de teléfono:** la comprobación de teléfono del sandbox acepta cualquier código bien formado (de 4 a 8 dígitos; incluido `123456`). Una entrada mal formada sigue devolviendo `400`.
* **OTP de correo electrónico:** la comprobación de correo del sandbox acepta cualquier código bien formado (incluido `123456`). Una entrada mal formada sigue devolviendo `400`.

Por defecto, las sesiones del sandbox **no** envían correos (alertas de revisión, cambios de estado, OTP, reenvío de la verificación, nuevos enlaces de sesión, etc.). Para enviar un correo de todas formas, usa uno de estos patrones de suscripción en la dirección del destinatario:

| Patrón de suscripción | Ejemplo |
| - | - |
| `<local>+sandbox@<domain>` | `alice+sandbox@example.com` |
| `*@didit.test` | `alice@didit.test` |

## Управление результатами: сценарии, магические значения, предварительная настройка и endpoint simulate

Есть пять способов управлять результатом в песочнице.

### 1. `sandbox_scenario` при создании сессии

Укажите slug сценария при создании сессии (`POST /v3/session/`). Процесс создания раскрывает встроенные в сценарий магические значения в поля ввода сессии, поэтому имитированные провайдеры возвращают нужный результат через реальный конвейер сценария.

```json theme={null}
{
  "workflow_id": "<your-workflow-uuid>",
  "sandbox_scenario": "decline_document_expired"
}
```

### 2. Магические значения, введённые вручную

Задайте отдельные поля ввода самостоятельно, например `expected_details.first_name = "SANDBOX_OCR_DOCUMENT_EXPIRED"` или `user_email = "sandbox+aml_hit@didit.test"`. Полный реестр см. в таблице магических значений выше.

### 3. Предварительная настройка (или повторная настройка) сессии до начала верификации

Задайте или замените настроенный сценарий у уже существующей сессии, пока она не перешла дальше статуса `Not Started`. Этот endpoint вызывает [выбор сценария до начала верификации](#песочница-в-размещённом-процессе-верификации). Вы также можете вызвать его самостоятельно, чтобы создать собственный выбор сценария или тестовый стенд:

```
POST /v3/session/{session_id}/sandbox/arm/
Session-Token: <session_token>
```

```json theme={null}
{
  "scenario": "decline_document_expired"
}
```

Ответ 200:

```json theme={null}
{
  "session_id": "<session_id>",
  "scenario": "decline_document_expired",
  "status": "Not Started"
}
```

* Аутентифицируйтесь с помощью собственного `Session-Token` сессии (возвращается как `session_token` при создании сессии), а не с помощью API-ключа приложения. Это эндпоинт для клиентской стороны.
* Возвращает `400` для неизвестного slug сценария, а также `400`, если сессия перешла дальше `Not Started` (`"Scenario can only be armed before the verification starts."`).
* Возвращает `404`, если `Session-Token` принадлежит продакшн-приложению (не песочнице) или не совпадает с `session_id` в пути.
* **Повторная настройка заменяет предыдущий сценарий.** Очищаются только магические значения, которые записал предыдущий сценарий, а всё, что пользователь ввёл вручную (email, имя и т. д.), остаётся без изменений. Например: если вы настроили `decline_phone_high_risk`, а затем `approve`, номер телефона возвращается к пустому значению, но email, введённый клиентом, сохраняется после обоих вызовов.

### 4. Endpoint simulate

Принудительно установите конечный статус постфактум:

* Консоль или API-ключ (требуется привилегия `write:sessions`; API-ключу с ограниченными правами нужен доступ на запись к сессиям): `POST /v3/session/{session_id}/simulate/`
* Размещённый поток (заголовок `Session-Token`): `POST /v3/session/{session_id}/sandbox/simulate/`

Оба варианта работают для сессий песочницы KYC и KYB.
Для продакшн-сессии возвращается `404`, и такой же ответ возвращается, если `Session-Token` не совпадает с `session_id` в пути.

Все поля тела запроса необязательны, но необходимо указать хотя бы одно из полей `new_status`, `scenario` или `risk`:

| Поле | Тип | Что делает |
| - | - | - |
| `new_status` | string | `Approved`, `Declined`, `In Review`, `Expired` или `Abandoned`. Если поле не указано, используется статус по умолчанию для кейса риска (`risk` или первый риск, который несут магические значения сценария), а если его нет, статус по умолчанию сценария. |
| `scenario` | string, до 100 символов | Slug сценария. Если не указан `risk`, применяется первый риск, который содержат его магические значения. |
| `risk` | string, до 128 символов | Кейс риска. Его предупреждение добавляется в сессию. |
| `node_id` | string, до 128 символов | Узел сценария, к которому прикрепляется предупреждение. По умолчанию это текущий узел сессии. |
| `comment` | string, до 500 символов | Примечание, добавляемое к записи активности, которую фиксирует изменение статуса. |
| `send_webhooks` | boolean, по умолчанию `true` | Отправляет ли изменение статуса webhook. |

`send_webhooks: true` отправляет именно те webhook, которые отправляет реальное изменение статуса: `status.updated`, а также события `user.status.updated` и `user.data.updated` (или `business.status.updated` и `business.data.updated` для сессии компании), которые вызывает это изменение, всем адресам назначения webhook, подписанным на них.
При `send_webhooks: false` статус всё равно меняется, но webhook не записывается в журнал и не отправляется.
Механизм восстановления пропущенных webhook никогда не отправляет это решение повторно, а консоль при этом обновляется в реальном времени.
Следующее изменение статуса сессии отправляет webhook в обычном режиме.

```json theme={null}
{
  "scenario": "decline_aml_hit",
  "send_webhooks": false
}
```

Ответ 200:

```json theme={null}
{
  "session_id": "<session_id>",
  "previous_status": "In Progress",
  "status": "Declined",
  "scenario": "decline_aml_hit",
  "risk": "POSSIBLE_MATCH_FOUND",
  "send_webhooks": false
}
```

* Поле `status` содержит статус, который установила симуляция, а `previous_status` содержит статус, который был у сессии до неё.
* `scenario` возвращает ваш slug, а в `risk` указан применённый кейс риска; каждое из полей равно `null`, если его нет.
* `send_webhooks` возвращает применённое значение.
* Возвращает `400` для неизвестного сценария или риска, если нельзя определить `new_status`, для любого другого `new_status`, а также если у сессии уже есть запрошенный статус (`["The new status is the same as the current status."]`).

### 5. `sandbox_scenario` в отдельном AML API

У серверного AML-скрининга нет конечного пользователя и сессии, которую можно настроить, поэтому slug указывается в самом запросе на скрининг (`POST /v3/aml/`):

```json theme={null}
{
  "full_name": "Ada Lovelace",
  "save_api_request": true,
  "sandbox_scenario": "decline_aml_hit"
}
```

* `decline_aml_hit` возвращает одно совпадение в формате продакшна и завершает скрининг со статусом `Declined`; `review_aml_possible_match` завершает его со статусом `In Review`. Сценарий, который не настраивает результат AML, оставляет скрининг чистым.
* При `save_api_request: true` (по умолчанию) скрининг сохраняется точно так же, как при работе с продакшн-ключом, поэтому возвращённый `request_id` можно использовать в `GET /v3/session/{request_id}/decision/` и `GET /v3/session/{request_id}/generate-pdf/`.
* Возвращает `400` для неизвестного slug сценария, а также `400`, если API-ключ принадлежит продакшн-приложению.

## Где появляется `sandbox_scenario`

Slug настроенного сценария (`null`, если сценарий не настроен) возвращается в одних интерфейсах API и намеренно опускается в других:

| Поверхность | Возвращается? |
| - | - |
| Payload текущего шага (KYC и KYB) | Да, как `sandbox_scenario` |
| `GET /v1/session/{id}/decision/` | Да, как `sandbox_scenario` |
| `GET /v3/session/{id}/decision/` (см. [Получение сессии](https://docs.didit.me/ru/sessions-api/retrieve-session.md)) | Да, верхнеуровневое поле `sandbox_scenario` (null, если сценарий не настроен) |
| Webhooks сессии (`status.updated`, `data.updated`) | Да, как `sandbox_scenario`; `null` для продакшн-сессий или сессий песочницы без настроенного сценария |

Если вашей интеграции нужно ветвить логику на стороне сервера в зависимости от настроенного сценария, читайте его из конверта webhook или из любого из endpoint решения (`v1` или `v3`).

## Биллинг и использование

Использование песочницы учитывается, но никогда не тарифицируется:

* Каждый замоканный вызов всё равно записывает событие использования (`is_sandbox: true`, стоимость `0.0000`), чтобы объём запросов в песочнице был виден для отладки. Однако такие события никогда не добавляются к вашим итоговым показателям использования, никогда не списываются с баланса и никогда не попадают в счёт.
* Баланс, пополнение и показатели использования в продакшн-среде в Business Console по умолчанию отфильтровывают использование песочницы. Эндпоинты использования, связанные с пополнением баланса, принимают параметр `environment` (`live`, значение по умолчанию, или `sandbox`), чтобы объём запросов в песочнице можно было просматривать отдельно. При этом его стоимость всегда нулевая, и он не расходует бесплатный тариф.
* Проверка электронной почты и проверка телефона тарифицируются за каждый запрос, а не за результат по сессии, и песочница не может полностью воспроизвести это на уровне webhook. Проверки электронной почты и телефона в песочнице всё равно записывают событие использования за каждый запрос по стоимости `0.0000`, как и любая другая замоканная функция. Это принятое, известное расхождение с поведением биллинга в продакшене, а не ошибка.
* Формат ответа проверки по базам данных в песочнице намеренно отличается от формата конкретного провайдера в продакшене, поскольку реального провайдера для воспроизведения нет. Относитесь к payload проверки по базам данных в песочнице как к заменителю результата (статуса и кода предупреждения), а не как к побайтовой копии ответа реального провайдера.


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