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:
- The user navigates to your registration webpage.
- Before serving the frontend, your server communicates with our server to create a temporary session object
- Your server includes the session object as part of the frontend of your webpage.
- Your webpage initializes OneSDK using the session object from the server.
- OneSDK handles the collection and verification of identify documents and biometrics.
- 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
- Serialize your FrankieOne API credentials to a string using ':' as a separator.
- 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:
Environment | URL |
---|---|
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 name | Required | Description |
---|---|---|
permissions | Required | A hash containing preset and entityId . |
permissions.preset | Required | The string 'one-sdk' . |
permissions.entityId | Required | A 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.8
<script src="https://assets.frankiefinancial.io/one-sdk/v0.8-alpha/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 name | Required | Description |
---|---|---|
session | Required, unless mode is specified as "dummy" . | The session object from your call to /machine-sessions . |
mode | Optional | One 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 name | Description |
---|---|
inputInfo | An 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. |
status | An object that contains the statuses of any previous calls. |
callback | A callback function that accepts the captured image data as an instance of the File interface. |
Valid statuses
Value | Description |
---|---|
AWAITING_DOCUMENT_OCR | OneSDK has captured a document but ocr process is yet to run. Default status if we get errors or user abandons process |
AWAITING_DOCUMENT_UPLOAD_FRONT | Capture of front needed |
AWAITING_DOCUMENT_UPLOAD_BACK | Capture of back needed |
COMPLETE_OCR | OCR results are available |
AWAITING_DOCUMENT_UPLOAD_FAILED_OCR | Capture successful, but an error happened during upload, potentially due to a bad scan |
AWAITING_DOCUMENT_UPLOAD_INVALID_TYPE | Document type of the scan seems to be invalid |
DOCUMENT_INVALID_EXCEEDED_SIZE_LIMIT | File size exceeds the limits supported by third party OCR provider |
DOCUMENT_INVALID_INCORRECT_FILE_FORMAT | File format is not accepted by the third party OCR provider |
AWAITING_OCR_RESULTS_PROVIDER_OFFLINE | OneSDK 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,
});
Updated about 1 year ago