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

Грамотно спроектированный процесс не блокирует добросовестного клиента из-за задержанного webhook, исправимой ошибки в документе или очереди операторов. Одновременно он не позволяет счёту выполнять действия, которые продукт ещё не разрешил. В POLADO такие процессы проектируются в рамках услуги FinTech и trading-системы вместе с клиентским интерфейсом, API-интеграциями, back-office и операционными контролями.

Нужны три слоя состояния, а не один KYC-статус

Поле вида kyc_status = pending | approved | rejected быстро становится недостаточным. В production-системе следует разделить три независимые области.

1. Сессия провайдера и обработка доказательств

Этот слой хранит внешние факты: название провайдера, ID внешней сессии, номер попытки, статус провайдера, коды причин, время получения, ID webhook-события и технический результат проверок. Если пользователь отправил документ, а сессия находится в состоянии processing, это ещё не внутреннее решение по аккаунту. Попытка верификации должна быть отдельной сущностью: у одного клиента может быть несколько повторных или заменяющих попыток.

2. Внутренний review и решение

Внутренний workflow может включать состояния not_started, awaiting_customer, queued_for_review, in_review, approved, declined, expired и superseded. Здесь фиксируются автор решения, причина, запрос дополнительной информации, момент постановки в очередь и версия применённого правила. Положительный ответ провайдера может вести к автоматическому одобрению либо к ручной проверке — это зависит от модели продукта.

3. Возможности счёта и активация

Разрешённые действия счёта нужно моделировать отдельно: can_view_market_data, can_open_demo_account, can_fund, can_withdraw, can_trade, can_use_margin. Такая модель не допускает опасного упрощения «KYC одобрен — значит открываем всё». Возможности рассчитываются на основании актуального внутреннего решения, типа счёта, параметров продукта и других необходимых входных данных.

Статус провайдера — это внешний факт; статус review — внутреннее решение; capabilities — разрешения продукта. Не объединяйте эти значения в одном поле.

Практическая машина состояний онбординга

Для клиента путь должен быть понятным, а для backend — строго определённым. Минимальный lifecycle может выглядеть так:

  1. Draft: счёт создан, но профиль ещё не заполнен.
  2. Identity required: для включения нужных возможностей требуется пройти идентификацию.
  3. Submitted / processing: данные или документы отправлены, ожидается внешний результат.
  4. Action required: клиент может исправить проблему: предоставить более чёткое изображение, недостающие данные или другой действительный документ.
  5. Review queued: по правилу или результату провайдера кейс попадает в операционную очередь.
  6. Under review: уполномоченный сотрудник взял кейс в работу.
  7. Approved: политика продукта рассчитывает и включает допустимые возможности.
  8. Declined: кейс или попытка закрыта с контролируемым клиентским результатом.
  9. Expired: сессия либо незавершённый путь истекли, нужна новая попытка.

Не смешивайте failed и declined. Failed обычно означает технический или исправимый пользователем результат: нечитаемое фото, неудачный захват selfie, ошибка распознавания. Declined — это внутреннее финальное решение. Разделение улучшает UX повторной попытки, снижает число обращений в поддержку и делает очереди понятнее для команды.

Не активируйте счёт напрямую из webhook

Webhook от провайдера — важный асинхронный сигнал, но не единственная команда для включения функций аккаунта. Событие может прийти повторно, с задержкой, в неожиданном порядке или временно не прийти вовсе. Endpoint должен проверять подпись, сохранять ограниченную запись raw event, дедуплицировать по ID события и обрабатываться идемпотентно. После этого фоновый обработчик обновляет попытку верификации, применяет внутренние правила маршрутизации и ставит пересчёт capabilities в очередь.

Например, два одинаковых события “verified” не должны отправить два письма об одобрении, дважды создать wallet или породить противоречивые записи аудита. Решение оператора также должно быть защищено от гонок: решение, запись аудита и дальнейшее уведомление должны выполняться контролируемо — одной транзакцией или через восстанавливаемый outbox. Такая дисциплина нужна и для других критичных FinTech-процессов.

Очередь ручной проверки должна быть рабочим инструментом

FinTech verification queue — не просто таблица с фильтрами. Сотруднику нужен контекст для авторизованного решения без переключения между таблицами, чатами и кабинетом провайдера. Карточка кейса должна объединять ID клиента и счёта, тип счёта, актуальную и предыдущие попытки, результат и коды причин провайдера, открытые запросы клиенту, возраст очереди, разрешённый операционный контекст и полную историю аудита.

Что включить в очередь до начала разработки

  • Фильтрацию и сортировку по приоритету, возрасту, сегменту, статусу попытки и категории причины.
  • Атомарный action claim, чтобы два сотрудника не приняли решение по одному кейсу параллельно.
  • Явные действия: approve, decline, request information, reassign и escalate.
  • Стандартизированные внутренние коды причин и отдельные безопасные шаблоны сообщений клиенту.
  • ID сотрудника, время, версию правила и snapshot состояния до и после решения.
  • Отдельные поля для внутренних заметок и сообщений, доступных клиенту.
  • Ролевой доступ к чувствительным данным и документам.

Для выбранных исключений можно разделить решение reviewer и полномочие на окончательную активацию. Это поддерживает принцип maker-checker, не утяжеляя стандартные кейсы. Удобство операционного интерфейса критично: сложным экранам нужны ясная иерархия, безопасные default-значения и понятные подтверждения. В рамках UI/UX и продуктового дизайна POLADO помогает превратить реальный путь сотрудника в понятные инструменты, а не в шаблонный dashboard.

Ограничивайте действия безопасно, но не замораживайте весь путь клиента

Цель — не отключить всё до окончания последней проверки, а дать клиенту полезный и наименее рискованный функционал на его стадии. Черновой аккаунт может заполнять профиль или использовать demo-среду. Клиент со статусом processing может продолжить онбординг и обратиться в поддержку, но не должен отправлять live order, пополнять счёт или инициировать вывод. Экран action required обязан объяснять конкретное следующее действие, а не оставлять пользователя с сообщением «проверка не пройдена».

Ограничения должны исполняться на сервере. Скрытая кнопка в web- или mobile-интерфейсе не является контролем активации. API для ордеров, пополнений, выводов и управления счётом должны проверять capability policy при каждом защищённом запросе. Так устаревшая сессия, старая версия приложения или прямой API-вызов не обойдут логику онбординга.

Аудит без превращения логов в хранилище PII

Для каждого значимого перехода сохраняйте тип и ID сущности, тип актора — клиент, оператор, система или webhook, — его ID, correlation ID, старое и новое состояние, код причины, версию правила, время и связанный внешний event ID. Неизменяемая история событий вместе с отдельно поддерживаемой проекцией текущего статуса помогает в расследованиях, сверке и безопасной повторной обработке.

Не записывайте изображения документов, полные идентификационные данные и raw payload провайдера в обычные application logs. Ограничивайте доступ к чувствительным данным, аудируйте сам доступ и заранее определяйте retention и redaction совместно с внутренними владельцами процесса и выбранным поставщиком. Конкретные юридические и регуляторные обязанности зависят от продукта и юрисдикции; этот материал посвящён инженерной архитектуре и не является юридической консультацией.

Чек-лист перед релизом

  • Повторные, задержанные и пришедшие не по порядку события обрабатываются без изменения ожидаемого результата?
  • Временная недоступность провайдера создаёт восстанавливаемое состояние, а не ошибочный decline?
  • Новая попытка корректно заменяет старую, не перезаписывая валидное решение?
  • Могут ли два оператора одновременно взять или одобрить один кейс?
  • Заблокированы ли сервером live orders, funding и withdrawals до включения соответствующих capabilities?
  • Может ли оператор объяснить принятое решение только по audit trail?
  • Может ли support подсказать следующий шаг без лишнего доступа к чувствительным данным?
  • Покрыты ли тестами retry, expiration, cancellation и ручная проверка?

Если вы планируете onboarding для брокерского или trading-продукта, начните не с формы документа, а с машины состояний, матрицы capabilities, очереди исключений, integration contract и сценариев сбоев. POLADO может провести аудит текущего flow либо спроектировать клиентскую, back-office и API-архитектуру нового продукта. Чтобы обсудить задачу, свяжитесь с нашей командой.