Skip to main content

Overview

The split flow uses the OCR and Biometrics components separately instead of the combined IDV flow. This gives you full control over the journey between document capture and facial verification — you can customize loading states, handle OCR results before proceeding to biometrics, and optionally insert a review screen between the two. Modules used: ocr, biometrics, form (WELCOME, CONSENT, DOCUMENT, LOADING screens)
Instead of building from scratch, fork an existing flow from the public sample codes.
Daon provider: Document selection and the documents parameter are not required when using the Daon provider — Daon provides its own document type selection screen. To use custom document selection instead of Daon’s built-in screen, contact your FrankieOne account team.

Flow Diagram

1

Welcome Screen

Initial greeting and introduction to the verification process.
2

Consent Screen

Capture user consent for data processing.
3

Document Selection

User selects the type of document to capture.
4

OCR Capture

Camera-based document capture and data extraction.
5

Biometrics Capture

Facial verification via selfie capture.
6

Result

Verification outcome displayed.

Full Implementation

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>OneSDK Split Flow</title>
    <script src="https://assets.frankiefinancial.io/one-sdk/v1/oneSdk.umd.js"></script>
    <style>
      body { margin: 0; font-family: sans-serif; background: #fff; }
      #onesdk-wrapper { position: relative; width: 100%; height: 100vh; }
      #onesdk-container { width: 100%; height: 100%; }
      #loading-overlay {
        position: absolute; top: 0; left: 0; width: 100%; height: 100%;
        z-index: 10; background: #fff;
      }
    </style>
  </head>
  <body>
    <div id="onesdk-wrapper">
      <div id="onesdk-container"></div>
      <div id="loading-overlay"></div>
    </div>

    <script>
      async function startOneSDK() {
        try {
          // 1. Generate session token (move to your backend in production)
          const tokenResponse = await fetch(
            "https://backend.kycaml.uat.frankiefinancial.io/auth/v2/machine-session",
            {
              method: "POST",
              headers: {
                authorization: "machine " + btoa("<CUSTOMER_ID>:<CUSTOMER_CHILD_ID>:<API_KEY>"),
                "Content-Type": "application/json",
              },
              body: JSON.stringify({
                permissions: {
                  preset: "one-sdk",
                  reference: "split-" + Date.now(),
                },
              }),
            }
          );
          const session = await tokenResponse.json();

          // 2. Initialize OneSDK
          const oneSdk = await OneSDK({
            session: session,
            mode: "development",
            recipe: {
              ocr: {
                maxDocumentCount: 3,
              },
              form: {
                provider: { name: "react" },
              },
            },
          });

          const appContainer = "#onesdk-container";

          // 3. Create form components
          const welcome = oneSdk.component("form", {
            name: "WELCOME",
            type: "ocr",
          });

          const consent = oneSdk.component("form", { name: "CONSENT" });

          const documentForm = oneSdk.component("form", {
            name: "DOCUMENT",
            showPreps: true,
          });

          const loading = oneSdk.component("form", {
            name: "LOADING",
            title: { label: "Loading..." },
            descriptions: [{ label: "" }],
          });

          const biometrics = oneSdk.component("biometrics");

          // 4. Wire up form navigation
          welcome.mount(appContainer);

          welcome.on("form:welcome:ready", () => {
            consent.mount(appContainer);
          });

          consent.on("form:consent:ready", () => {
            documentForm.mount(appContainer);
          });

          // 5. Handle document selection → OCR capture
          documentForm.on("form:document:ready", ({ inputInfo }) => {
            loading.mount("#loading-overlay");
            const docType = inputInfo.documentType;

            const ocr = oneSdk.component("ocr", {
              documents: [{ type: docType, countries: ["AUS"] }],
            });

            ocr.mount(appContainer);

            ocr.on("loading", (isLoading) => {
              if (!isLoading) {
                loading.unmount();
              }
            });

            ocr.on("error", (err) => {
              console.error("OCR error:", err);
            });

            // 6. Handle OCR results → Biometrics
            ocr.on("results", ({ document }) => {
              if (document) {
                loading.mount("#loading-overlay");
                biometrics.mount(appContainer);
              }
            });
          });

          // 7. Handle biometrics
          let biometricsError = false;

          biometrics.on("detection_failed", () => {
            biometricsError = true;
          });

          biometrics.on("session_closed", () => {
            if (biometricsError) {
              biometrics.mount(appContainer);
              biometricsError = false;
            }
          });

          biometrics.on("loading", (isLoading) => {
            if (!isLoading) {
              loading.unmount();
            }
          });

          biometrics.on("results", (result) => {
            document.getElementById("onesdk-container").innerHTML =
              "<h2>Verification complete</h2>";
          });

          biometrics.on("error", (err) => {
            console.error("Biometrics error:", err);
          });
        } catch (error) {
          console.error("OneSDK initialization failed:", error);
        }
      }

      startOneSDK();
    </script>
  </body>
</html>

Step-by-Step Breakdown

1. Initialize the SDK

Pass the session object to OneSDK(). Include the ocr and form.provider recipe configuration.

2. Configure Components

Create form components for Welcome, Consent, Document selection, and a shared Loading screen. Create the ocr and biometrics components separately.

3. Wire Up Events

Use .on(event) listeners to navigate between screens and transition from OCR to biometrics. A single loading screen is reused for both OCR and biometrics initialization — mounted to the overlay before each component, and unmounted when the component is ready.
Unmount clears the container. Calling .unmount() on a component removes all content from the element it was mounted to — not just the component itself. Loading screens in this flow are mounted to a separate overlay element (#loading-overlay) so that unmounting them does not destroy the OCR or biometrics component underneath. See the IDV with Review flow for a detailed explanation.

4. Handle Results

Listen for results on both the OCR and biometrics components. See Error Scenarios for details on handling failures.

OCR Results Handling

When the OCR component completes, it returns the extracted document data and the flow proceeds to biometrics:
ocr.on("results", ({ document }) => {
  if (document) {
    // Access extracted fields if needed
    const dob = document.ocrResult.dateOfBirth;
    const name = document.ocrResult.fullName;

    // Proceed to biometrics
    loading.mount("#loading-overlay");
    biometrics.mount(appContainer);
  }
});
See OCR Module for all available result fields.

Biometrics Error Recovery

The biometrics component may fail due to camera issues or detection problems. Implement automatic retry:
let biometricsError = false;

biometrics.on("detection_failed", () => {
  biometricsError = true;
});

biometrics.on("session_closed", () => {
  if (biometricsError) {
    biometrics.mount(appContainer);
    biometricsError = false;
  }
});
See Biometrics Module for all events and configuration options.

Adding a Review Screen

To let users confirm extracted data before proceeding to biometrics, insert a review screen between OCR and biometrics:
const review = oneSdk.component("form", {
  name: "REVIEW",
  type: "ocr",
});

ocr.on("results", ({ document }) => {
  if (document) {
    review.mount(appContainer);
  }
});

review.on("form:review:ready", () => {
  loading.mount("#loading-overlay");
  biometrics.mount(appContainer);
});

Customization Reference

AspectReference
SDK initialization optionsSDK Initialization
OCR component configurationOCR Module
Biometrics configurationBiometrics Module
Form screen configurationForm Module
Screen names and typesForm Screens
Event names and payloadsEvents
Error handling patternsError Scenarios