---
title: Интеграция Web-приложения
description: Как реализовать интеграцию контракта Web & SDK на стороне клиента — редиректы и настройка iFrame SDK.
canonical: https://developer.unico.io/ru/dual-api/developers/sdks-and-tools/web/web-integration/
locale: ru
generated_by: markdown-export
---

На этой странице описано, как работают сценарии Unico и какие модели интеграции доступны для их
встраивания в приложение.

**Сценарий** — это последовательность шагов, которые пользователь проходит для завершения проверки
личности. Например: сделать фотографию документа и выполнить захват лица (Проверка живости).

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

:::tip[Выбор подхода к интеграции]

- **Web SDK** (пакет `unico-webframe`): используйте, когда ваш бэкенд уже управляет процессом
  проверки личности и вам нужен только клиентский компонент захвата. Возвращает `base64` +
  зашифрованный JWT прямо в ваш callback; вызовы API вы выполняете сами.
- **Web App Integration** (пакет `idpay-b2b-sdk`): используйте, когда хотите, чтобы Unico
  оркестрировал весь сценарий (многошаговые потоки, захват документа + Проверка живости). Пакет
  `idpay-b2b-sdk` обеспечивает встроенную модель **Journeys SDK** (iFrame); модель **Прямой доступ**
  (редирект) не требует библиотеки.
  :::

## Две модели интеграции

У каждого клиента свои потребности. Unico предлагает **две модели** для направления пользователя к
сценарию.

| Модель             | Подходит для                                                                                                          |
| ------------------ | --------------------------------------------------------------------------------------------------------------------- |
| **Прямой доступ**  | Мобильные приложения, уже использующие WebView, или веб-потоки, где сценарий может выполняться вне основной страницы   |
| **Journeys SDK**   | Веб-приложения, которым нужен интегрированный и бесшовный опыт с сохранением пользователя в той же среде               |

### Прямой доступ

Пользователь **перенаправляется на размещённую Unico ссылку**, где выполняется сценарий. После
завершения он возвращается на URL, заданный при создании процесса (параметр `callbackUri`).

Это самый простой в применении подход: он не требует установки библиотек и хорошо подходит, когда
сценарию не нужно выполняться внутри собственной страницы приложения. С другой стороны, вывод
пользователя за пределы среды клиента обычно создаёт больше трений и, как следствие, более высокий
процент отказов.

После создания процесса ответ API содержит URL размещённого Unico сценария. Есть два
распространённых способа направить к нему пользователя:

- **Стандартный редирект.** Пользователь перенаправляется напрямую на URL сценария. После
  завершения Unico возвращает его на `callbackUri`, заданный при создании процесса.
- **Новая вкладка с `window.open()`.** Сценарий открывается в новой вкладке браузера, оставляя
  пользователя в отдельном контексте. В этом случае рекомендуется отслеживать изменение URL на
  `callbackUri` и закрывать вкладку после завершения процесса. Подробности об API см. в
  [документации MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/open).

```mermaid
sequenceDiagram
    participant Unico as Unico backend service
    participant Backend as Customer backend server
    participant Frontend as Customer frontend application
    participant Hosted as Unico hosted frontend application

    Frontend->>Backend: start kyc flow
    Backend->>Unico: call createProcess
    Unico->>Backend: return Unico process info
    Backend->>Frontend: return Unico process info
    Frontend->>Hosted: redirect user to process url
    Note over Hosted: User journey
    Hosted->>Frontend: redirect user to callback url

    critical Get process result
        Frontend->>Backend: signals that journey was finished
        Backend->>Unico: call getProcess
        opt Webhook
            Note over Backend: In addition to getProcess, you can use the Webhook implementation to ensure a fallback in obtaining the process result.
        end
    end
```

В мобильных приложениях принято использовать **WebView**, чтобы открыть сценарий напрямую, без
дополнительного редиректа. В этом случае `callbackUri` также принимает **deeplink**, что позволяет
по завершении сценария открыть определённый экран в нативном приложении. Достаточно настроить
deeplink как адрес возврата, и операционная система сама направит пользователя в нужное место.

```mermaid
sequenceDiagram
    participant Unico as Unico backend service
    participant Backend as Customer backend server
    participant App as Customer mobile application
    participant Hosted as Unico hosted frontend application

    App->>Backend: start kyc flow
    Backend->>Unico: call createProcess
    Unico->>Backend: return Unico process info
    Backend->>App: return Unico process info
    App->>Hosted: open the process url in a webview
    Note over Hosted: User journey
    Hosted->>App: redirect user to the deeplink (callback url)

    critical Get process result
        App->>Backend: signals that journey was finished
        Backend->>Unico: call getProcess
        opt Webhook
            Note over Backend: In addition to getProcess, you can use the Webhook implementation to ensure a fallback in obtaining the process result.
        end
    end
```

### Journeys SDK

Сценарий выполняется **внутри самого приложения**, не выводя пользователя из его контекста.
**Journeys SDK** устанавливается в приложение и используется для открытия сценария при
необходимости.

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

Unico предоставляет библиотеку JavaScript, совместимую с современными браузерами, которая позволяет
интегрировать сценарий практически в любое приложение всего несколькими строками кода.

#### Совместимость

Библиотека спроектирована так, чтобы без трения вписываться в любой проект, независимо от
используемого стека:

- **Любое веб-приложение.** Распространяется в формате UMD и работает при импорте через современные
  сборщики (такие как webpack или Vite). Совместима с любым фреймворком (React, Angular, Vue) или с
  чистым JavaScript.
- **Современные браузеры.** Библиотека уже включает необходимые полифилы для таких возможностей, как
  Promises и `async/await`, расширяя совместимость и на более старые версии браузеров.
- **Стандартные веб-API.** Сценарий работает на нативных возможностях браузера, без зависимости от
  плагинов или внешних библиотек в проекте.

#### Как SDK работает изнутри

При открытии сценария SDK вставляет iFrame в страницу и с этого момента берёт под контроль весь
визуальный опыт. Экраны, скрипты и ресурсы каждого шага выполняются внутри этого iFrame, с момента
начала пользователем и до завершения процесса.

Это архитектурное решение принято намеренно: изоляция iFrame гарантирует, что сценарий Unico не
вмешивается ни в стили, ни в поведение приложения. Ни один скрипт не утекает во внешний контекст, ни
одно правило CSS не конфликтует со стилями приложения. В результате достигается единообразный опыт
для конечного пользователя и минимальное влияние на продукт клиента.

Поскольку Unico отвечает за создание и управление iFrame, улучшения сценария (будь то
производительность, опыт или проверки) автоматически доставляются всем пользователям без
каких-либо изменений в интегрированном приложении. Интеграция всегда будет работать с лучшими
доступными оптимизациями, без необходимости отслеживать каждое обновление платформы или реагировать
на него.

#### Начало работы

****Шаг 1**: Установка**

Пакет `idpay-b2b-sdk` используется совместно платёжными сценариями IDPay и сценариями проверки
личности. Для сценариев идентификации импортируйте класс `ByUnicoSDK`, как показано в шагах ниже.

```bash
  npm install idpay-b2b-sdk
```

Рекомендуемый способ установки Journeys SDK — через менеджер зависимостей, такой как **npm** или
**yarn**, из пакета, доступного в **npm registry**. Помимо упрощения установки и управления
зависимостями, такой подход даёт чёткий контроль над используемой версией и облегчает обновление
при выходе каждой новой версии.

SDK следует **семантическому версионированию (SemVer)**, то есть обновления patch и minor не вносят
несовместимых изменений. Можно безопасно настроить проект на автоматическое получение этих
обновлений. Изменения, которые могут потребовать доработок интеграции, выносятся в major-версии и
всегда сопровождаются руководством по миграции.

:::tip[Поддерживайте SDK в актуальном состоянии]
Оставаться на последней версии особенно важно по двум причинам. Первая — **безопасность**: патчи
безопасности выпускаются всякий раз, когда выявляются уязвимости или появляется возможность усилить
протокол связи. Использование устаревшей версии означает отказ от этих исправлений и подверженность
потока излишним рискам. Вторая — **стабильность**: исправления ошибок распространяются тем же
способом, и старые версии могут демонстрировать поведение, уже исправленное в более новых выпусках.
:::

Перед началом зарегистрируйте свои домены в команде поддержки Unico. Все домены должны использовать
HTTPS.

****Шаг 2**: Вызовите `init(options)`**

Инициализирует SDK и предварительно загружает скрипты, необходимые для корректной работы сценария,
обеспечивая более плавный опыт для конечного пользователя. Вызывайте его как можно раньше в потоке.

| Параметр | Обязательный | Описание                                         |
| -------- | ------------ | ------------------------------------------------ |
| `token`  | Да           | Токен процесса, возвращаемый API Create Process  |
| `env`    | Нет          | Установите `'uat'` только для тестовых сред       |

```javascript
import { ByUnicoSDK } from 'idpay-b2b-sdk';

ByUnicoSDK.init({
  token,
  // env: 'uat' // только для тестовых сред
});
```

****Шаг 3**: Вызовите `open(options)`**

Отображает iFrame и запускает сценарий для пользователя. С этого момента всё происходит
автоматически внутри iFrame, без необходимости управлять какими-либо промежуточными шагами.

| Параметр                   | Обязательный | Описание                                                        |
| -------------------------- | ------------ | --------------------------------------------------------------- |
| `transactionId`            | Да           | ID процесса, возвращаемый API Create Process                    |
| `token`                    | Да           | Токен процесса, возвращаемый API Create Process                 |
| `onFinish`                 | Да           | Callback, выполняемый при завершении или закрытии сценария      |
| `onWidgetVisibilityChange` | Нет          | Callback, выполняемый при изменении состояния видимости виджета |

Следующее взаимодействие с приложением происходит, когда сценарий завершается, независимо от того,
завершил ли его пользователь или закрыл. В этот момент SDK вызывает callback **`onFinish`**,
переданный как параметр в `open`. После этого приложение может вызвать API **`getProcess`**, чтобы
проверить результат, или дождаться уведомления через **Webhook**, если предпочтителен асинхронный
подход.

Помимо запроса результата, рекомендуется использовать `onFinish` для управления состоянием фронтенда
приложения:

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

:::warning
Callback `onFinish` сигнализирует, что пользователь завершил сценарий, но не гарантирует одобрения.
Процесс мог завершиться отказом по одному из правил проверки Unico. Запрос через `getProcess` или
получение уведомления через Webhook не являются необязательными: это единственные источники
фактического результата, и поведение приложения должно основываться на них. `onFinish` нельзя
использовать изолированно для определения того, был ли пользователь одобрен.
:::

Callback `onFinish` получает объект, описывающий, как завершился сценарий:

| Поле                      | Тип                 | Описание                                                                                    |
| ------------------------- | ------------------- | ------------------------------------------------------------------------------------------- |
| `type`                    | string              | Как завершился сценарий: `'FINISH'` (завершён) или `'CLOSE'` (пользователь закрыл до завершения) |
| `transaction`             | object \| undefined | Присутствует, когда `type` равен `'FINISH'`; `undefined`, когда `type` равен `'CLOSE'`       |
| `transaction.id`          | string              | Идентификатор процесса (тот же `transactionId`, что был передан)                            |
| `transaction.redirectUrl` | string              | URL для перенаправления пользователя после сценария                                         |

Обработка callback **`onWidgetVisibilityChange`** необязательна и может быть нерелевантна для вашего
сценария использования. Он вызывается всякий раз, когда меняется состояние видимости виджета, и
полезен только в одном конкретном случае: некоторые сценарии отображаются с прозрачным фоном,
оставляя страницу приложения видимой за интерфейсом. Приложения, которые показывают собственное
модальное окно во время потока проверки (например, в рамках оркестрации между несколькими
провайдерами KYC), могут в итоге отображать это окно позади виджета Unico, ухудшая визуальный опыт.
В этом случае callback позволяет приложению скрывать любые дополнительные визуальные элементы, пока
сценарий Unico активен, и восстанавливать их по его завершении. Если в вашем приложении нет
интерфейса, который мог бы перекрывать виджет, его можно безопасно не использовать.

```javascript
ByUnicoSDK.open({
  transactionId: '9bc22bac-1e64-49a5-94d6-9e4f8ec9a1bf',
  token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
  onFinish: ({ transaction, type }) => {
    if (type === 'FINISH') {
      // Сценарий завершён (transaction = { id, redirectUrl }): продолжите свой поток здесь.
    }
    // type === 'CLOSE' → пользователь закрыл до завершения;
  },
  // Необязательно: нужно только если ваше приложение показывает интерфейс, способный перекрыть виджет.
  onWidgetVisibilityChange: (visible) => {
    // скрывайте или восстанавливайте своё модальное окно в зависимости от видимости виджета
  },
});

// Чтобы явно закрыть SDK в любой момент:
ByUnicoSDK.close();
```

Приведённая ниже диаграмма последовательности показывает, как использовать SDK и результат API для
настройки iFrame:

```mermaid
sequenceDiagram
    participant Unico as Unico backend service
    participant Backend as Customer backend server
    participant Frontend as Customer frontend application
    participant SDK as ByUnicoSDK

    Frontend->>Backend: start kyc flow
    Backend->>Unico: call createProcess
    Unico->>Backend: return Unico process info
    Backend->>Frontend: return Unico process info
    Note over Frontend: Initialize the Unico journey as soon as it is determined that the KYC flow is required

    critical Unico journey initialization
        Frontend->>SDK: byUnicoSDK.init
        SDK-->>Frontend: validates customer domain and initialize
    end

    critical Unico journey exhibition
        Frontend->>SDK: byUnicoSDK.open
        SDK-->>Frontend: show byUnico experience
    end
    Note over SDK: User journey

    critical Unico journey completion
        SDK-->>Frontend: call onFinish
    end

    critical Get process result
        Frontend->>Backend: signals that journey was finished
        Backend->>Unico: call getProcess
        opt Webhook
            Note over Backend: In addition to getProcess, you can use the Webhook implementation to ensure a fallback in obtaining the process result.
        end
    end
```

#### Примеры приложений

| Язык / Фреймворк | Описание | Репозиторий |
| --------------------- | ------------ | ---------- |
| Angular | PoC на Angular, реализующий Journeys SDK | [GitHub — unico-cbu-poc-angular](https://github.com/unico-labs/unico-cbu-poc-angular) |
| JS Vanilla | PoC на JS Vanilla, реализующий Journeys SDK | [GitHub — unico-cbu-poc-js](https://github.com/unico-labs/unico-cbu-poc-js) |
| React | PoC на React, реализующий Journeys SDK | [GitHub — unico-cbu-poc-react](https://github.com/unico-labs/unico-cbu-poc-react) |
| Vue JS | PoC на Vue JS, реализующий Journeys SDK | [GitHub — unico-cbu-poc-vuejs](https://github.com/unico-labs/unico-cbu-poc-vuejs) |

#### Безопасность

:::note[Область действия этого раздела]
Это обоснование безопасности относится именно к **Web App Integration** (`idpay-b2b-sdk`). **Web
SDK** (`unico-webframe`) использует другую модель: он выполняется полностью в контексте страницы и
[требует CSP](/dual-api/developers/sdks-and-tools/web/web-sdk/installation). Это два разных продукта с
разными архитектурами безопасности.
:::

Безопасность в этой модели построена слоями, начиная с протокола связи между SDK и приложением,
выполняющимся внутри iFrame.

При загрузке сценария обе стороны выполняют **рукопожатие (handshake)** для установления связи. В
ходе этого процесса приложение Unico проверяет источник сообщения внедрения данных, полученного через
`postMessage`, по закрытому списку авторизованных доменов, сегментированному по средам (UAT и PROD).
Сообщения из неутверждённых источников немедленно отбрасываются, что не позволяет встраивать сценарий
на неавторизованных страницах и устраняет поверхность атаки для таких уязвимостей, как
**clickjacking**.

Помимо проверки источника, поток продолжается только при наличии действительного токена транзакции:
одноразового JWT, выпущенного и подписанного бэкендом Unico. Это гарантирует, что даже авторизованный
источник не сможет работать с просроченным, повторно использованным или поддельным токеном.

После рукопожатия токен внедряется в iFrame, и между сторонами больше не передаётся никакой
конфиденциальной информации. Вся остальная связь служит лишь для управления интерфейсом (открытие,
закрытие и переходы между экранами), не позволяя перехватить или раскрыть данные процесса во время
сценария.

Изоляция iFrame также защищает целостность скриптов Unico во время выполнения. Поскольку код
выполняется в контексте, отделённом от страницы, внешние скрипты не могут получить к нему доступ или
изменить его, что гарантирует выполнение сценария ровно так, как он был построен, без вмешательства.

По замыслу CSP не используется в этой модели интеграции. Авторизованные домены являются частью
конфигурации безопасности каждого клиента, и их публичное раскрытие в заголовках могло бы облегчить
злоумышленникам составление карты инфраструктуры. Поскольку идентификация клиента происходит только в
момент `init`, невозможно динамически внедрить эти домены в заголовки до этого момента, что делает
CSP неприменимым без отказа от этой конфиденциальности. Все гарантии безопасности обеспечиваются
протоколом рукопожатия, описанным выше.

#### Устранение неполадок, специфичных для SDK

В этом разделе рассматриваются наиболее частые проблемы, возникающие при интеграции, и рекомендуемые
способы их исследования.

##### Непредвиденное поведение или прерванный поток

Проверьте, не манипулирует ли какой-либо скрипт приложения iFrame напрямую в DOM. SDK создаёт iFrame
и управляет им в `body` страницы, и любое внешнее изменение (области видимости, позиционирования или
атрибутов) может нарушить жизненный цикл сценария и вызвать непредсказуемое поведение.

##### Визуальный опыт отличается от ожидаемого

Проверьте, не переопределяет ли какая-либо глобальная таблица стилей приложения свойства внутри
iFrame. SDK создаёт iFrame и все его внутренние элементы с динамическими ID и классами с префиксом
`unico`, что значительно снижает риск конфликта по селекторам ID или классов. Тем не менее правила
CSS широкой области действия (например, селекторы тегов) могут затрагивать элементы внутри iFrame и
изменять визуальный опыт, предоставляемый пользователю.

##### Файлы библиотеки SDK изменены напрямую

Проверьте, не был ли какой-либо файл библиотеки изменён вне менеджера зависимостей. Библиотекой
следует управлять исключительно через **npm** или **yarn**, без прямого редактирования установленных
файлов. Ручные изменения могут приводить к аномальному, труднодиагностируемому поведению и делают
невозможной помощь со стороны поддержки Unico.

#### Не держите DevTools открытыми во время тестов захвата

Приложение Unico использует Capture SDK (unico-webframe) для захвата лица, который распознаёт открытые DevTools как возможный признак мошенничества и блокирует отправку. Закройте DevTools перед запуском сквозных (end-to-end) тестов захвата.

:::warning[Неподдерживаемые интеграции]
Модели, описанные в этой документации (прямой доступ и Journeys SDK), являются единственными
способами интеграции, официально поддерживаемыми Unico. Интеграции, отклоняющиеся от этих стандартов,
могут вызывать непредвиденное поведение, сбои в потоке безопасности и прерывания сценария и не будут
покрываться поддержкой Unico.

Несколько примеров неподдерживаемых подходов:

- **Встраивание SDK внутрь WebView** в мобильных приложениях. В таких случаях правильный подход —
  использовать модель **прямого доступа**, открывая ссылку сценария напрямую в WebView, без
  задействования Journeys SDK.
- **Загрузка iFrame напрямую через HTML-тег `<iframe>`** без использования Journeys SDK. iFrame —
  это внутренняя деталь реализации SDK, и его нельзя инстанцировать вручную. Правильный подход —
  использовать **Journeys SDK**, который безопасно управляет жизненным циклом iFrame в рамках
  ожидаемых стандартов.

Если есть сомнения, соответствует ли подход поддерживаемому стандарту, обратитесь к документации или
свяжитесь с поддержкой, прежде чем продолжать реализацию.
:::