Подключение

KYC Widget

Браузерный флоу верификации личности: съёмка документа, селфи и liveness-проверка (антиспуфинг). Есть четыре способа интеграции:

  1. Тег <script> в обычном JavaScript-приложении — window.KYCWidget.setupKYC({...})
  2. npm-пакет kyc-widget-nv в React-приложении — <KycWidget ... />
  3. Тег <script> в React-приложении
  4. Прямая ссылка (без интеграции) — https://kyc.neuro-vision.ru

Перед запуском

❗ Не рекомендуется встраивать Web SDK в <iframe>. Подключайте виджет только в основную страницу сайта — как элемент корневого DOM-документа.

  1. Добавьте домен сайта в разрешённые. В личном кабинете откройте «Доступ» → «Разрешённые домены» и добавьте домены, на которых встраиваете виджет. Виджет работает только на доменах из этого списка и только на сайтах с https. Маска *.example.com разрешает все поддомены example.com, но не сам example.com. Изменения вступают в силу в течение двух минут. Менять список может владелец аккаунта или пользователь с правом делегирования.
  2. Откройте страницу по HTTPS. Браузер даёт доступ к камере только на защищённых страницах.
  3. Не встраивайте виджет в <iframe> (см. предупреждение выше). Если обойтись без фрейма нельзя, разрешите ему камеру: <iframe src="..." allow="camera">. Без этого браузер не даст камеру. Инлайн-режим (mountElementId) внутри iframe не работает — см. таблицу параметров.
  4. Мобильное приложение. Для запуска внутри WebView нужны отдельные настройки приложения — см. Мобильные приложения и WebView.

Язык интерфейса

Параметра языка у виджета нет. Язык выбирается так: сохранённый выбор пользователя в этом браузере → язык браузера → английский. Список ограничен языками, включёнными в сценарии; пользователь может переключить язык в виджете. Всего доступно 29 языков.

Экраны окружения

Если устройство или браузер не подходят, виджет показывает пользователю экран с подсказкой, а не ошибку:

СитуацияЧто видит пользователь
Доступ к камере запрещёнПросьба разрешить доступ к камере на этом устройстве
Камера не поддерживает нужное разрешениеПросьба повторить попытку с более современного устройства
Сценарий не разрешает камеру компьютераQR-код и ссылка, чтобы продолжить проверку на смартфоне
Устройство в горизонтальной ориентацииПросьба повернуть устройство в портретный режим
Нет интернет-соединенияСообщение об отсутствии соединения
Неверные дата или время на устройствеПросьба исправить дату и время
Браузер блокирует проверкуПросьба открыть ссылку в другом браузере или на другом устройстве

Параметры конфигурации

ПараметрТипОбязательныйПо умолчаниюОписание
scenarioIdstringДа*—Уникальный идентификатор сценария из раздела «KYC/AML» личного кабинета (*не требуется при использовании taskId)
clientKeystringДа*—Уникальная строка (максимум 36 символов), которая передаётся в зашифрованном виде; пример кода шифрования доступен в личном кабинете в разделе «KYC/AML» (*не требуется при использовании taskId)
clientUserstringНет—Идентификатор пользователя на стороне клиента, максимум 36 символов. Не обязан быть уникальным: передавайте одно и то же значение в разных сессиях, чтобы потом поиском по нему найти все сессии (попытки) этого пользователя
taskIdstringНет—Идентификатор задачи верификации. Нужен, только если вам выдали ссылку на задачу вида https://kyc.neuro-vision.ru/<taskId>: виджет открывает эту задачу, а scenarioId/clientKey не нужны. При обычной интеграции и для одноразовых ссылок из раздела «KYC Ссылки» используются scenarioId и clientKey
isOpenbooleanДа*—Видимость виджета (*обязателен только для React-компонента)
themestringНетиз настроек сценарияТема оформления: light или dark
stickySessionbooleanНетfalse«Липкие» сессии: виджет запоминает clientKey для сценария (в localStorage, на 15 минут). Повторное открытие в этом окне продолжает предыдущую сессию, даже если передан другой clientKey
closeCbfunctionНет—Вызывается при закрытии виджета: кнопкой ×, кнопкой возврата на экране результата (при любом итоге) или при сбое виджета. Не вызывается при повторном setupKYC (прежний экземпляр заменяется без колбэка) и если элемента с mountElementId нет на странице
successCbfunctionНет—Вызывается один раз и только при итоге success, когда виджет показывает экран результата: окно в этот момент ещё открыто. Получает результат сессии в виде JSON-строки. Про остальные итоги — раздел «Как получить итог проверки»
finalizedCbfunctionНет—Колбэк при открытии виджета для сессии, которая уже была финализирована ранее. Получает { status }
topOffsetnumberНет0Отступ сверху в пикселях
bottomOffsetnumberНет0Отступ снизу в пикселях
blurHostbooleanНетfalseЕсли true, фон виджета рендерится как «матовое стекло» поверх страницы хоста (без фоновой картинки и правой blur-панели) — страница хоста просвечивает через полупрозрачный размытый слой
mountElementIdstringНет—Только для интеграции через script-тег (widget-lib.js). Если задан, виджет монтируется инлайн внутрь элемента с этим id, а не поверх всей страницы. Виджет заполняет хост-элемент (width/height: 100%), поэтому задайте элементу явные размеры. См. пример ниже. Не поддерживается внутри cross-origin iframe — браузер заблокирует камеру; в этом случае вызывается closeCb, чтобы хост мог сбросить своё состояние. Не вызывайте setupKYC внутри closeCb — повторные детекты iframe зациклятся. Если элемента с таким id нет в DOM, виджет молча не запускается: окна нет, closeCb не вызывается

Payload колбэка successCb

successCb получает результат верификации в виде JSON-строки. Точный набор полей зависит от шагов сценария (шаг с документом приходит как "type": "document", liveness — как "type": "liveness" и т.д.). Поле schemaId в результате — идентификатор сценария, тот же, что scenarioId. Сокращённый пример:

{
  "sessionId": "098d57-...",
  "status": "success",
  "errors": [],
  "results": [
    {
      "type": "liveness",
      "status": "success",
      "errors": [],
      "tries": 1,
      "startedAt": "2026-07-19T09:41:37.590Z",
      "faces": ["https://..."],
      "video": "https://..."
    }
  ],
  "schemaId": "3676-...",
  "clientKey": "46d1c-...",
  "clientUser": "",
  "createdAt": "2026-07-19T09:41:37.000Z",
  "secondsToLive": 0
}

Жизненный цикл виджета

  • Функции закрытия или уничтожения виджета нет: пользователь закрывает его сам — кнопкой × или кнопкой возврата на экране результата.
  • Повторный вызов setupKYC, пока виджет открыт, заменяет открытый экземпляр новым; closeCb у прежнего не вызывается. Не вызывайте setupKYC повторно, пока виджет открыт.
  • Если виджет монтировался в элемент (mountElementId), содержимое элемента очищается при закрытии.

Как получить итог проверки

  • successCb приходит только при итоге success. Он не означает, что окно закрыто: пользователь ещё видит экран результата.
  • Любой другой итог (отказ, ошибка, пользователь закрыл виджет) колбэком не приходит: срабатывает только closeCb, без статуса. Итог сессии в этом случае берите из вебхука или запросом статуса сессии.
  • Решение о прохождении проверки принимайте на сервере по вебхуку или статусу сессии, а не по колбэкам в браузере.

1. Пример интеграции в JavaScript-приложение через script-тег (index.html)

  1. Создайте кнопку с начальным состоянием загрузки.
  2. Загрузите скрипт динамически и активируйте кнопку по готовности.
  3. Вызовите window.KYCWidget.setupKYC() по клику на кнопку.

Файл: index.html

<body>
    <button id="btn" disabled>Загрузка...</button>

    <script>
      const btn = document.getElementById("btn");

      const script = document.createElement("script");
      script.src = "https://kyc.neuro-vision.ru/lib/widget-lib.js";
      script.onload = () => {
        btn.disabled = false;
        btn.textContent = "Открыть KYC-виджет";
      };
      script.onerror = () => {
        btn.textContent = "Не удалось загрузить KYC-виджет";
      };
      document.body.appendChild(script);

      const openWidget = () => {
        window.KYCWidget.setupKYC({
          scenarioId: "scenarioId",
          clientKey: "clientKey",
          clientUser: "clientUser",
          theme: "light",
          stickySession: true,
          topOffset: 0,
          bottomOffset: 0,
          // Необязательный. Если задан, виджет монтируется ВНУТРЬ элемента
          // с этим id (инлайн-блок), а не поверх всей страницы. Элемент
          // должен существовать в DOM. При закрытии элемент очищается.
          // ⚠️ Не открывайте страницу хоста внутри cross-origin <iframe> —
          // браузер заблокирует getUserMedia, и камера не запустится.
          // mountElementId: "kyc-here",
          closeCb: () => console.log("CLOSE CALLBACK"),
          successCb: (sessionJson) => console.log("SUCCESS CALLBACK", sessionJson),
          finalizedCb: ({ status }) => console.log("FINALIZED CALLBACK", status),
        });
      };

      btn.addEventListener("click", openWidget);
    </script>
  </body>

2. Пример интеграции в React-приложение через npm-пакет

  1. Установите npm-пакет kyc-widget-nv: npm i kyc-widget-nv.
  2. Импортируйте в приложение: import { KycWidget } from "kyc-widget-nv".
  3. Заведите переменную состояния для управления видимостью виджета.
  4. Передайте пропсы компоненту KycWidget (см. «Параметры конфигурации» выше).

Пакет не включает React в бандл — react и react-dom должны быть установлены в вашем приложении.

Файл: App.js

import { useState } from "react";
import { KycWidget } from "kyc-widget-nv";

function App() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <>
      <button onClick={() => setIsOpen(true)}>Открыть</button>

      <KycWidget
        scenarioId="scenarioId"
        clientKey="clientKey"
        clientUser="clientUser"
        isOpen={isOpen}
        stickySession={true}
        theme="light"
        topOffset={0}
        bottomOffset={0}
        closeCb={() => setIsOpen(false)}
        successCb={(sessionJson) => console.log("SUCCESS CALLBACK", sessionJson)}
        finalizedCb={({ status }) => console.log("FINALIZED CALLBACK", status)}
      />

    </>
  );
}

export default App;

3. Пример интеграции в React-приложение через script-тег

Используйте этот способ, если не можете установить npm-пакет и нужно загрузить виджет через script-тег.

  1. Загрузите скрипт виджета динамически в useEffect.
  2. Отслеживайте состояние загрузки через useState.
  3. Показывайте кнопку только после загрузки скрипта.
  4. Вызовите window.KYCWidget.setupKYC() по клику на кнопку.

Файл: App.js

import { useState, useEffect, useCallback } from "react";

function App() {
  const [widgetLoaded, setWidgetLoaded] = useState(false);

  const openWidgetHandler = () => {
    window.KYCWidget.setupKYC({
      scenarioId: "scenarioId",
      clientKey: "clientKey",
      clientUser: "clientUser",
      theme: "light",
      topOffset: 0,
      bottomOffset: 0,
      // Необязательный. Если задан, виджет монтируется ВНУТРЬ элемента
      // с этим id (инлайн-блок), а не поверх всей страницы. Элемент
      // должен существовать в DOM. При закрытии элемент очищается.
      // ⚠️ Не открывайте страницу хоста внутри cross-origin <iframe> —
      // браузер заблокирует getUserMedia, и камера не запустится.
      // mountElementId: "kyc-here",
      closeCb: () => console.log("CLOSE CALLBACK"),
      successCb: (sessionJson) => console.log("SUCCESS CALLBACK", sessionJson),
      finalizedCb: ({ status }) => console.log("FINALIZED CALLBACK", status),
    });
  };

  const loadWidgetScript = useCallback(() => {
    const widgetScript = document.getElementById("kyc-widget-script");
    if (widgetScript) return;

    const script = document.createElement("script");
    script.id = "kyc-widget-script";
    script.src = 'https://kyc.neuro-vision.ru/lib/widget-lib.js';
    script.defer = true;
    script.crossOrigin = "anonymous";

    script.onload = () => {
      setWidgetLoaded(true);
    };

    script.onerror = () => {
      console.error("Не удалось загрузить скрипт KYC-виджета");
    };

    document.head.appendChild(script);
  }, []);

  useEffect(() => {
    if (window.KYCWidget) {
      setWidgetLoaded(true);
      return;
    }

    loadWidgetScript();
  }, [loadWidgetScript]);

  return (
    <>
      {widgetLoaded && (
        <button onClick={openWidgetHandler}>Открыть KYC-виджет</button>
      )}
    </>
  );
}

export default App;

4. Верификация по ссылке

Для прохождения верификации можно воспользоваться сервисом https://kyc.neuro-vision.ru напрямую.

Переход по ссылке следующего вида создаёт сессию:

https://kyc.neuro-vision.ru/scenarioId/encrypted(clientKey)
https://kyc.neuro-vision.ru/scenarioId/encrypted(clientKey)/clientUser
  • scenarioId: уникальный идентификатор сценария, его нужно получить в личном кабинете в разделе «KYC/AML».
  • clientKey: уникальная строка (максимум 36 символов), которая передаётся в зашифрованном виде; пример кода шифрования доступен в личном кабинете в разделе «KYC/AML». Зашифрованный ключ — это base64 (может содержать / и +), поэтому при построении ссылки его нужно URL-энкодить.
  • clientUser: необязательный. Идентификатор пользователя на стороне клиента, максимум 36 символов. Не обязан быть уникальным — передавайте одно значение в разных сессиях, чтобы потом найти все сессии (попытки) этого пользователя.

Одноразовые ссылки с ограниченным сроком и числом переходов создаются в личном кабинете, раздел «KYC Ссылки».

Возврат на сайт после проверки

Если в основных настройках сценария задан «URL-адрес мобильного перенаправления в случае успеха», виджет, открытый по прямой ссылке, возвращает пользователя на этот адрес и дописывает параметры ?sessionId=<id сессии>&status=<итоговый статус>:

  • при итоге success — автоматически через 5 секунд;
  • при любом итоге — по кнопке возврата на экране результата.

При встраивании на ваш сайт (setupKYC, npm-пакет) перенаправления нет: кнопка возврата закрывает виджет и вызывает closeCb. Статус из адреса возврата служит подсказкой для интерфейса; итог проверяйте на сервере.

Ссылка на задачу

Если вам выдали ссылку на задачу верификации, она имеет вид:

https://kyc.neuro-vision.ru/taskId
https://kyc.neuro-vision.ru/taskId/cu/clientUser