Skip to main content

react-native-incode-sdk Integration guide

Contents:

Installation​

npm install https://sdk-js.s3.amazonaws.com/react-native/react-native-incode-sdk-5.1.0-nvc.tgz

Additional setup for iOS​

After installation, it's necessary to do the linking for the iOS, after running the command above. Requirements:

  • Xcode 13+
  • Swift 5.5+
  • Cocapods 1.11+
  • iOS 11+
  1. Change your Podfile so it equires deployment target 11 or higher.
-platform :ios, '10.0'
+platform :ios, '11.0'
  1. Add this line to the top of your Podfile:
pod 'react-native-incode-sdk', :path => '../node_modules/react-native-incode-sdk/ios'
  1. Add an empty Swift file (e.g. Void.swift) through xCode to your native project. When prompted for a bridging header, choose Create Bridging header.

  2. Relying on React Native's auto-linking, run the following:

cd ios && pod install cd ..
  1. Adapt Info.plist by adding:
  • NSCameraUsageDescription. The SDK uses the camera in order to verify the identity of the customer, e.g. in ID scan, Selfie scan and so on.
  • NSLocationWhenInUseUsageDescription. The SDK uses the current user location in order to detect exact location for Geolocation step.
  • NSMicrophoneUsageDescription. The SDK uses microphone for performing a video call during Video Conference step or for doing speech recognition during Video Selfie.
  1. Add Linker flags

Go to your projects Target, then Build Settings -> Other Linker Flags and add these flags:

$(inherited) -all_load -ObjC -l β€œstdc++” -l β€œiconv”

Additional setup for Android​

In your app's build.gradle please make sure that following settings are set:

  1. Change your minSdkVersion to 17 or higher. Set compileSdkVersion to 31 or higher.

  2. Add this dependency in you app's build.gradle:

  dependencies {
+ implementation 'com.incode.sdk:core-light:2.2.0'
}

  1. Application has multidex support enabled:
  defaultConfig {
...
+ multiDexEnabled true
...
}
  dependencies {
...
+ implementation 'com.android.support:multidex:1.0.3'
...
}

Your Application class should now be able to extend MultiDexApplication:


+ import androidx.multidex.MultiDexApplication;

+ public class MyApplication extends MultiDexApplication implements ReactApplication {
...
}
  1. Modify your project's build.gradle so it contains Artifactory username and password, provided by Incode.
allprojects {
repositories {
...
+ jcenter()
+ maven {
+ url "http://repo.incode.com/artifactory/libs-incode-welcome"
+ credentials {
+ username = "ARTIFACTORY_USERNAME"
+ password = "ARTIFACTORY_PASSWORD"
+ }
+ }
...
}
}

Usage

The typical basis workflow includes the following steps:

  1. Explicitly initialize IncodeSdk
  2. After waiting for the SDK to be initialized, configure Incode Onboarding Flow, by selecting modules (steps) you need
  3. Register listeners for steps-related events (e.g. step completion, step update, step failure)
  4. Run the Onboarding flow

Usage Example​

import React from 'react';
import IncodeSdk from 'react-native-incode-sdk';
import { View, TouchableOpacity } from 'react-native';

const StartOnboardingButton = () => {
// 1. initialization
const initializeAndRunOnboarding = () => {
IncodeSdk.initialize({
testMode: false,
apiConfig: {
key: 'YOUR API KEY HERE',
url: 'YOUR API URL HERE',
},
})
.then((_) => {
// 2. configure and start onboarding
startOnboarding();
})
.catch((e) => console.error('Incode SDK failed init', e));
};

const startOnboarding = () =>
IncodeSdk.startOnboarding({
flowConfig: [
{ module: 'IdScan' },
{ module: 'SelfieScan' },
{ module: 'FaceMatch' },
],
})
.then((result) => {
console.log(result);
})
.catch((error) => console.log(error));

// 3: register listeners for relevant events when the component gets mounted
React.useEffect(() => {
const unsubscribers = setupListeners(); //defined below

// return a function unregistering all your listeners (called when component is unmounted)
return () => {
unsubscribers.forEach((unsubscriber) => unsubscriber());
};
}, []);

return <TouchableOpacity label="Start onboarding!" onPress={initializeAndRunOnboarding} />;
};

const setupListeners = () => {
// returns a callback to unregister your listener, e.g. when your screen is getting unmounted
IncodeSdk.onSessionCreated((session) => {
console.log('Onboarding session created, interviewId: ' + session.interviewId);
})

const complete = IncodeSdk.onStepCompleted;
return [
complete({
module: 'IdScanFront',
listener: (e) => {
console.log('ID scan front:', e.result);
},
}),
complete({
module: 'IdScanBack',
listener: (e) => {
console.log('ID scan back: ', e.result);
},
}),
complete({
module: 'ProcessId',
listener: (e) => {
console.log('ProcessId result: ', e.result.extendedOcrData);
},
}),
complete({
module: 'SelfieScan',
listener: (e) => {
console.log('Selfie scan complete', e.result);
},
}),

complete({
module: 'FaceMatch',
listener: (e) => {
console.log('Face match complete', e.result);
},
}),
];
};

Initialize the SDK​

Parameters available for IncodeSDK.initialize method:

  • testMode - Set to true if running on simulator/emulators, false when running on devices. Default false.
  • sdkMode - Specify standard or captureOnly modes. Default is standard. captureOnly mode works completely offline and for ID and Selfie scan only does image captures without doing any validations.
  • disableHookCheck - Set to true if you would like to test the app on Android devices that have some hook frameworks installed, cause they are not allowed in production. Default false.
  • waitForTutorials - Specifying false means that the users can see and press continue button on all video tutorial screens without waiting for the video to complete. Default true.
  • apiConfig
    • key [optional] - API key, provided by Incode
    • url - API url, provided by Incode

Possible error codes and error messages during initialize:

Incd::EmulatorDetected - β€œEmulator detected, emulators aren't supported in non test mode!”
Incd::RootDetected - β€œRoot access detected, rooted devices aren't supported in non test mode!”
Incd::HookDetected - β€œHooking framework detected, devices with hooking frameworks aren't supported in non test mode!”
Incd::TestModeDetected - β€œPlease disable test mode before deploying to a real device!”

Start the onboarding​

IncodeSdk.startOnboarding will create a new session based on specified list of modules that you provide via flowConfig.

In case you would like to change session parameters, specify them inside optional sessionConfig parameter:

  • region - Specify a region, currently supported are ALL(covers all regions), BR (optimized for Brazil) and IN (optimized for India)
  • queue - Specify a queue to which this onboarding session will be attached to
  • interviewId - In case you're creating an onboarding session on the backend, you can provide its interviewId and the flow will be started for that particular onboarding session
  • configurationId - In case you've created a flow on the dashboard with a specific configuration, you can provide it here so that those settings apply to this session
  • token - In case you're creating an onboarding session on the backend, you can provide its token and the flow will be started for that particular onboarding session
  • externalId - ID used outside of Incode Omni
  • validationModules - List of validation modules that should be enabled in this session
  • customFields - Custom data that should be attached to this onboarding session

Supported modules​

The modules supported by the SDK are listed here, and elaborated in more detail throughout the rest of this document.

  • Phone
  • DocumentScan
  • Geolocation
  • UserConsent
  • Signature
  • VideoSelfie
    • ⚠️ Android note: Available only for API level 21+.
  • IdScan (does capture of both front and back ID and validates it)
  • IdScanFront (does capture of ony front)
  • IdScanBack (does capture of only back)
  • ProcessId (does only validation of the ID - should be called once IdScanFront and IdScanBack are completed)
  • Conference
  • SelfieScan
  • FaceMatch
  • QrScan
  • Email
  • Approve
  • UserScore

Modules interdependencies​

The order of the modules in the config array indicates the execution order. Note that:

  • FaceMatch module expects IdScan and SelfieScan to have executed, in order to perform the match. In other words, IdScan and SelfieScan must precede FaceMatch
  • ProcessId module expects IdScanFront and IdScanBack to have executed, in order to validate the ID properly. In other words, IdScanFront and IdScanBack must precede ProcessId
  • UserScore module should succeed all other modules (must be at the end)
  • Approve module should succeed all other modules (must be at the end)
  • The UserScore and Approve modules do not depend on each other, so their order can be arbitrary.

Flow execution results

When the flow completes, the promise startOnboarding will contain the execution status:

{ "status": "success" }

In case the user cancels the process, the status will be user_cancelled.

In case the execution can not be completed, the startOnboarding promise will be rejected. This can happen:

  • if the user cancels the process
  • if the user fails to enter the correct captcha for 3 times (given the Captcha module is included)

Modules configuration

Common configuration needed for each module includes:

Parameter nameFunction
moduleNameMandatory. The name of the module we wish to include
enabledOptional: Whether or not the module is needed in the flow

Below is the list of all available module names, with additional configuration parameters.

  • Phone
    • no additional parameters
  • DocumentScan
    • showTutorial (optional, defaults to false): Show tutorial for document scan.
    • showDocumentProviderScreen (optional, defaults to true): Specify true if you would like to show document provider screen to the user, or false if you would like to go directly to the capture.
    • type - specify document type addressStatement, paymentProof, medicalDoc, otherDocument1, otherDocument2, otherDocument3.
  • Geolocation
    • no additional parameters
  • UserConsent
    • title: string, content: string
  • Signature
    • title: (optional) string - Adds optional title to the top of the screen. Contains value of the title string key
    • description: (optional) string - Adds optional description below the title. Contains value of the description string key
    • descriptionMaxLines (optional): number - Specifies maximum amount of lines of text in the description
  • VideoSelfie: Available only for API level 21+.
    • showTutorial (optional, defaults to false): Show tutorial for video selfie.
    • selfieScanMode (optional, defaults to selfieMatch): selfieMatch | faceMatch; Specify if you would like to do selfie comparison, or comparison with the photo from ID.
    • selfieLivenessCheck (optional, defaults to false): Check for user liveness during video selfie.
    • showIdScan (optional, defaults to true): Ask for ID scan during video selfie.
    • showDocumentScan (optional, defaults to true): Ask for Proof of Address during video selfie
    • showVoiceConsent (optional, defaults to true): Ask for Voice consent during video selfie
    • voiceConsentQuestionsCount (optional, defaults to 3): Choose number of questions for video selfie voice consent steps.
  • IdScan
    • showTutorial (optional, defaults to true): boolean
    • idType (optional): id or passport. If omitted, the app will display a chooser to the user.
    • idCategory (optional): primary or secondary. Default primary
    • showRetakeScreen (optional, defauts to true): boolean
  • IdScanFront
    • showTutorial (optional, defaults to true): boolean
    • idType (optional): id or passport. If omitted, the app will display a chooser to the user.
    • idCategory (optional): primary or secondary. Default primary
    • showRetakeScreen (optional, defauts to true): boolean
  • IdScanBack
    • showTutorial (optional, defaults to true): boolean
    • idCategory (optional): primary or secondary. Default primary
    • showRetakeScreen (optional, defauts to true): boolean
  • ProcessId
    • enableIdSummaryScreen: boolean. Specifying false means no summary screen will be shown to the user once he fail to capture ID multiple times. Defaults to true.
  • Conference
    • disableMicOnStart: boolean
  • SelfieScan
    • showTutorial (optional, defaults to true): boolean
    • lensesCheck (optional, defaults to true): boolean. Performs check if user is wearing glasses during Selfie Scan.
  • FaceMatch
    • idCategory (optional): primary or secondary. Default primary
    • Note: has to be specified after IDScan and SelfieScan modules.
  • QrScan
    • no additional parameters
  • Email
    • no additional parameters
  • Approve
    • forceApproval (optional, defaults to false): boolean - if true the user will be force-approved
  • UserScore
    • mode (optional, defaults to accurate): accurate or fast. If accurate the results will be fetched from server, which may exhibit some latency, but will rely on server-side processing of information, which may be more reliable than on-device processing. If fast, then results based on on-device processing will be shown.

Flow listeners

The SDK offers several types of listeners:

  • user cancellation
  • step completion, for each module individually
  • step error, for each module individually
  • step update, for each module individually

User cancellation​

If the user cancels the onboarding, startOnboarding method result would have status - 'userCancelled'. On Android, the user can cancel by pressing the back key. On iOS the user can not cancel.

Step completion​

When onboarding session gets created, the information about the session can be obtained via IncodeSdk.onSessionCreated method.

IncodeSdk.onSessionCreated((session) => {
console.log('Onboarding session created, interviewId: ' + session.interviewId);
})
  • interviewId: String - Unique identifier of the onboarding session
  • token: String - Token created for this onboarding session

Note This method should be called before startOnboarding

When a step within the configured Onboarding flow is completed, the information can be obtained by registering a listener via IncodeSdk.onStepCompleted. This takes two arguments: (1) the module name and (2) the callback.

IncodeSdk.onStepCompleted({
module: 'SelfieScan',
listener: (selfieScanResult) => {
console.log('SELFIE SCAN completed', selfieScanResult.result);
},
})

IdScanFront​

  • image: IncdImage object, containing pngBase64 of the captured front ID
  • croppedFace: IncdImage object, containing pngBase64 of the cropped face from the front ID
  • classifiedIdType: the String - Classified ID type by Incode, ie. Voter Identification
  • chosenIdType: the String - what did the user choose to capture id or passport
  • idCategory: String, category of the ID verified primary or secondary
  • status: the String . If value is other than ok you can consider the ID scan and/or validation did not come through successfully. The Incode UI will clearly inform the user about these errors and will attempt the scan several times, before responding with an error. Possible error values: errorClassification, noFacesFound, errorGlare, errorReadability, errorSharpness, errorTypeMismatch, userCancelled, unknownError, errorClassification, errorShadow, errorPassportClassification.

IdScanBack​

  • image: IncdImage object, containing pngBase64 of the captured front ID
  • classifiedIdType: the String - Classified ID type by Incode, ie. Voter Identification
  • chosenIdType: the String - what did the user choose to capture id or passport
  • idCategory: String, category of the ID verified primary or secondary
  • status: the String . If value is other than ok you can consider the ID scan and/or validation did not come through successfully. The Incode UI will clearly inform the user about these errors and will attempt the scan several times, before responding with an error. Possible error values: errorClassification, noFacesFound, errorGlare, errorReadability, errorSharpness, errorTypeMismatch, userCancelled, unknownError, errorClassification, errorShadow, errorPassportClassification.

Notes:

  • result.data.birthDate is the epoch time.
  • result.status.back and result.status.front can take one of following values: ok or several others indicating an issue with the scanning. The Incode UI will clearly inform the user about these errors and will attempt the Scan several times, before responding with an error. Other errors are: errorClassification, noFacesFound, errorCropQuality, errorGlare, errorReadability, errorSharpness, errorTypeMismatch, userCancelled, unknownError, errorClassification, shadow, errorAddress, errorPassportClassification, errorReadability.

ProcessId​

  • data: the basic IdScanOcrData object, containing most important data
  • ocrData: the String object, raw JSON containing full OCR data ie. exteriorNumber, interiorNumber, typeOfId, documentFrontSubtype

Notes:

  • result.data.birthDate is the epoch time.

Conference​

This module starts a video conference call with the executive.

Example response for completion of the step:

{
"step": "Conference",
"result": {
"status": "success"
}
}

Example response for error of the step:

{
"step": "Conference",
"result": {
"status": "error"
}
}

The field result.status can have values userCancelled, invalidSession or error;

DocumentScan​

The DocumentScan will attempt reading address from the provided document.

Note: If the user decides to skip this step, you will get a response with blank values, instead of nil/error.

Example response for completion of the step:

{
"result": {
"address": { // parsed OCR data
"city": "Springfield",
"colony": "Springfield",
"postalCode": "555555",
"state": "Serbia",
"street": "Evergreen terrace"
},
"data": {"raw JSON OCR data"},
"type": "addressStatement",
"image": {"pngBase64": "/9j/4AAQSkZJRgABAQAAAQABAAD/4..."},
},
"step": "DocumentScan"
}

Example response for error of the step:

{
"status": "userCancelled",
"step": "DocumentScan"
}

The field status can have one of the following values: permissionsDenied, simulatorDetected or unknown.

Geolocation​

The Geolocation steps yields the current location of the user. Example response for completion of the step:

{
"result": {
"city": "Springfield",
"colony": "Springfield",
"postalCode": "555555",
"state": "Serbia",
"street": "Evergreen terrace"
},
"step": "Geolocation"
}

The field status can have one of the following values: permissionsDenied, unknownError or noLocationExtracted.

UserConsent​

In case the user has given the consent:

{
"status": "success",
"step": "UserConsent"
}

If the user declined to give the consent, the onboarding flow will be ended with a status userCancelled.

FaceMatch​

This module checks if the face from the scanned ID/passport and the face obtained from the SelfieScan module are a match.

Example response for completion of the step:

{ "result": { "status": "match",
"confidence": 1,
"nameMatched": false,
"existingUser": false,
"existingInterviewId": "exampleInterviewID",
"idCategory": "primary"
},
"step": "FaceMatch"
}

The field result.status can take values match or mismatch. Example response for error of the step:

{
"status": "userCancelled",
"step": "FaceMatch"
}

The field status can have one of values: unknownError or simulatorDetected.

Phone​

This module enables the user to enter their phone number. Example response for completion of the step:

{
"result": { "phone": "+15555555555", "resultCode": "success" },
"step": "Phone"
}

The field result.resultCode can take the value success.

Example response for error of the step:

{
"status": "error",
"step": "Phone"
}

The field status can take one of the values: invalidSession, userCancelled, error.

Email​

This module enables the user to enter their email. Example response for completion of the step:

{
"result": { "email": "email@example.com", "status": "success" },
"step": "Email"
}

Example response for error of the step:

{
"status": "fail",
"step": "Email"
}

Signature​

This module enables user to add a digital signature by signing on a canvas.

Besides sepcifying title and description keys it is needed to provide texts for Android and iOS in their res/values/strings.xml and Localizable.strings files.

{
module: 'Signature',
title: 'onboard_sdk_signature_title',
description: 'onboard_sdk_signature_description',
descriptionMaxLines: 2
}

For Android:

<string name="onboard_sdk_signature_title">Example title</string>
<string name="onboard_sdk_signature_description">Description example</string>

For iOS:

"onboard_sdk_signature_title" = "Example title";
"onboard_sdk_signature_description" = "Description example";

Example response for completion of the step:

{ "result": { "status": "success" }, "step": "Signature" }

Example response for error of the step:

{ "status": "error", "step": "Signature" }

The field status can take one of following: error or invalidSession.

SelfieScan​

Example result:

{
"result": { "spoofAttempt": false, "status": "success" },
"step": "SelfieScan",
"image": {
"pngBase64": "...PNG Base 64 encoded",
"encryptedBase64": "...PNG Encyrpted Base 64 encoded"
}
}

Example response for error of the step:

{
"status": "success",
"step": "SelfieScan"
}

The field status can take one of the values: none, permissionsDenied, simulatorDetected, spoofDetected.

Approve​

Adding this module to the flow instructs the Incode server to perform the approval of the user.

Example response for completion of the module:

{ "result": { "status": "approved", "id": "customerUUID", "customerToken": "customerToken"}}, "step": "Approve" }
  • The field status can take values: approved and failed.

Example response for error of the module: there is no error.

UserScore​

This module displays the user score using the UI.

Example response for completion of the module:

{
"result": {
"data": {
"existingUser": true,
"facialRecognitionScore": "0.0/100",
"idVerificationScore": "79.0/100",
"livenessOverallScore": "95.2/100",
"overallScore": "0.0/100",
"status": "fail"
},
"extendedUserScoreJsonData": "{..}"
},
"step": "UserScore"
}

data will contain basic parsed users core data. extendedUserScoreJsonData will contain raw JSON containing full user score data.

Example response for error of the module: The field result.data.status can have one of the following values: warning, unknown, manual and fail.

QrScan​

This module captures the QR code on the back of the ID, extracts the valuable data out of it and sends it to the server.

VideoSelfie​

This module records the device's screen while the user needs to do a selfie, show his ID, answer a couple of questions and confirms that he accept the terms and conditions. The recorded video is then uploaded and stored for later usage.

Captcha​

This module asks the user to enter OTP generated for current session. If the user doesn't enter correct OTP multiple times the flow will be terminated. On module completion, the result given to the listener will take the shape of:

{
"result": {
"status": "success",
"response": "ABCDEF"
}
}

Note: Captcha failure will result in rejection of Onboarding promise. There is no module error listener here.

Other API methods

Incode's SDK exposes additional operations: Face login, user approve and user score.

Face Login​

Prerequisites for a successful Face Login is that user has an approved account with an enrolled face.

Face Login 1:1​

1:1 Face Login performs a 1:1 face comparison, and returns a successful match if the two faces match.

For 1:1 Face login you nned to have at hand his customerUUID. If the user was approved during onboarding on mobile device, you should have received customerUUID as a result of Approve step during onboarding.

Example usage:

const runLogin = async () => {
await IncodeSdk.initialize({
testMode: false,
apiConfig: {
key: 'YOUR API KEY',
url: 'YOUR API URL',
},
});

IncodeSdk.startFaceLogin({
showTutorials: true,
faceMaskCheck: false, // Specify true if you would like to prevent login for users that wear face mask
customerUUID: 'YOUR_CUSTOMER_UUID'
}
).then( (faceLoginResult) => {
console.log(faceLoginResult)
})
.catch((e) => {
console.error(e.code + " - " + e.message)
});
};

Note To enable faceMaskCheck on Android, please add additional dependency to the build.gradle:

  dependencies {
...
+ implementation 'com.incode.sdk:model-mask-detection:2.0.0'
...
}

Example Face Login 1:1 response:

{
"faceMatched": true, // boolean indicator if Face Login was successful. Reason for faiulure might be that faces didn't match, or the user with this customerToken and customerUUID isn't found in the system.
"spoofAttempt": false, // boolean indicator if face login failed due to spoof attempt
"image": {
"pngBase64": "...PNG Base 64 encoded",
"encryptedBase64": "...PNG Encyrpted Base 64 encoded"
},
"customerUUID": "exampleCustomerUUID", // Approved customer ID
"interviewId": "exampleInterviewID", // Interview ID of the session where the user got approved
"interviewToken": "exampleInterviewToken", // Interview token of the session where the user got approved
"token": "exampletoken", // Fewshly generated token for now authenticated user
"transactionId": "Unique Authentication attempt ID", // Unique ID of this authentication attempt
"hasFaceMask": false, // boolean indicator if person was wearing a face mask during login. Available in iOS only, Anddroid will force the user to take the mask off before login is performed.
}

Face Login 1:N​

1:N Face Login performs a 1:N database face lookup, and returns a successful match if face is found in the database.

Example usage:

const runLogin = async () => {
await IncodeSdk.initialize({
testMode: false,
apiConfig: {
key: 'YOUR API KEY',
url: 'YOUR API URL',
},
});

IncodeSdk.startFaceLogin({
showTutorials: true,
faceMaskCheck: false, // Specify true if you would like to prevent login for users that wear face mask
}
).then( (faceLoginResult) => {
console.log(faceLoginResult)
})
.catch((e) => {
console.error(e.code + " - " + e.message)
});
};

Note To enable faceMaskCheck on Android, please add additional dependency to the build.gradle:

  dependencies {
...
+ implementation 'com.incode.sdk:model-mask-detection:2.0.0'
...
}

Example Face Login 1:N response:

{
"faceMatched": true, // boolean indicator if Face Login was successful. Reason for faiulure might be that this face isn't associated with any approved user in the database.
"spoofAttempt": false, // boolean indicator if face login failed due to spoof attempt
"image": {
"pngBase64": "...PNG Base 64 encoded",
"encryptedBase64": "...PNG Encyrpted Base 64 encoded"
},
"customerUUID": "exampleCustomerUUID", // Approved customer ID
"interviewId": "exampleInterviewID", // Interview ID of the session where the user got approved
"interviewToken": "exampleInterviewToken", // Interview token of the session where the user got approved
"token": "exampletoken", // Fewshly generated token for now authenticated user
"transactionId": "Unique Authentication attempt ID", // Unique ID of this authentication attempt
"hasFaceMask": false, // boolean indicator if person was wearing a face mask during login. Available in iOS only, Anddroid will force the user to take the mask off before login is performed.
}

Get user score API​

To fetch user score programmatically in order to evaluate it, you can use IncodeSdk.getUserScore.

When the promise is fulfilled, the result will contain all the data like in the result field of the corresponding User Score step.

Configuraton is similar to User Score step: this method can receive optional config parameter map: {mode: 'accurate'}. The mode parameter is optional: can take values accurate or fast.

If config object or the mode is absent, then accurate is the default;

IncodeSdk.getUserScore()
.then((score) => console.log(score))
.catch((e) => {
console.error('Face match failed', e);
})

Approve API​

To programmatically initiate approval of the user, you can use IncodeSdk.approve. It takes a config object, setting forceApprove (see approve module). When the promise is fulfilled, the result will contain all the data like in the result field of the corresponding Approve step.

IncodeSdk.approve({forceApproval: false})
.then((result) => {
console.log("approve finished: ", result);
})
.catch((e) => {
console.log("approve error: ", e);
});

FaceMatch API​

To programmatically initiate face match between photo from the ID and Selfie, you can use IncodeSdk.faceMatch. It does the matching silently in the background, comapring to regular Face Match module that shows UI feedback to the user.

IncodeSdk.faceMatch()
.then((faceMatchResult) => {
console.log('Face match result: ', faceMatchResult);
})
.catch((e) => {
console.error('Face match failed', e);
});

Delete Local User Data API​

To programmatically delete localy stored onboarding session data on Android devices, you can use IncodeSdk.deleteUserLocalData. This will delete up to 5-6 MB of data stored on local storage during onboarding flow.

IncodeSdk.deleteUserLocalData();

Sections execution API

The Sections execution API enables you to design a flow which executes in sections, whereas the regular onboarding flow is executed in a single go. You'd typically use this method to evaluate results of a module (e.g. ID Scan) in order to choose whether or not other modules (e.g. Geolocation) are needed. In this case ID Scan would be executed in one section, and Selfie would be executed in the following. In between sections, the Incode's UI goes away, and you can have your own business logic getting executed or show your own UI screens.

Here's full code sample:

import React from 'react';
import IncodeSdk from 'react-native-incode-sdk';
import { View, TouchableOpacity } from 'react-native';

const StartSectionedOnboardingButton = () => {
const [addressCity, setAddressCity] = useState(null);

const executeSectionedFlow = async () => {
await IncodeSdk.initialize({
testMode: false,
apiConfig: {
key: 'YOUR_API_KEY',
url: 'YOUR_URL',
},
});

const session = await IncodeSdk.setupOnboardingSession({});
const idSection = await IncodeSdk.startOnboardingSection({
flowConfig: [
{
module: 'IdScan',
},
],
});

// insert optional custom business logic

await IncodeSdk.startOnboardingSection({
flowConfig: [{ module: 'SelfieScan' }],
});
IncodeSdk.finishOnboardingFlow();
unregisterIdScanListener();
};

return <TouchableOpacity label="Start sections" onPress={executeSectionedFlow} />;
};

Init the SDK​

Parameters available for IncodeSDK.initialize method:

  • testMode - Set to true if running on simulator/emulators, false when running on devices. Default false.
  • sdkMode - Specify standard or captureOnly modes. Default is standard. captureOnly mode works completely offline and for ID and Selfie scan only does image captures without doing any validations.
  • disableHookCheck - Set to true if you would like to test the app on Android devices that have some hook frameworks installed, cause they are not allowed in production. Default false.
  • apiConfig
    • key [optional] - API key, provided by Incode
    • url - API url, provided by Incode

Possible error codes and error messages during initialize:

Incd::EmulatorDetected - β€œEmulator detected, emulators aren't supported in non test mode!”
Incd::RootDetected - β€œRoot access detected, rooted devices aren't supported in non test mode!”
Incd::HookDetected - β€œHooking framework detected, devices with hooking frameworks aren't supported in non test mode!”
Incd::TestModeDetected - β€œPlease disable test mode before deploying to a real device!”

Setup the onboarding session​

To setup an onboarding session call setupOnboardingSession method:

const session = await IncodeSdk.setupOnboardingSession({});

In case you would like to change session parameters, specify them inside optional sessionConfig parameter:

  • region - Specify a region, currently supported are ALL(covers all regions), BR (optimized for Brazil) and IN (optimized for India)
  • queue - Specify a queue to which this onboarding session will be attached to
  • interviewId - In case you're creating an onboarding session on the backend, you can provide its interviewId and the flow will be started for that particular onboarding session
  • configurationId - In case you've created a flow on the dashboard with a specific configuration, you can provide it here so that those settings apply to this session
  • token - In case you're creating an onboarding session on the backend, you can provide its token and the flow will be started for that particular onboarding session
  • externalId - ID used outside of Incode Omni
  • validationModules - List of validation modules that should be enabled in this session
  • customFields - Custom data that should be attached to this onboarding session

List of available validation modules:

id - enables ID validation for the session liveness - enables spoof detection during Selfie for the session faceRecognition - enables Face Match comparison between photo from the ID and Selfie governmentValidation - enables govermnent validation of the ID governmentFaceValidation - enables govermnent validation of face from the Selfie governmentOcrValidation - enables govermnent validation of the OCR data from the ID videoSelfie - enables Video selfie results being part of scoring for the session

Default validation modules are: id, liveness, and faceRecognition.

Return values of setupOnboardingSession method:

  • token: String - Token of the onboarding session
  • interviewId: String - Unique identifier of the onboarding session

Start the section​

To configure and start the flow for a section use startOnboardingSection method:

const idSection = await IncodeSdk.startOnboardingSection({
flowConfig: [
{
module: 'IdScan',
},
],
});

You can start multiple sections, but only one at a time. startOnboardingSection accepts the same config and modules as startOnboarding method, so please take a look at Supported modules section above.

Return values:

  • status: String. 'success' or 'userCancelled'.

To get results from the steps within the section, please take a look at the Step completion section above.

Finish the flow​

Once all the sections are completed you'll have to finish current onboarding session. To do so, call finishOnboardingFlow method:

IncodeSdk.finishOnboardingFlow();

Using SDK without an API KEY

To use the SDK without an API KEY, please provide a token to the setupOnboardingSession method, and afterwards you should proceed with using Sections API like in the example below:

await IncodeSdk.initialize({
testMode: false,
apiConfig: {
url: 'YOUR_URL'
},
});

IncodeSdk.setupOnboardingSession({
sessionConfig: {
token: 'YOUR_TOKEN',
}
}).then((sessionResult) => {
IncodeSdk.startOnboardingSection({
config: [{ module: 'IdScan', showTutorial: false },
{ module: 'SelfieScan', showTutorial: false},],
})
.then((onboardingSectionResult) => {
IncodeSdk.faceMatch()
.then((faceMatchResult) => {
IncodeSdk.finishOnboardingFlow()
.then((finishResult) => {
console.log('Session completed successfully');
})
.catch((e) => {
console.error('Finish session error', e);
})
})
.catch((e) => {
console.error('Face match error', e);
})
})
.catch((e) => {
console.error('Start onboarding section error', e);
});
})
.catch((e) => {
console.error('Set onboarding session error', e);
});

SDK impact size optimizations

1) To further optimize Android SDK impact size you can use lighter version of the Android dependency in your build.gradle:

-implementation 'com.incode.sdk:core-light:2.2.0'
+implementation 'com.incode.sdk:core-light-reduced:2.2.0'

2) To programmatically delete localy stored onboarding session data on Android devices, refer to the section here

Dynamic Delivery

To use Dynamic Delivery of the resources on Andorid and iOS platforms please follow the guide here

Customization

The customization is done independently for both platforms.

Android​

  • To change the texts, add other localization to the app, change icons or videos or customize the theme check the full guide here.

iOS​

  • To change icons or videos guide, please follow the guide here.
  • To change the texts, add other localization to the app, please follow the guide here
  • To change the theme use setTheme method, as in the following example:
const jsonTheme = JSON.stringify({
"colors": {
"accent": "#00B2FD",
"primary": "#20263D",
"background": "#FFFFFF",
"secondaryBackground": "#E9E9EB",
"success": "#0CD5A2",
"error": "#FF5C6F",
"warning": "#F3AB3C",
"cancel": "#20263D"
},
"fonts": {
"buttonBig": {
"name": "CircularStd-Black",
"size": "20"
},
"buttonMedium": {
"name": "CircularStd-Black",
"size": "16"
},
"buttonSmall": {
"name": "CircularStd-Black",
"size": "12"
},
"title": {
"name": "CircularStd-Black",
"size": "25"
},
"hugeTitle": {
"name": "CircularStd-Black",
"size": "40"
},
"subtitle": {
"name": "CircularStd-Black",
"size": "18"
},
"boldedSubtitle": {
"name": "CircularStd-Bold",
"size": "18"
},
"smallSubtitle": {
"name": "CircularStd-Black",
"size": "14"
},
"info": {
"name": "CircularStd-Black",
"size": "16"
},
"body": {
"name": "CircularStd-Medium",
"size": "14"
},
"boldedBody": {
"name": "CircularStd-Bold",
"size": "14"
},
"textFieldBig": {
"name": "CircularStd-Black",
"size": "20"
},
"textFieldMedium": {
"name": "CircularStd-Black",
"size": "15"
}
},
"buttons": {
"primary": {
"states": {
"normal": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "#00B2FD",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 32,
"shadowColor": "#000000",
"shadowOffset": [0,5],
"shadowOpacity": 0.15,
"shadowRadius": 9,
"textColor": "#FFFFFF",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
},
"highlighted": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "#20263D",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 32,
"shadowColor": "#000000",
"shadowOffset": [0,5],
"shadowOpacity": 0.15,
"shadowRadius": 9,
"textColor": "#00B2FD",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
},
"disabled": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "#E9E9EB",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 32,
"shadowColor": "#000000",
"shadowOffset": [0,5],
"shadowOpacity": 0,
"shadowRadius": 9,
"textColor": "#FFFFFF",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
}
},
"big": {
"height": 64,
"minWidth": 200,
"contentInsets": {
"top": 19,
"left": 32,
"bottom": 19,
"right": 32
},
"kerning": 0
},
"medium": {
"height": 46,
"minWidth": 0,
"contentInsets": {
"top": 12,
"left": 24,
"bottom": 12,
"right": 24
},
"kerning": 0
}
},
"secondary": {
"states": {
"normal": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "#FFFFFF",
"borderColor": "#20263D",
"borderWidth": 1,
"cornerRadius": 32,
"shadowColor": "",
"shadowOffset": [0,0],
"shadowOpacity": 0,
"shadowRadius": 0,
"textColor": "#20263D",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
},
"highlighted": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "#20263D",
"borderColor": "#20263D",
"borderWidth": 1,
"cornerRadius": 32,
"shadowColor": "",
"shadowOffset": [0,0],
"shadowOpacity": 0,
"shadowRadius": 0,
"textColor": "#00B2FD",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
},
"disabled": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "#FFFFFF",
"borderColor": "#E9E9EB",
"borderWidth": 1,
"cornerRadius": 32,
"shadowColor": "",
"shadowOffset": [0,0],
"shadowOpacity": 0,
"shadowRadius": 0,
"textColor": "#E9E9EB",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
}
},
"big": {
"height": 64,
"minWidth": 200,
"contentInsets": {
"top": 19,
"left": 32,
"bottom": 19,
"right": 32
},
"kerning": 0
},
"medium": {
"height": 46,
"minWidth": 0,
"contentInsets": {
"top": 12,
"left": 24,
"bottom": 12,
"right": 24
},
"kerning": 0
}
},
"text": {
"states": {
"normal": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 0,
"shadowColor": "",
"shadowOffset": [0,0],
"shadowOpacity": 0,
"shadowRadius": 0,
"textColor": "#20263D",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
},
"highlighted": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 0,
"shadowColor": "",
"shadowOffset": [0,0],
"shadowOpacity": 0,
"shadowRadius": 0,
"textColor": "#00B2FD",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
},
"disabled": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 0,
"shadowColor": "",
"shadowOffset": [0,0],
"shadowOpacity": 0,
"shadowRadius": 0,
"textColor": "#E9E9EB",
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"tx": 0,
"ty": 0
}
}
},
"big": {
"height": 40,
"minWidth": 200,
"contentInsets": {
"top": 8,
"left": 16,
"bottom": 8,
"right": 16
},
"kerning": 0
},
"medium": {
"height": 30,
"minWidth": 0,
"contentInsets": {
"top": 12,
"left": 24,
"bottom": 12,
"right": 24
},
"kerning": 0
}
},
"help": {
"alpha": 1,
"cornerRadius": 20,
"backgroundColor": "#FFFFFF",
"textColor": "#20263D",
"iconColor": "#20263D",
"width": 90,
"height": 40,
"iconTitlePadding": 8,
"verticalPadding": 8,
"horizontalPadding": 12
}
},
"labels": {
"title": {
"textColor": "#20263D",
"kerning": 0
},
"secondaryTitle": {
"textColor": "#FFFFFF",
"kerning": 0
},
"subtitle": {
"textColor": "#20263D",
"kerning": 0
},
"secondarySubtitle": {
"textColor": "#FFFFFF",
"kerning": 0
},
"smallSubtitle": {
"textColor": "#20263D",
"kerning": 0
},
"info": {
"textColor": "#636670",
"kerning": 0
},
"secondaryInfo": {
"textColor": "#FFFFFF",
"kerning": 0
},
"body": {
"textColor": "#20263D",
"kerning": 0
},
"secondaryBody": {
"textColor": "#FFFFFF",
"kerning": 0
},
"code": {
"textColor": "#20263D",
"kerning": 16
}
},
"customComponents": {
"cameraFeedback": {
"alpha": 0.8,
"backgroundColor": "#000000",
"cornerRadius": 20,
"textBackgroundColor": "",
"textColor": "#FFFFFF"
},
"idCaptureHelp": {
"commonIssueLayoutOrientation": "horizontal"
},
"idSideLabel": {
"alpha": 1,
"backgroundColor": "#FFFFFF",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 5
}
},
})

IncodeSdk.setTheme({jsonTheme: jsonTheme})