Вебхук — POST-запрос, который система отправляет на ваш сервер, когда с сессией или анкетой что-то произошло. Так вы узнаёте о результате без постоянного опроса API.
Настройка
Адрес вебхука задаётся в настройках сценария KYC в личном кабинете, поле «Бэкэнд колбэк URL». У каждого сценария свой адрес. Если поле пустое, вебхуки по сценарию не отправляются.
Там же настраиваются:
| Настройка | Что делает |
|---|---|
| Зашифровать тело POST-запроса с помощью секретного ключа | Тело приходит зашифрованным секретным ключом сценария, см. «Шифрование» |
| Не отправлять персональные данные | Из тела убираются распознанные и введённые данные, см. «Режим без персональных данных» |
| Уведомлять только если сессия финализирована | SESSION_COMPLETE приходит один раз, когда сессия завершена окончательно |
| Отправить тестовый запрос | Отправляет пробный запрос на указанный адрес |
Доставка
- Метод
POST, заголовокContent-Type: application/json; charset=utf-8. - Подписи запроса нет. Чтобы убедиться, что запрос пришёл от системы, включите шифрование: расшифровать тело можно только секретным ключом сценария.
- Ожидание ответа — 30 секунд. Код и тело вашего ответа не учитываются.
- Повторной отправки нет. Если вебхук не дошёл, получите актуальное состояние методом API (см. таблицу событий).
- Порядок событий
DATABASE_CHECKS_COMPLETEиSESSION_COMPLETEне гарантирован. - Обрабатывайте события идемпотентно: одно и то же событие по одной сессии может прийти больше одного раза.
События
Тип события — в поле event тела запроса.
| event | Когда приходит | Как получить то же через API |
|---|---|---|
SESSION_COMPLETE | Изменился результат KYC-сессии | kyc/session/status |
DATABASE_CHECKS_COMPLETE | Завершились все проверки сессии по базам данных | kyc/session/databases |
QUESTIONNAIRE_COMPLETE | Пользователь заполнил анкету первого этапа | kyc/questionnaire/sessions |
PD_ERASURE_COMPLETE | Завершено уничтожение персональных данных сессии | kyc/session/erase |
SESSION_COMPLETE
Тело — данные сессии в том же виде, что в ответе kyc/session/status, плюс поле event.
- По умолчанию событие приходит при каждом изменении результата сессии, пока пользователь её проходит. Повторные попытки пользователя дают новые события.
- С настройкой «Уведомлять только если сессия финализирована» событие приходит один раз: когда время жизни сессии истекло (
secondsToLive= 0) или исчерпаны попытки. - Если в сценарии есть проверки по базам данных, итоговое событие приходит после их завершения.
- Поле
faceReference(сравнение с эталонной сессией) приходит во всех режимах.
{
"event": "SESSION_COMPLETE",
"sessionId": "00000000-0000-0000-0000-000000000000",
"schemaId": "00000000-0000-0000-0000-000000000000",
"clientKey": "client-0001",
"status": "success",
"secondsToLive": 0,
"results": []
} Полный список полей — на странице Статус сессии. Значения статусов — на странице Статусы сессии.
DATABASE_CHECKS_COMPLETE
Приходит, когда все проверки сессии по базам данных завершились. По сессии, персональные данные которой уничтожены, не отправляется.
{
"event": "DATABASE_CHECKS_COMPLETE",
"sessionId": "00000000-0000-0000-0000-000000000000",
"schemaId": "00000000-0000-0000-0000-000000000000",
"clientId": "00000000-0000-0000-0000-000000000000",
"results": [
{
"checker": "insolvencyStatus",
"spent": 1230,
"outcome": "performed",
"notPerformedReason": null,
"missingInputs": [],
"passed": true
}
],
"responseTime": "2026-01-01T10:00:00.000Z"
} Поля результата проверки описаны на странице kyc/session/databases. Сначала смотрите outcome, потом passed: пропущенная проверка — не «чисто».
QUESTIONNAIRE_COMPLETE
Приходит, когда пользователь отправил анкету первого этапа (см. Двухэтапная проверка: анкета → KYC). Если в сценарии анкеты есть проверки по базам данных, событие приходит после их завершения и содержит массив checks.
{
"event": "QUESTIONNAIRE_COMPLETE",
"type": "questionnaire",
"questionnaireSessionId": "00000000-0000-0000-0000-000000000000",
"schemaId": "00000000-0000-0000-0000-000000000000",
"clientKey": "client-0001",
"clientUser": "user-0001",
"status": "success",
"createdAt": "2026-01-01T10:00:00.000Z",
"fullName": "Иванов Иван Иванович",
"dob": "1990-01-01",
"email": "user@example.com",
"phone": "+70000000000",
"fields": [
{ "key": "city", "title": "Город", "value": "Москва" }
],
"checks": [
{
"checker": "insolvencyStatus",
"status": "success",
"outcome": "performed",
"notPerformedReason": null,
"missingInputs": [],
"result": { "passed": true }
}
]
} status: "success" означает, что ответы анкеты записаны. Это не решение по пользователю.
PD_ERASURE_COMPLETE
Приходит один раз, когда завершено уничтожение персональных данных сессии: по запросу kyc/session/erase или при удалении сессии в личном кабинете.
{
"event": "PD_ERASURE_COMPLETE",
"sessionId": "00000000-0000-0000-0000-000000000000",
"schemaId": "00000000-0000-0000-0000-000000000000",
"clientKey": "client-0001",
"pdErasedAt": "2026-03-02T10:15:30Z",
"parts": {
"text": { "state": "erased" },
"media": { "state": "erased" },
"person": { "state": "kept", "reason": "linked_session" },
"questionnaire": { "state": "absent" }
},
"responseTime": "2026-03-02T10:15:30Z"
} Если событие потерялось, вызовите kyc/session/erase ещё раз: он ответит erased с тем же pdErasedAt.
Связанные сценарии
Если сессия создана по связанным сценариям, вебхуки приходят на адрес сценария, с которого сессия началась, и шифруются его секретным ключом. В теле есть selectedSchemaId — сценарий, выбранный по документу, или null.
Режим без персональных данных
С настройкой «Не отправлять персональные данные»:
- в
SESSION_COMPLETEнет распознанных данных документов (ocrвresultsиhistory) и данных анкеты: ФИО, даты рождения, email, телефона и значений полей (keyиtitleостаются); - в
QUESTIONNAIRE_COMPLETEнет введённых значений, результаты проверокchecksприходят полностью.
Полные данные можно получить методами API.
Шифрование
Шифрование работает, если включена настройка «Зашифровать тело POST-запроса с помощью секретного ключа» и в сценарии задан «Секретный ключ» — тот же, которым шифруется clientKey.
Тело зашифрованного запроса:
{
"encrypted": "<base64>"
} Как расшифровать:
- Ключ — первые 32 символа шестнадцатеричной строки SHA-256 от секретного ключа сценария.
- Декодируйте
encryptedиз base64. - Первые 16 байт — вектор инициализации (IV), остальное — шифротекст.
- Расшифруйте AES-256-CBC и разберите результат как JSON.
Пример на Node.js
const crypto = require('crypto');
function decryptWebhook(body, secretKey) {
const key = crypto.createHash('sha256').update(secretKey).digest('hex').substring(0, 32);
const buf = Buffer.from(body.encrypted, 'base64');
const decipher = crypto.createDecipheriv('aes-256-cbc', key, buf.subarray(0, 16));
const text = Buffer.concat([decipher.update(buf.subarray(16)), decipher.final()]).toString('utf8');
return JSON.parse(text);
}