Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Info

Ondato’s OnAge solution allow your customers to complete the process from anywhere, with any device, in a matter of seconds. With this method, Ondato employs AI and machine learning to gather and analyse biometric data, which is then used to create a 3D map of the customer’s face and accurately place them in an age group without gathering or storing any personal data. With a quick selfie, we are able to perform liveness checks, preventing any spoofing attempts or masks from getting through while keeping the steps easy for your clients.

...

...

📁 Table of Contents

Table of Contents
stylenone

...

ℹ️ Introduction

The current flow only allows using the Web Browser SDK by installing it through npm🔗or using it as a script🔗.

...

🔢 Latest version

  • Latest Major version is v2.x.x

  • Refer to Changelog for latest versions and changes.

...

🚥 Compatibility

  • 🟢 Supported: Only web browsers (Chrome, Firefox, Safari, Edge etc.).

  • 🔴 Not supported: Native application languages like React-Native, Flutter etc.

...

📂 Getting started with npm

To begin, run the following command:

Code Block
npm install @ondato-public/idv-sdk

...

☑️ Prerequisites

  • Adjusted .npmrc file with custom registry.

...

  • Obtain the static OnAge setup id.

  • Verify the Web browser version limitations.

    • Refer to the documentation here.

  • Review npm examples for a better understanding.

...

🗃️ Example npm

Download example here

Expand
title|| CLICK TO VIEW SNIPPET ||
Code Block
// Typescript React example
import { memo, ReactElement, useCallback, useState } from 'react';

import { 
  IdvLanguage, 
  load, 
  SdkMode, 
  version,
  SdkLoadResult,
  SdkOnSuccessResult,
  SdkOnFailureResult,
  SdkOnCloseResult } from '@ondato-public/idv-sdk';

export const AppNew = memo((): ReactElement => {
  const [onAgeSetupId, setOnAgeSetupId] = useState('');

  const [language, setLanguage] = useState('');

  const [sdkOnAge, setSdkOnAge] = useState<SdkLoadResult | null>(null);
  const [isLoaded, setIsLoaded] = useState(false);

  const loadHandlerOnage = useCallback(() => {
    try {
      const onAge = load({
        mode: SdkMode.Sandbox,
      });

      setSdkOnAge(onAge);
      setIsLoaded(true);
    } catch (error) {
      console.warn('OnageSdkLoadFailure', error);
      alert(`OnageSdkLoadFailure, ${error}`);
    }
  }, []);

  const beginHandlerOnAge = useCallback(async () => {
    try {
      if (sdkOnAge?.onAge.begin) {
  
        await sdkOnAge.onAge.begin({
          onAgeSetupId: onAgeSetupId.trim(),

          language: language.trim() as IdvLanguage,
          onSuccess: (props: SdkOnSuccessResult) => {
            console.log('onSuccess', { props });
            alert(`onSuccess, OnAge: ${props}`);
          },
          onFailure: (props: SdkOnFailureResult) => {
            console.log('onFailure', props);
            alert(`onFailure, OnAge: ${props}, reason: ${props}}`);
          },
          onClose: (props: SdkOnCloseResult) => {
            console.log('onClose ', props.id);
          },
        });
      }
    } catch (error) {
      console.warn('OnAgeSdkBeginFailure', error);
      alert(`OnAgeSdkBeginFailure, ${error}`);
    }
  }, [sdkOnAge?.onAge, onAgeSetupId, language]);

  const versionHandler = useCallback(() => {
    alert(version());
  }, []);

  const endHandlerOnAge = useCallback(() => {
    sdkOnAge?.onAge.end();
  }, [sdkOnAge]);

  return (
    <>
      <button type="button" disabled={isLoaded} onClick={loadHandlerOnage}>
        Load OnAge
      </button>
      <button type="button" onClick={versionHandler}>
        SDK version
      </button>
      <button type="button" disabled={!isLoaded} onClick={beginHandlerOnAge}>
        Begin On age
      </button>
      <button
        type="button"
        className="end-action"
        onClick={endHandlerOnAge}
        disabled={!isLoaded}
      >
        X
      </button>
      <button
        type="button"
        className="end-action"
        onClick={endHandlerOnAge}
        disabled={!isLoaded}
      >
        X
      </button>
      <div className="input-group">
        <input
          type="text"
          placeholder="OnAge setup Id"
          value={onAgeSetupId}
          onChange={(event) => setOnAgeSetupId(event.target.value)}
        />
        <input
          type="text"
          className="short-input"
          placeholder="en-GB (optional)"
          value={language}
          onChange={(event) => setLanguage(event.target.value)}
        />
      </div>
    </>
  );
});

...

  • Full TypeScript support is available. Full list *.d.ts types can be downloaded from script🔗examples or when installed through npm🔗.

Expand
title|| VIEW MOST IMPORTANT TYPES ||
Code Block
export { IdvLanguage as AvailableLanguages } from '@idv/utils/idvLanguage';

export { ThemeType as SdkThemeType } from '@idv/utils/common/common.enums';

export enum SdkMode {
  Production = 'Production',
  Sandbox = 'Sandbox',
}

export type BackgroundStyle = {
  /**
   * SDK backround opacity.
   * CSS property opacity.
   * Default is 0.9.
   */
  opacity?: number | null;

  /**
   * SDK backround blur.
   * The radius of the blur in px / rem / em / etc.
   * Default is 0.375rem.
   */
  blur?: string | null;
};

export type CustomiseStyleProps = {
  /**
   * SDK backround styles.
   */
  background?: BackgroundStyle | null;

  /**
   * SDK theme.
   * Theme values dark | light.
   * Default is light.
   */
  theme?: SdkThemeType;
};

...

📂 Getting started with javascript Script

To begin, run the following command:

Code Block
<script src="{baseUrl}/ondato-sdk.2.x.x.min.js"></script>

...

☑️ Prerequisites

...

🗃️ Example script

Download example here

Expand
title|| CLICK TO VIEW SNIPPET ||
Code Block
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      http-equiv="Cache-control"
      content="no-cache, no-store, must-revalidate"
    />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />
    <style>
      html {
        height: 100vh;
        background-color: #b7b7b7;
        background-position: center;
        background-image: url(https://img.freepik.com/free-vector/quiz-background-with-flat-objects_23-2147593080.jpg);
      }

      body {
        margin: 0;
      }

      #end-action {
        position: fixed;
        top: 0;
        right: 0;
        z-index: 10000001;
      }

      .input-group {
        display: grid;
        margin-top: 1rem;
        max-width: 30rem;
      }

      .input-group > * {
        margin: 1rem;
      }
    </style>
    <script>
      window.sdkTest = true;

      let onAgeSdk = null;
      async function loadHandler() {
        try {
          onAgeSdk = WebSdkEntry.load({
            mode: 'Sandbox',
          });

          document.getElementById('load-action').disabled = true;
          document.getElementById('begin-action').disabled = false;
          document.getElementById('customise-style-action').disabled = false;
          document.getElementById('end-action').disabled = false;
        } catch (error) {
          console.warn('OnageSdkLoadFailure', error);
          alert(`OnageSdkLoadFailure, ${error}`);
        }
      }

      async function beginHandler() {
        try {
          if (onAgeSdk?.onAge.begin) {
            await onAgeSdk.onAge.begin({
              onAgeSetupId: document
                .getElementById('on-age-setup-id')
                .value.trim(),
              language: document.getElementById('on-age-language').value.trim(),
              onSuccess: (props) => {
                console.log('onSuccess', props);
                alert(`onSuccess, OnAge: ${JSON.stringify(props)}`);
              },
              onFailure: (props) => {
                console.log('onFailure', props);
                alert(`onFailure, OnAge: ${JSON.stringify(props)}}`);
              },
              onClose: (props) => {
                console.log('onClose onAge', props);
              },
            });
          }
        } catch (error) {
          console.warn('OnAgeSdkBeginFailure', error);
          alert(`OnAgeSdkBeginFailure, ${error}`);
        }
      }

      function customiseStyleHandler() {
        onAgeSdk?.onAge.customiseStyle({
          background: {
            opacity: 0.12,
            blur: '10px',
          },
          theme: 'dark',
        });
      }

      function endHandler() {
        onAgeSdk?.onAge.end();
      }

      function versionHandler() {
        alert(WebSdkEntry.version());
      }
    </script>
  </head>
  <body>
    <button id="load-action" onclick="loadHandler()">Load On Age</button>
    <button onclick="versionHandler()">On Age SDK version</button>
    <button
      id="customise-style-action"
      onclick="customiseStyleHandler()"
      disabled
    >
      Customise Style
    </button>
    <button id="begin-action" onclick="beginHandler()" disabled>
      Begin On Age
    </button>
    <button id="end-action" onclick="endHandler()" disabled>X</button>
    <div class="input-group">
      <input
        id="on-age-setup-id"
        type="text"
        placeholder="On Age Setup Id"
        value=""
      />
      <input
        id="on-age-language"
        type="text"
        placeholder="en-GB (optional)"
        value=""
      />
    </div>
    <script src="../../build/ondato-sdk.2.0.3.min.js"></script>
  </body>
</html>

...

🔀 Flows explained

To illustrate how to implement flows, consider the following code snippet:

Code Block
import { load } from '@ondato-public/idv-sdk';

const exampleSdk = load({ mode: SdkMode.Sandbox });

...

1️⃣ load()

Info
  • Purpose: To invoke the initial Web SDK instance.

  • Return: On success, it provides the onAge.begin() and onAge.end() methods.

  • Accepted property: The mode interface (used for setting the environment).

Expand
title|| CLICK TO VIEW MORE ||
Code Block
languagenone
declare enum SdkMode {
  Production = "Production",
  Sandbox = "Sandbox"
} 

⚠️ Possible exceptions:

Code Block
languagenone
declare enum SdkLoadFailure {
   NotSupportedMode = 'NotSupportedMode' // incorrect mode (environemnt) provided
}

...

2️⃣ exampleSdk.onAge.customiseStyleonload()

Info
  • Purpose: This function enables customization of certain CSS styles within the SDK.

  • Accepted property: ({ background: { opacity: 0, blur: '0' } })

Expand
title|| CLICK TO VIEW MORE ||
Code Block
export type BackgroundStyle = {
  /**
   * IDV SDK backround opacity.
   * CSS property opacity.
   * Default is 0.9.
   */
  opacity?: number | null;

  /**
   * IDV SDK backround blur.
   * The radius of the blur in px / rem / em / etc.
   * Default is 0.375rem.
   */
  blur?: string | null;
};

export type CustomiseStyleProps = {
  /**
   * SDK backround styles.
   */
  background?: BackgroundStyle | null;
};

...

3️⃣ exampleSdk.onAge.begin()

Info
  • Purpose: Creates OnAge session.

  • Accepted property: onAgeSetupId, language, onSuccess, onFailure, onClose

Expand
title|| CLICK TO VIEW MORE ||
Code Block
exampleSdk.onAge.begin({
  onAgeSetupId: 'xxxxxx-xxxx', // Static onAge setupId provided by support
  language?: 'bg-BG' // possible languages are listed below or can be found in the interface
  onSuccess:  // callback fired on successful completion
  onFailure:  // callback fired on any failure mentioned in possible exceptions
  onClose:  // callback fired when sdk process is closed
});

⚠️ Possible exceptions:

Code Block
declare enum SdkBeginFailure {
  NoOnAgeSetupId = 'NoOnAgeSetupId',
  CantBeUsedInIframe = "CantBeUsedInIframe", // Consumer cannot use this sdk in iframe. We restrict usage due to requiring full screen
  NoIdvId = "NoIdvId", // idvId or idv setup id was not provided
  NotSupportedMode = "NotSupportedMode",// check if provided mode is invalid according to SdkMode 
  ProcessStarted = "ProcessStarted", // if multiple sdk begin were started error. You cannot start multiple identifications in the same page simultaniously. 
  StartFailed = "StartFailed" //  if sdk applications has crashed for some reason when trying to initially load the sdk application. Due to nework error etc. 
}

declare enum SdkProcessFailure {
  ConsentDeclined = "ConsentDeclined", // if user declines consent, sdk application is closed and error is returned
  FailureExit = 'FailureExit', // When process gives a dead end reason and process failed, user is prompted with exit from sdk application button. Button is clicked - sdk application is closed and FailureExit is returned.
  Generic = 'Generic', // An error during sdk application flow happened and we cannot provide the exact reason why the process failed. Sdk closes and returns Generic error. (Something similar like internal server error)
  InvalidId = 'InvalidId',  // no accessToken or no session id case.
  Unauthorized = 'Unauthorized', // in case of invalid session id, in case of expired session id, in case of any other way invalidated session id, in case of completed session id, in case of session id that does not belong to accessToken etc.
  Aborted = 'Aborted', // if user aborts Identity verification process.
  Suspended = 'Suspended', // If identify verification process was suspended
  Expired = 'Expired', // If identify verification process was suspended
  NotSupportedBrowser = 'NotSupportedBrowser',
  NoIFrameContainer = 'NoIFrameContainer', // If user closes sdk application in an unknown way and there is still an sdk application instance running.
  CurrentSessionIdAndPassedIdMismatch = 'CurrentSessionIdAndPassedIdMismatch', // session id was does not match previous session id
}

...

4️⃣ exampleSdk.onAge.end()

Info
  • Purpose: Closes SDK application without error. Cleans up all sdk tasks and application.

  • Accepted property: None

...

5️⃣ Data flow

🚀 Startup

Drawio
mVer2
zoom1
simple0
inComment0
custContentId3001253901
pageId2969042947
lbox1
diagramDisplayNameStartup flow.drawio
contentVer6
revision6
baseUrlhttps://ondato.atlassian.net/wiki
diagramNameUntitled Diagram-1730363657203.drawio
pCenter0
width556
links
tbstyle
height581

...

🆕 New Visitor

Drawio
mVer2
zoom1
simple0
zoominComment10
inCommentcustContentId03001090097
pageId2969042947
custContentIdlbox30010900971
diagramDisplayNameNew Visitor flowlbox1
contentVer7
revision7
baseUrlhttps://ondato.atlassian.net/wiki
diagramNameUntitled Diagram-1730363923619.drawio
pCenter0
width566
links
tbstyle
height1371.0000000000002

...

◀️ Returning Visitor

Drawio
mVer2
zoom1
simple0
inComment0
custContentId3001745432
pageId2969042947
lbox1
diagramDisplayNameReturning Visitor flow
contentVer3
revision3
baseUrlhttps://ondato.atlassian.net/wiki
diagramNameUntitled Diagram-1730364540308.drawio
pCenter0
width381
links
tbstyle
height551

...

❔ Frequently Asked Questions (FAQs)

  • Why should both the begin()andload()methods be used within a try-catch block?

    • Both methods should be utilized within a try-catch block to ensure proper error handling.

  • What happens to the session id during an F5 (page refresh)?

    • In the event of an F5 (page refresh), the same session id will be retained, allowing the same session to be loaded seamlessly.

  • Where can I find a list of available languages?

...

🗒️ Changelog 🔗

...