Web App Integration
This page describes how the Unico journeys work and the available integration models for embedding them into an application.
A journey is the set of steps the user goes through to complete an identity verification. For example: capturing a document photo and performing a facial capture (liveness).
Unico manages the entire experience. The integration effort is minimal: the journey is created via CreateProcess, the user is directed to it, and the result is received at the end. Everything in between — screens, instructions, validations — is already built and maintained by Unico.
- Web SDK (
unico-webframepackage) — use when your back-end already controls the identity verification flow and only needs the client-side capture component. Returnsbase64+ encrypted JWT directly to your callback; you manage the API calls. - Web App Integration (
idpay-b2b-sdkpackage) — use when you want Unico to orchestrate the full journey (multi-step flows, document capture + liveness). Theidpay-b2b-sdkpackage powers the embedded Journeys SDK (iFrame) model; the Direct access (redirect) model needs no library.
Two integration models
Each client has different needs. Unico offers two models for directing the user to the journey.
| Model | Best for |
|---|---|
| Direct access | Mobile applications that already use WebView, or web flows where the journey can happen outside the main page |
| Journeys SDK | Web applications that need an integrated, seamless experience, keeping the user within the same environment |
- Direct access
- Journeys SDK
The user is redirected to a Unico-hosted link, where the journey takes place. Upon completion,
they are returned to the URL defined during process creation (the callbackUri parameter).
This is the simplest approach to adopt: it requires no library installation and works well when the journey does not need to happen inside the application's own page. On the other hand, taking the user outside the client's environment tends to introduce more friction and, consequently, a higher drop-off rate.
After creating a process, the API response includes the URL of the Unico-hosted journey. There are two common ways to direct the user to it:
- Standard redirect. The user is redirected directly to the journey URL. Upon completion,
Unico redirects them back to the
callbackUridefined during process creation. - New tab with
window.open(). The journey is opened in a new browser tab, keeping the user in a separate context. In this case, it is recommended to monitor for a URL change to thecallbackUriand close the tab once the process is complete. See the MDN documentation for details on the API.

In mobile applications, it is common to use a WebView to open the journey directly, with no
additional redirect needed. In this case, the callbackUri also accepts a deeplink, allowing
the journey's completion to trigger the opening of a specific screen in the native application.
Simply configure the deeplink as the return destination and the operating system handles routing
the user to the right place.

The journey takes place inside the application itself, without taking the user out of their context. The Journeys SDK is installed in the application and used to open the journey when needed.
This is the recommended path for a more integrated and seamless experience, keeping the user in the same environment throughout, which tends to reduce friction and drop-off across the flow.
Unico provides a JavaScript library compatible with modern browsers, allowing the journey to be integrated into virtually any application with just a few lines of code.
Compatibility
The library is designed to fit into any project without friction, regardless of the stack in use:
- Any web application. Distributed in UMD format, it works when imported through modern bundlers (such as webpack or Vite). Compatible with any framework (React, Angular, Vue) or plain JavaScript.
- Modern browsers. The library already includes the necessary polyfills for features like
Promises and
async/await, extending compatibility to older browser versions as well. - Standard web APIs. The journey runs on native browser capabilities, with no dependency on plugins or external libraries in the project.
How the SDK works internally
When a journey is opened, the SDK inserts an iFrame into the page and takes control of the entire visual experience from that point on. The screens, scripts, and assets for each step run inside this iFrame, from the moment the user begins through to the completion of the process.
This architectural decision is intentional: iFrame isolation ensures the Unico journey does not interfere with the application's styles or behavior. No script leaks into the external context, no CSS rule collides with the application's own styles. The result is a consistent experience for the end user and minimal impact on the client's product.
Since Unico is responsible for creating and managing the iFrame, journey improvements — whether in performance, experience, or validation — are delivered automatically to all users, with no changes required in the integrated application. The integration will always run with the best available optimizations, without needing to track or react to every platform update.
Getting started
Step 1 — Installation
The idpay-b2b-sdk package is shared between IDPay payment journeys and identity verification
journeys. For identity use cases, import the ByUnicoSDK class as shown in the steps below.
npm install idpay-b2b-sdk
The recommended way to install the Journeys SDK is through a package manager such as npm or yarn, from the package available on the npm registry. In addition to simplifying installation and dependency management, this approach provides clear control over the version in use and makes it straightforward to update whenever a new version is published.
The SDK follows Semantic Versioning (SemVer), meaning patch and minor updates do not introduce breaking changes. It is safe to configure the project to receive these updates automatically. Changes that may require integration updates are reserved for major versions and always come with a migration guide.
Staying on the latest version is especially important for two reasons. The first is security: security patches are published whenever vulnerabilities are identified or opportunities to strengthen the communication protocol arise. Running an outdated version means missing these fixes and exposing the flow to unnecessary risk. The second is stability: bug fixes are distributed the same way, and older versions may exhibit behaviors that have already been resolved in more recent releases.
Before getting started, register your domains with the Unico support team. All domains must use HTTPS.
Step 2 — Call init(options)
Initializes the SDK and pre-loads the scripts necessary for the journey to function correctly, creating a smoother experience for the end user. Call this as early as possible in the flow.
| Parameter | Required | Description |
|---|---|---|
token | Yes | Process token returned by the Create Process API |
env | No | Set to 'uat' for test environments only |
import { ByUnicoSDK } from 'idpay-b2b-sdk';
ByUnicoSDK.init({
token,
// env: 'uat' // only for test environments
});
Step 3 — Call open(options)
Displays the iFrame and starts the journey for the user. From this point on, everything happens automatically inside the iFrame, with no need to manage any intermediate step.
| Parameter | Required | Description |
|---|---|---|
transactionId | Yes | Process ID returned by the Create Process API |
token | Yes | Process token returned by the Create Process API |
onFinish | Yes | Callback executed when the journey ends or is closed |
onWidgetVisibilityChange | No | Callback executed when the widget visibility state changes |
The next interaction with the application occurs when the journey ends, whether the user
completed it or closed it. At that point, the SDK invokes the onFinish callback, passed as
a parameter in open. From there, the application can call the getProcess API to check the
result, or wait for a Webhook notification if an asynchronous approach is preferred.
In addition to querying the result, it is recommended to use onFinish to handle the
application's front-end state:
- Avoid loops. Prevent the immediate and unnecessary recreation of processes in case the user triggers the flow again right after the journey ends.
- Flow management. Ensure the user is directed to the next step of the application, avoiding a dead-end screen after the journey closes.
The onFinish callback signals that the user has completed the journey, but does not guarantee
approval. The process may have ended with a failure on one of the Unico validation rules.
Querying via getProcess or receiving the Webhook notification is not optional: these are the
only sources of the actual result, and the application's behavior must be based on them. onFinish
must not be used in isolation to determine whether a user was approved.
The onFinish callback receives an object describing how the journey ended:
| Field | Type | Description |
|---|---|---|
type | string | How the journey ended: 'FINISH' (completed) or 'CLOSE' (user closed before finishing) |
transaction | object | undefined | Present when type is 'FINISH'; undefined when type is 'CLOSE' |
transaction.id | string | Process identifier (same as transactionId passed in) |
transaction.redirectUrl | string | URL to redirect the user after the journey |
Handling the onWidgetVisibilityChange callback is optional and may not be relevant to your
use case. It is invoked whenever the widget's visibility state changes, and is useful only in a
specific scenario: some journeys display a transparent background, keeping the application page
visible behind the experience. Applications that show a custom modal during the verification flow
(for example, as part of an orchestration across multiple KYC providers) may end up displaying
that modal behind the Unico widget, degrading the visual experience. In that case, the callback
lets the application suppress any additional visual elements while the Unico journey is active,
and restore them once it ends. If your application has no UI that could overlap the widget, you
can safely omit it.
ByUnicoSDK.open({
transactionId: '9bc22bac-1e64-49a5-94d6-9e4f8ec9a1bf',
token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
onFinish: ({ transaction, type }) => {
if (type === 'FINISH') {
// Journey completed (transaction = { id, redirectUrl }) — continue your flow here.
}
// type === 'CLOSE' → user closed before finishing;
},
// Optional: only needed if your app shows UI that could overlap the widget.
onWidgetVisibilityChange: (visible) => {
// suppress or restore your modal based on widget visibility
},
});
// To close the SDK explicitly at any point:
ByUnicoSDK.close();
The sequence diagram below demonstrates how to use the SDK and the API result to configure the iFrame:

Security
This security rationale applies specifically to the Web App Integration (idpay-b2b-sdk). The
Web SDK (unico-webframe) uses a different model — it runs entirely in the page context and
does require a CSP. These are two distinct
products with different security architectures.
Security in this model is built in layers, starting with the communication protocol between the SDK and the application running inside the iFrame.
When the journey is loaded, both parties perform a handshake to establish communication. In
this process, the Unico application validates the origin of the data injection message received via postMessage
against a closed list of authorized domains, segmented by environment (UAT and PROD). Messages
from non-approved origins are discarded immediately, preventing the journey from being embedded in
unauthorized pages and eliminating the attack surface for vulnerabilities such as clickjacking.
In addition to origin validation, the flow only proceeds with a valid transaction token: a single-use JWT, issued and signed by the Unico backend. This ensures that even an authorized origin cannot operate with an expired, reused, or forged token.
After the handshake, the token is injected into the iFrame and no sensitive information flows between the two parties. All remaining communication serves only for interface control — opening, closing, and screen transitions — preventing process data from being intercepted or leaked during the journey.
The iFrame isolation also protects the integrity of the Unico scripts at runtime. Since the code runs in a context separate from the page, it cannot be accessed or modified by external scripts, ensuring the journey executes exactly as built, without interference.
By design, CSP is not adopted in this integration model. The authorized domains are part of each
client's security configuration, and their public exposure in headers could facilitate infrastructure
mapping by malicious actors. Since client identification only happens at the time of init, it is
not possible to inject these domains dynamically into the headers before that point, making CSP
unviable without giving up this privacy. All security guarantees are provided by the handshake
protocol described above.
SDK-specific troubleshooting
This section covers the most common issues encountered during integration and the recommended ways to investigate them.
Unexpected behavior or broken flow
Check whether any application script is directly manipulating the iFrame in the DOM. The SDK
creates and manages the iFrame in the page body, and any external modification — whether to
scope, positioning, or attributes — can interfere with the journey's lifecycle and cause
unpredictable behavior.
Visual experience different from expected
Check whether any global stylesheet in the application is overriding properties inside the iFrame.
The SDK creates the iFrame and all its internal elements with dynamic IDs and classes prefixed with
unico, which significantly reduces the risk of conflict via ID or class selectors. Even so, broad
CSS rules — such as tag selectors — can reach elements inside the iFrame and alter the visual
experience delivered to the user.
SDK library files modified directly
Check whether any library file has been modified outside the package manager. The library must be managed exclusively via npm or yarn, with no direct edits to installed files. Manual modifications can produce anomalous behavior that is difficult to reproduce and will prevent Unico support from being able to assist.
Do not keep DevTools open during capture tests
The Unico application uses the Capture SDK (unico-webframe) for facial capture, which detects open DevTools as a potential fraud signal and blocks the submission. Close DevTools before running end-to-end capture tests.
The models described in this documentation — direct access and Journeys SDK — are the only integration approaches officially supported by Unico. Integrations that deviate from these standards may cause unexpected behavior, security flow failures, and journey interruptions, and will not be covered by Unico support.
Examples of unsupported approaches:
- Embedding the SDK inside a WebView in mobile applications. In these cases, the correct approach is to use the direct access model, opening the journey link directly in the WebView without involving the Journeys SDK.
- Loading the iFrame directly via an
<iframe>HTML tag, without going through the Journeys SDK. The iFrame is an internal implementation detail of the SDK and must not be instantiated manually. The correct approach is to use the Journeys SDK, which manages the iFrame lifecycle securely and within the expected standards.
If there is any doubt about whether an approach is within the supported standard, consult the documentation or contact support before proceeding with the implementation.