react-native-incode-sdk Usage guide
Contents:
- Installation
- Additional setup for iOS
- Additional setup for Android
- Installation Expo SDK
- Usage
- Onboarding flow and workflow execution results
- Flow listeners
- Other API methods
- Sections execution API
- Dynamic Delivery
- Using SDK without an API KEY
- SDK impact size optimizations
- E2EE SDK Integration Guide
- Customization
Installationβ
npm i @incode-sdks/react-native-incode-sdk
Additional setup for iOSβ
After installation, it's necessary to do the linking for the iOS, after running the command above. Requirements:
- Xcode 15.0.1+
- Swift 5.5+
- Cocapods 1.11+
- iOS 13+
- Change your Podfile so it equires deployment target 13 or higher.
-platform :ios, '10.0'
+platform :ios, '13.0'
- Add this line to the top of your Podfile:
RN >= 0.69 no changes needed
RN < 0.69
pod 'react-native-incode-sdk', :path => '../node_modules/@incode-sdks/react-native-incode-sdk/'
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.
Relying on React Native's auto-linking, run the following:
cd ios && pod install cd ..
- 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.
- 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:
Change your
minSdkVersion
to 21 or higher. SetcompileSdkVersion
to 34 or higher.Add this dependency in you app's
build.gradle
:
dependencies {
+ implementation 'com.incode.sdk:core-light:2.6.4'
}
- 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 {
...
}
- Modify your project's
build.gradle
so it contains Artifactory username and password, provided by Incode.
allprojects {
repositories {
...
+ maven { url "https://jitpack.io" }
+ maven {
+ url "https://repo.incode.com/artifactory/libs-incode-welcome"
+ credentials {
+ username = "ARTIFACTORY_USERNAME"
+ password = "ARTIFACTORY_PASSWORD"
+ }
+ }
...
}
}
Installation Expo SDKβ
- Install SDK
npx expo install @incode-sdks/react-native-incode-sdk
- Install configuration plugin
npx expo install @incode-sdks/expo-incode-sdk-configuration
- Integrate and configure configuration plugin. Update 'plugins' field in app.json file:
{
"expo": {
"plugins": [
[
"@incode-sdks/expo-incode-sdk-configuration",
{
"artifactoryUserName": "client_artifactory_username",
"artifactoryPassword": "client_artifactory_password",
"coreLightVersion": "2.6.4"
}
]
]
}
}
Usage
The typical basis workflow includes the following steps:
- Explicitly initialize IncodeSdk
- After waiting for the SDK to be initialized, configure Incode Onboarding Flow, by selecting modules (steps) you need
- Register listeners for steps-related events (e.g. step completion, step update, step failure)
- Run the Onboarding flow
Usage Exampleβ
import React from 'react';
import IncodeSdk from '@incode-sdks/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((error) => {
const e = error as IncodeSdkInitError;
console.error(`Incode SDK initialize failed with error ${e.code} - ${e.message}`);
});
};
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
- Specifystandard
orcaptureOnly
modes. Default isstandard
.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 Incodeurl
- API url, provided by Incodee2eeUrl
- custom server url used for End-to-End Encryption (E2EE)
sslPinningConfig
enabled
- Set to false to disable SSL pinning. Default istrue
disableJailbreakDetection
- Set to true if you would like to disable jalibreak detection. Valid only for iOS. Default false.externalAnalyticsEnabled
- Set to true if you would like to enable external analytics. Default true.loggingEnabled
- Set to true if you would like to enable logging. Default true.externalScreenshotsEnabled
- Set to true if you would like to enable external screenshots. Default false.disableEmulatorDetection
- Set to true if you would like to disable emulator detection.Valid only for Android. Default false.disableRootDetection
- Set to true if you would like to disable root detection. Valid only for Android. Default false.
IncodeSDK.initialize
method throws IncodeSdkInitError
error with following possible values for field code
:
simulatorDetected
, testModeEnabled
, invalidInitParams
, configError
, unknown
Start the onboardingβ
IncodeSdk.startOnboarding
will create a new session based on specified list of modules that you provide via flowConfig
.
To change session parameters, specify them inside optional sessionConfig
parameter:
region
- Specify a region, currently supported areALL
(covers all regions),BR
(optimized for Brazil) andIN
(optimized for India)queue
- Specify a queue to which this onboarding session will be attached tointerviewId
- 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 sessionconfigurationId
- 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 sessiontoken
- 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 sessionexternalId
- ID used outside of Incode OmnivalidationModules
- List of validation modules that should be enabled in this sessioncustomFields
- Custom data that should be attached to this onboarding sessione2eEncryptionEnabled
- Enable e2e encryption.
To enable screen recording of ID and Selfie capture, specify optional recordSessionConfig
parameter:
- Set
recordSession
totrue
- Set
forcePermissions
,true
if you wish to abort the session in case user denies permissons,false
otherwise
Start workflowβ
IncodeSdk.startWorkflow
will create a new session based on configurationId
that you provide via sessionConfig
.
To change session parameters, specify them inside required sessionConfig
parameter:
configurationId
- Configuration ID of a flow on the dashboard. Required parameter.region
- Specify a region, currently supported areALL
(covers all regions),BR
(optimized for Brazil) andIN
(optimized for India)queue
- Specify a queue to which this onboarding session will be attached tointerviewId
- 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 sessiontoken
- 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 sessionexternalId
- ID used outside of Incode OmnivalidationModules
- List of validation modules that should be enabled in this sessioncustomFields
- Custom data that should be attached to this onboarding session
To enable screen recording of ID and Selfie capture, specify optional recordSessionConfig
parameter:
- Set
recordSession
totrue
- Set
forcePermissions
,true
if you wish to abort the session in case user denies permissons,false
otherwise
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 onceIdScanFront
andIdScanBack
are completed)Conference
SelfieScan
FaceMatch
QrScan
Email
Approve
UserScore
MLConsent
GovernmentValidation
Antifraud
GlobalWatchlist
CustomWatchlist
Aes
Name
CURP
OCREdit
eKYB
eKYC
Modules interdependenciesβ
The order of the modules in the config array indicates the execution order. Note that:
FaceMatch
module expectsIdScan
andSelfieScan
to have executed, in order to perform the match. In other words,IdScan
andSelfieScan
must precedeFaceMatch
ProcessId
module expectsIdScanFront
andIdScanBack
to have executed, in order to validate the ID properly. In other words,IdScanFront
andIdScanBack
must precedeProcessId
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
andApprove
modules do not depend on each other, so their order can be arbitrary.
Onboarding flow and workflow execution results
When the flow completes, the promise startOnboarding
and startWorkflow
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, promise will be rejected with a IncodeSdkFlowError
with following possible values for field code
:
simulatorDetected
, rootDetected
, hookDetected
, badEnvDetected
,virtualEnvDetected
, permissionsDenied
, unknown
Example of handling the error:
try {
const onboardingResult = await IncodeSdk.startOnboarding({
sessionConfig: sessionConfig,
flowConfig: flowConfig,
});
} catch (error) {
const e = error as IncodeSdkFlowError;
if (e.code === 'permissionsDenied') {
console.log(`User denied some mandatory permission during the flow`);
} else {
console.log('Unknown error occured')
}
}
Workflow execution results
When the workflow completes, the promise startWorkflow
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 startWorkflow
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 name | Function |
---|---|
moduleName | Mandatory. The name of the module we wish to include |
enabled | Optional: Whether or not the module is needed in the flow |
Below is the list of all available module names, with additional configuration parameters.
Phone
otpVerification
(optional, defaults tofalse
): Ask for otp verification
DocumentScan
showTutorial
(optional, defaults tofalse
): Show tutorial for document scan.showDocumentProviderScreen
(optional, defaults totrue
): Specifytrue
if you would like to show document provider screen to the user, orfalse
if you would like to go directly to the capture.type
- specify document typeaddressStatement
,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 keydescription
: (optional) string - Adds optional description below the title. Contains value of the description string keydescriptionMaxLines
(optional): number - Specifies maximum amount of lines of text in the description
VideoSelfie: Available only for API level 21+.
showTutorial
(optional, defaults tofalse
): Show tutorial for video selfie.selfieScanMode
(optional, defaults toselfieMatch
):selfieMatch
|faceMatch
; Specify if you would like to do selfie comparison, or comparison with the photo from ID.selfieLivenessCheck
(optional, defaults tofalse
): Check for user liveness during video selfie.showIdScan
(optional, defaults totrue
): Ask for ID scan during video selfie.showVoiceConsent
(optional, defaults totrue
): Ask for Voice consent during video selfievoiceConsentQuestionsCount
(optional, defaults to3
): Choose number of questions for video selfie voice consent steps.cameraFacingConfiguration
(optional): CameraFacingConfiguration. Specifies which camera will be used during each step in Video selfie.
IdScan
showTutorial
(optional, defaults totrue
): booleanidType
(optional):id
orpassport
. If omitted, the app will display a chooser to the user.idCategory
(optional):primary
orsecondary
. Defaultprimary
showRetakeScreen
(optional, defaults totrue
): booleanenableFrontShownAsBackCheck
(optional, defaults tofalse
): booleanenableBackShownAsFrontCheck
(optional, defaults tofalse
): booleanshowAutoCaptureRetakeScreen
(optional, defaults tofalse
): booleanenableRotationOnRetakeScreen
(optional, defaults totrue
): booleanautocaptureUxMode
(optional):countdown
orholdStill
. Default 'holdStill'showIDOverlay
(optional, defaults tofalse
): boolean
IdScanFront
showTutorial
(optional, defaults totrue
): booleanidType
(optional):id
orpassport
. If omitted, the app will display a chooser to the user.idCategory
(optional):primary
orsecondary
. Defaultprimary
showRetakeScreen
(optional, defaults totrue
): booleanenableFrontShownAsBackCheck
(optional, defaults tofalse
): booleanenableBackShownAsFrontCheck
(optional, defaults tofalse
): booleanshowAutoCaptureRetakeScreen
(optional, defaults tofalse
): booleanenableRotationOnRetakeScreen
(optional, defaults totrue
): booleanautocaptureUxMode
(optional):countdown
orholdStill
. Default 'holdStill'showIDOverlay
(optional, defaults tofalse
): boolean
IdScanBack
showTutorial
(optional, defaults totrue
): booleanidCategory
(optional):primary
orsecondary
. Defaultprimary
showRetakeScreen
(optional, defaults totrue
): booleanenableFrontShownAsBackCheck
(optional, defaults tofalse
): booleanenableBackShownAsFrontCheck
(optional, defaults tofalse
): booleanshowAutoCaptureRetakeScreen
(optional, defaults tofalse
): booleanenableRotationOnRetakeScreen
(optional, defaults totrue
): booleanautocaptureUxMode
(optional):countdown
orholdStill
. Default 'holdStill'showIDOverlay
(optional, defaults tofalse
): 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 totrue
): booleanlensesCheck
(optional, defaults totrue
): boolean. Performs check if user is wearing glasses during Selfie Scan.cameraFacing
(optional, defaults tofront
):front
|back
. Specifies which camera will be used during Selfie capture.faceMaskCheck
(optional, defaults tofalse
): boolean. This checks if a person has a mask on.brightnessThreshold
(optional, defaults to50
): number. Adjust minimum requirements for a well lit face during capture.
FaceMatch
idCategory
(optional):primary
orsecondary
. Defaultprimary
showUserExists
(optional): defaults totrue
: boolean- Note: has to be specified after IDScan and SelfieScan modules.
QrScan
- no additional parameters
Email
- no additional parameters
Approve
forceApproval
(optional, defaults tofalse
): boolean - iftrue
the user will be force-approved
UserScore
mode
(optional, defaults toaccurate
):accurate
orfast
. Ifaccurate
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. Iffast
, then results based on on-device processing will be shown.
MLConsent
type
:gdpr
|us
GovernmentValidation
isBackgroundExecuted
(optional): defaults tofalse
: boolean
Antifraud
- no additional parameters
GlobalWatchlist
- no additional parameters
CustomWatchlist
- no additional parameters
Aes
uploadDocument
(optional): defaults tofalse
: booleandownloadDocument
(optional): defaults tofalse
: boolean
Name
- no additional parameters
CURP
validationEnabled
(optional): defaults totrue
: boolean - Specifies should the CURP be validated on the server or not.
OCREdit
isEditable
(optional): defaults tofalse
: boolean
eKYB
checkBusinessName
(optional): defaults tofalse
: booleancheckAddress
(optional): defaults tofalse
: booleancheckTaxId
(optional): defaults tofalse
: boolean
eKYC
checkName
(optional): defaults tofalse
: booleancheckEmail
(optional): defaults tofalse
: booleancheckAddress
(optional): defaults tofalse
: booleancheckPhone
(optional): defaults tofalse
: booleancheckSsn
(optional): defaults tofalse
: booleancheckDob
(optional): defaults tofalse
: booleancheckNationality
(optional): defaults tofalse
: boolean
Flow listeners
The SDK offers several types of listeners:
- user cancellation
- tracking events
- 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
and startWorkflow
method result would have status
- 'userCancelled'.
On both platforms the user can cancel by pressing 'X' button that can be enabled using IncodeSdk.showCloseButton(true);
, and additionally on Android the user can cancel by pressing the back key.
Tracking eventsβ
- When onboarding has been started, information about events used to track all the user steps in their flow can be obtained using
onEvents
callback.
IncodeSdk.onEvents((e) => {
for (const ev of e.events) {
console.log(ev.event);
}
});
- e:
Events
- Parameter holding array of all events - events:
EventDetails[]
- Array of emitted events - event:
Event
- Event with fields:- event:
string
- Unique identifier of the event - data:
string
- JSON string with additional event details
- event:
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, containingpngBase64
of the captured front ID - croppedFace:
IncdImage
object, containingpngBase64
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 captureid
orpassport
- idCategory:
String
, category of the ID verifiedprimary
orsecondary
- status: the
String
. If value is other thanok
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, containingpngBase64
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 captureid
orpassport
- idCategory:
String
, category of the ID verifiedprimary
orsecondary
- status: the
String
. If value is other thanok
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
andresult.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
.
MLConsentβ
In case the user has given the machine learning consent:
{
"status": "success",
"step": "MLConsent"
}
If some error happened, the "status" field will be set to corresponding error.
If the user declined to give the consent, the onboarding flow will be ended with a status userCancelled
.
GovernmentValidationβ
This module enables your user to input their information to validate with Government services as a part of your flow.
On module completion, the result returned will look like this:
{
"status": "success",
"step": "GovernmentValidation"
}
The field status
can have one of the following values: success
or fail
.
Antifraudβ
This module gives ability to compare current interview with existing interviews and customers and detect anomalies that could be signs of fraud.
On module completion, the result returned will look like this:
{
"status": "success",
"step": "Antifraud"
}
The field status
can have one of the following values: success
or fail
.
Nameβ
This module enables to capture user's name as a part of your flow.
On module completion, the result returned will look like this:
{
"status": "success",
"name": "exampleName",
"step": "Name"
}
The field status
can have one of the following values: success
or fail
.
CURPβ
This module enables your user to input their CURP information to validate with RENAPO service as a part of your flow. (CURP is a person identifier in MΓ©xico)
On module completion, the result returned will look like this:
{
"status": "success",
"curp": "exampleCurp",
"step": "CURP"
}
The field status
can have one of the following values: success
or fail
.
OCREditβ
This module will show to the user parsed OCR from his ID, which can be optionally edited.
On module completion, the result returned will look like this:
{
"status": "success",
"step": "OCREdit"
}
The field status
can have one of the following values: success
or fail
.
eKYBβ
This module enables a step of KYB validation with the business information and an option of source for this information which includes business name, addresses, city, state, postal code and bank account number.
On module completion, the result returned will look like this:
{
"status": "success",
"step": "eKYB"
}
The field status
can have one of the following values: success
or fail
.
eKYCβ
This module enables a step of kyc validation with the user's information and an option of source for this information which includes data obtained from id, proof of address, or a manual capture.
On module completion, the result returned will look like this:
{
"status": "success",
"step": "eKYC"
}
The field status
can have one of the following values: success
or fail
.
GlobalWatchlistβ
This module checks customer identities against sources of Sanctions, Politically Exposed Persons (PEPs), & Watchlists.
On module completion, the result returned will look like this:
{
"status": "success",
"step": "GlobalWatchlist"
}
The field status
can have one of the following values: success
or fail
.
CustomWatchlistβ
This module checks if the user is found on the watchlist. Watchlist is configured in incode's dashboard.
On module completion, the result returned will look like this:
{
"status": "success",
"step": "CustomWatchlist"
}
The field status
can have one of the following values: success
or fail
.
Aesβ
This module enables an advanced electronic signature to ensure legally binding and compliant document signing with enhanced security and authentication measures.
On successfull module completion, the result returned will look like this:
{
"status": "success",
"step": "Aes"
}
The field status
can have one of the following values: success
or fail
.
Example response for error of the step:
{
"status": "fail",
"error": "noDocuments",
"step": "Aes"
}
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", "image": "...PNG Base 64 encoded" },
"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
andfailed
.
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 () => {
try {
await IncodeSdk.initialize({
testMode: false,
apiConfig: {
key: 'YOUR API KEY',
url: 'YOUR API URL',
},
});
} catch (error) {
const e = error as IncodeSdkInitError;
console.error(e.code + " - " + e.message)
}
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',
lensesCheck: false,
brightnessThreshold: 50,
logAuthenticationEnabled: false,
}
).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 () => {
try {
await IncodeSdk.initialize({
testMode: false,
apiConfig: {
key: 'YOUR API KEY',
url: 'YOUR API URL',
},
});
} catch (error) {
const e = error as IncodeSdkInitError;
console.error(e.code + " - " + e.message)
}
IncodeSdk.startFaceLogin({
showTutorials: true,
faceMaskCheck: false, // Specify true if you would like to prevent login for users that wear face mask
lensesCheck: false,
brightnessThreshold: 50,
logAuthenticationEnabled: false,
}
).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();
Show close button during the flowβ
To programatically show the 'X' button on the top right corner during the flow, call IncodeSdk.showCloseButton
.
Once user clicks the 'X' button the flow will be aborted.
IncodeSdk.showCloseButton(true);
Set Localization Languageβ
To programatically set localization language in runtime, call IncodeSdk.setLocalizationLanguage
.
Parameters available for IncodeSDK.setLocalizationLanguage
method:
language
- language used for runtime localization. Supported values are currently: 'en', 'es' , 'pt'.
IncodeSdk.setLocalizationLanguage('en');
Additionally, on Android platform a new dependency needs to be added in your app's build/gradle:
implementation 'com.incode.sdk:extensions:1.1.0'
Set stringβ
To programatically set and update strings in runtime, call IncodeSdk.setString
.
Parameters available for IncodeSDK.setString
method:
strings
:{ [key: string]: string }
. Map of string keys and its values.
IncodeSdk.setString({
/// iOS labels
'incdOnboarding.idChooser.idButton': 'Id',
/// Android labels
'onboard_sdk_btn_passport': 'Passport',
});
Additionally, on Android platform a new dependency needs to be added in your app's build/gradle:
implementation 'com.incode.sdk:extensions:1.1.0'
For iOS please check documentation here:
https://docs.incode.com/docs/ios/LOCALIZATION_GUIDE#list-of-localizable-texts
For Android please check documentation here:
https://docs.incode.com/docs/android/USER_GUIDE_CUSTOMIZATION#32-dynamic-localization
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 '@incode-sdks/react-native-incode-sdk';
import { View, TouchableOpacity } from 'react-native';
const StartSectionedOnboardingButton = () => {
const [addressCity, setAddressCity] = useState(null);
const executeSectionedFlow = async () => {
try {
await IncodeSdk.initialize({
testMode: false,
apiConfig: {
key: 'YOUR API KEY',
url: 'YOUR API URL',
},
});
} catch (error) {
const e = error as IncodeSdkInitError;
console.error(e.code + " - " + e.message)
}
const session = await IncodeSdk.setupOnboardingSession({});
const idSection = await IncodeSdk.startOnboardingSection({
flowConfig: [
{
module: 'IdScan',
},
sectionTag: 'idSection',
],
});
// insert optional custom business logic
await IncodeSdk.startOnboardingSection({
flowConfig: [{ module: 'SelfieScan' }],
sectionTag: 'selfieSection',
});
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
- Specifystandard
orcaptureOnly
modes. Default isstandard
.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 Incodeurl
- 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 areALL
(covers all regions),BR
(optimized for Brazil) andIN
(optimized for India)queue
- Specify a queue to which this onboarding session will be attached tointerviewId
- 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 sessionconfigurationId
- 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 sessiontoken
- 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 sessionexternalId
- ID used outside of Incode OmnivalidationModules
- List of validation modules that should be enabled in this sessioncustomFields
- Custom data that should be attached to this onboarding sessione2eEncryptionEnabled
- Enable e2e encryption.
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 sessioninterviewId
: 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',
},
],
sectionTag: 'idSection',
});
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.
Optionally, specify sectionTag
parameter to uniquely identify section you want to start.
To enable screen recording of ID and Selfie capture, specify optional recordSessionConfig
parameter:
- Set
recordSession
totrue
- Set
forcePermissions
,true
if you wish to abort the session in case user denies permissons,false
otherwise
Return values:
status
: String. 'success' or 'userCancelled'.sectionTag
: String. value ofsectionTag
parameter passed in config.
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:
try {
await IncodeSdk.initialize({
testMode: false,
apiConfig: {
url: 'YOUR API URL',
},
});
} catch (error) {
const e = error as IncodeSdkInitError;
console.error(e.code + " - " + e.message)
}
IncodeSdk.setupOnboardingSession({
sessionConfig: {
token: 'YOUR_TOKEN',
}
}).then((sessionResult) => {
IncodeSdk.startOnboardingSection({
flowConfig: [{ 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
- 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'
- 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
E2EE SDK Integration Guide
End-to-End Encryption (E2EE) adds an extra layer of security to your communications by encrypting the data transmitted between the server and client. The process begins with a key exchange where the client and server share keys for encrypting and decrypting messages. This exchange acts like a handshake and ensures that all subsequent communications are encrypted. Only the intended server and client are able to decrypt the messages.
Steps to Enable E2EE in the SDK.
1. Install SDK variant with e2ee supportβ
npm i @incode-sdks/react-native-incode-sdk-e2ee
2. Set Up a Custom Server for E2EEβ
Initialize the SDK with a custom server for E2EE as follows:
IncodeSdk.initialize({
apiConfig: {
key: 'YOUR API KEY HERE',
url: 'YOUR API URL HERE',
e2eeUrl: 'YOUR E2EE URL HERE',
},
});
3. Enable E2EE via SessionConfigβ
const sessionConfig: OnboardingSessionConfig = {
e2eEncryptionEnabled: true,
};
4. Pass the SessionConfig Objectβ
You can pass the SessionConfig object to SDK when setup onboarding session:
const session = await IncodeSdk.setupOnboardingSession(sessionConfig);
or when starting a flow:
await IncodeSdk.startOnboarding({
sessionConfig,
flowConfig,
});
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": "CircularXXTT-Black",
"size": "20"
},
"buttonMedium": {
"name": "CircularXXTT-Black",
"size": "16"
},
"buttonSmall": {
"name": "CircularXXTT-Black",
"size": "12"
},
"title": {
"name": "CircularXXTT-Black",
"size": "25"
},
"hugeTitle": {
"name": "CircularXXTT-Black",
"size": "40"
},
"subtitle": {
"name": "CircularXXTT-Black",
"size": "18"
},
"boldedSubtitle": {
"name": "CircularXXTT-Bold",
"size": "18"
},
"smallSubtitle": {
"name": "CircularXXTT-Black",
"size": "14"
},
"info": {
"name": "CircularXXTT-Black",
"size": "16"
},
"body": {
"name": "CircularXXTT-Medium",
"size": "14"
},
"boldedBody": {
"name": "CircularXXTT-Bold",
"size": "14"
},
"textFieldBig": {
"name": "CircularXXTT-Black",
"size": "20"
},
"textFieldMedium": {
"name": "CircularXXTT-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": {
"states": {
"normal": {
"animateStateChange": true,
"alpha": 1,
"backgroundColor": "#FFFFFF",
"borderColor": "",
"borderWidth": 0,
"cornerRadius": 20,
"shadowColor": "#000000",
"shadowOffset": [0,5],
"shadowOpacity": 0.15,
"shadowRadius": 9,
"textColor": "#20263D",
"iconImageName": "incdOnboarding.help.clipped",
"iconTintColor": "#20263D",
"iconPosition": "left",
"iconPadding": 8,
"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
}
}
},
"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})