Getting started

Learn how to add identity verification to your website with OneSDK.

OneSDK integrates into your user registration flow at key points.

How it works

The user onboarding flow works as follows:

  1. The user navigates to your registration webpage.
  2. Before serving the frontend, your server communicates with our server to create a temporary session object
  3. Your server includes the session object as part of the frontend of your webpage.
  4. Your webpage initializes OneSDK using the session object from the server.
  5. OneSDK handles the collection and verification of identify documents and biometrics.
  6. You onboard the individual using OneSDK's submit() method.

Step 1: Create a session

Obtain a session on your backend and forward it to your frontend web page.

Construct the API credentials

  1. Serialize your FrankieOne API credentials to a string using ':' as a separator.
  2. Encode the resulting string using Base64 encoding.

Run the following command:

echo -n 'CUSTOMER_ID:API_KEY' | openssl base64
const base64EncodedCredentials = Buffer.from(`${CUSTOMER_ID}:${API_KEY}`).toString("base64");

If you have a child account with FrankieOne, modify the above command to the following:

echo -n 'CUSTOMER_ID:CUSTOMER_CHILD_ID:API_KEY' | openssl base64

Obtain a temporary session token

Send a POST request to the /machine-sessions endpoint of our Backend for Frontend server (BFF). The appropriate URL for BFF depends on the environment you're integrating with:

EnvironmentURL
Demo<https://backend.demo.frankiefinancial.io/auth/v2/machine-session>
UAT<https://backend.kycaml.uat.frankiefinancial.io/auth/v2/machine-session>
Production<https://backend.kycaml.frankiefinancial.io/auth/v2/machine-session>

๐Ÿ“˜

Different Base URL

The base URL for the /machine-sessions endpoint is different to the server API.

Pass the encoded credential in the Authorization request header using machine as the scheme:

Authorization: machine YOUR_ENCODED_CREDENTIAL

Include the following parameters in the body of the request:

Parameter nameRequiredDescription
permissionsRequiredA hash containing preset and entityId.
permissions.presetRequiredThe string 'one-sdk'.
permissions.entityIdRequiredA string containing the entity ID for the individual being onboarded.

The following example creates a session object for a user using an existing entity ID:

ENCODED_CREDENTIAL=$(echo -ne "$YOUR_CUSTOMER_ID:$API_KEY" | base64);

curl https://backend.demo.frankiefinancial.io/auth/v2/machine-session \
  -X POST \
  -H "Authorization: machine $ENCODED_CREDENTIAL"
  -H 'Content-Type: application/json' \
  -d '{
    "permissions": {
      "preset": "one-sdk",
      "entityId": "YOUR_ENTITY_ID",
    }
  }';
const sessionObject = fetch(`${FRANKIE_BFF_URL}/auth/v2/machine-session`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    authorization: "machine " + Buffer.from(`${CUSTOMER_ID}:${CUSTOMER_CHILD_ID}:${API_KEY}`).toString("base64"),
  },
  body: JSON.stringify({
    permissions: {
      preset: "one-sdk",
      entityId: "YOUR_ENTITY_ID",
    },
  }),
}).then((response) => response.json());

๐Ÿšง

Keep your credentials confidential

Do not publish your credentials to your frontend. They should remain accessible only from your server.

Sample response:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}

Step 2: Set up OneSDK

Use OneSDK to onboard an individual into your application.

Install the SDK

We recommend installing OneSDK via a

Embed script

The current version is v0.4

<script src="https://assets.frankiefinancial.io/one-sdk/v0.4/oneSdk.umd.js"></script>

NPM Module

npm install @frankieone/one-sdk

Import the SDK into your application:

import OneSdk from '@frankieone/one-sdk'

If you install OneSDK as an npm package, you are responsible for updating the version in your package.json file to ensure you always have the most up-to-date version.

Create configuration object

Create an object for the global configuration of your SDK integration. This section shows the required and recommended parameters.

Parameter nameRequiredDescription
sessionRequired, unless mode is specified as "dummy".The session object from your call to /machine-sessions.
modeOptionalOne of "production" or "dummy". If this is specified as "dummy", then session does not need to be specified. The default value is "production".

Sample configuration:

const configuration = {
  session: sessionObject,
};

Pass the entire object returned as the response of the /machine-sessions endpoint as the value for the session parameter. Do not extract the token or any other field from the response.

For example your server-side code may look like:

<?php $sessionResponse = createFrankieSession(); ?>
<script>
  const session = JSON.parse('<?php echo json_encode($sessionResponse) ?>'); // session is the object { token: "...." }
  const oneSdk = await OneSdk({ session });
</script>
<script>
  {% set sessionObject = await createFrankieSession(); %}

  const sessionObject = JSON.parse("{{ sessionObject | json_encode | raw }}"); // session is the object { token: "...." }
  const oneSdk = await OneSdk({ session: sessionObject });
</script>

Initialize the OneSdk object

Create an instance of OneSdk using the configuration object you created.

The OneSDK function returns a promise, which can be await-ed in Javascript ES2017's await.

const oneSdk = await OneSdk(configuration);

Otherwise you can use Javascript's Promise API.

OneSdk(configuration).then((oneSdk) => {
  // The oneSDK instance is ready to use...
});

Step 3: Verify document details via OCR

Use the OCR Component provided by OneSDK to verify document details.

Create the OCR Component

Create an instance of the OCR Component by passing 'ocr' to the type in component(type) method of the FrankieOne object.

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

Handle image capture

Listen to the input_required event to present your image capture interface to the user. The handler method that you provide should accept the following arguments:

Argument nameDescription
inputInfoAn object that describes the type of document required and any additional specifications for the document.

For example, if the front side of a drivers license has already been captured, this object will specify that the back side needs to be captured.
statusAn object that contains the statuses of any previous calls.
callbackA callback function that accepts the captured image data as an instance of the File interface.

Valid statuses

ValueDescription
AWAITING_DOCUMENT_OCROneSDK has captured a document but ocr process is yet to run. Default status if we get errors or user abandons process
AWAITING_DOCUMENT_UPLOAD_FRONTCapture of front needed
AWAITING_DOCUMENT_UPLOAD_BACKCapture of back needed
COMPLETE_OCROCR results are available
AWAITING_DOCUMENT_UPLOAD_FAILED_OCRCapture successful, but an error happened during upload, potentially due to a bad scan
AWAITING_DOCUMENT_UPLOAD_INVALID_TYPEDocument type of the scan seems to be invalid
DOCUMENT_INVALID_EXCEEDED_SIZE_LIMITFile size exceeds the limits supported by third party OCR provider
DOCUMENT_INVALID_INCORRECT_FILE_FORMATFile format is not accepted by the third party OCR provider
AWAITING_OCR_RESULTS_PROVIDER_OFFLINEOneSDK has captured a document but there was a communication issue uploading the document or retrieving the result

The following example implements an input_required listener that supports passports and drivers licenses.

ocr.on("input_required", async (inputInfo, status, provideFile) => {
  
  const { documentType, side } = inputInfo;
  
  // documentType will initially be null, until the type is inferred from the first provided scan
  if (documentType === "PASSPORT") {
    // present UI to capture a passport image
  } else if (documentType === "DRIVERS_LICENCE") {
    // check which side of the drivers licence is required
    if (side === "front") {
      // present UI to capture the licence's front side
    } else if (side === "back") {
      // present UI to capture the licence's back side
    }
  } else {
    // present UI to capture any type of identity document
  }

  // Your use interface you should capture an image and provide it to OneSDK as a File object.
  // https://developer.mozilla.org/en-US/docs/Web/API/File
  //
  // For example, your interface may use the Image Capture API to obtain the image data, though use of this API is not required.
  // See https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Image_Capture_API
  // const blob = // ...
  // provideFile(blob)

  // example of capturing a blob image from browser
  navigator.mediaDevices.getUserMedia({ video: true }).then((mediaStream) => {
    // Do something with the stream.
    const track = mediaStream.getVideoTracks()[0];
    let imageCapture = new ImageCapture(track);
    imageCapture.takePhoto().then((file) => provideFile(file));
  });
});

Obtain results

Listen to the results event to get notified when the detected document details are available.

ocr.on("results", ({ document }) => {
  // Present the details of the document that were detected from the uploaded image or images.
  // Decide whether to proceed to the next stage of the onboarding process
  // depending on whether document verification was successful.
  if (document) {
  } else {
  }
});

Handle errors

Listen to the error event to handle any errors from the OCR component. For example, the supplied image may be unprocesseable.

ocr.on("error", (error) => {
  console.error(error.message);
});

Start the document capture flow

Finally, start the document capture flow. This will immediately trigger the input_required event.

ocr.start();

Step 5: Verify biometrics

Use the Biometrics Component provided by OneSDK to verify the user's facial image.

You may skip this step if biometrics is not required according to the current workflow for the entity.

Create the container element for the Biometrics Component

Create a DOM container element on your onboarding web page where you want the Component to be rendered. Make sure to give the container element a descriptive id.

For example:

<div id="biometrics-container"></div>

If you are using JavaScript frameworks such as Vue or React, make sure that you use references instead of selectors and that you don't re-render the DOM element.

Create the Biometrics Component

Create an instance of the Biometrics Component by passing 'biometrics' to the component(type, options?) method of the FrankieOne object.

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

Obtain results

Listen to the results event to get notified when biometrics results are available.

biometrics.on("results", ({ checkStatus, processing }) => {
  // Decide whether to proceed to the next stage of the onboarding process
  // depending on whether biometrics verification was successful.
  if (processing) {
  } else {
  }
});

Handle errors

Handle detection failed events

When the biometrics component fails to detect the user, it will emit a detection_failed event.

Listen to the detection_failed event to re-attempt to capture the user by mounting the component again.

biometrics.on("detection_failed", (error) => {
  console.error(error);

  if (retriesAttempted < 3) {
    biometrics.mount("#biometrics-container");
  }
});

Listen to the error event to handle any other component errors.

biometrics.on("error", ({ message, payload }) => {
  console.error(message);
});

Start the biometrics flow

Mount the component

Finally, start the document capture flow by mounting the component in your container element.

biometrics.mount("#biometrics-container");

Get notified when the capture feed is ready

The component may take a moment to initialize and display the video capture feed. During this time you can optionally display your own loading state. Listen for the ready event to know when when the biometrics capture interface is ready for use.

biometrics.on("ready", () => {
  // If you provided your own loading state it can now be hidden.
  loadingElement.remove();
});

Step 6: Submit information

Access the Individual object to represent the person being onboarded.

const individual = oneSdk.individual();

Submit all information, make sure that consent has been added and initiate the verification process.

individual.addConsent();
individual.submit({
  verify: true,
});