Integration Guide
Incode Onboarding Flutter SDK
Incode Onboarding provides effortless onboarding where security matters.
Incode Onboarding is part of Incode Omnichannel Biometric Identity Platform, that is powered by Incode's world class Face Recognition, Liveness detection and ID Validation models.
In this repo you can find an example onboarding app that uses Incode Onboarding Flutter SDK to enable remote account opening.
SDK Setup
Requirements
- Flutter version >=1.20.0
Installation
onboarding_flutter_wrapper:
git:
url: [email protected]:Incode-Technologies-Example-Repos/IncdOnboardingFlutter.git
ref: release/[VERSION]If you need a variant that supports streaming the camera feed during Selfie and/or ID scan, please use the following option instead:
onboarding_flutter_wrapper:
git:
url: [email protected]:Incode-Technologies-Example-Repos/IncdOnboardingFlutter.git
ref: release/[VERSION]-vcIf you need a variant that supports NFC scanning (reading data from a passport or ID chip) please use the following option instead:
onboarding_flutter_wrapper:
git:
url: [email protected]:Incode-Technologies-Example-Repos/IncdOnboardingFlutter.git
ref: release/[VERSION]-nfcReplace [VERSION] in the ref field with the latest release branch name e.g release/4.6.0
To use a version older than the latest one, replace [VERSION] in the ref field with the specific release branch, e.g., release/4.2.0.
Additional setup for iOS
After installation, it's necessary to do the linking for the iOS, after running the command above.
- Change your
Podfileinsideiosfolder so it requires deployment target 13 or higher.
-platform :ios, '11.0'
+platform :ios, '13.0'- Run
pod installwithin theiosfolder:
pod install- Adapt
Info.plistby adding mandatory permission related entries depending on the modules you need:
- For camera modules like IdScan, SelfieScan, DocumentScan or VideoSelfie the
NSCameraUsageDesscriptionis mandatory. Geolocationmodule requiresNSLocationWhenInUseUsageDescriptionVideoSelfiemodule and its voice consent step requiresNSMicrophoneUsageDescription
Additional setup for Android
- Modify
app/build.gradleso that you enablemultiDexEnabledand set the minimum API level to 23:
defaultConfig {
…
multiDexEnabled true
minSdkVersion 23
}- Modify your
build.gradleso 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"
+ }
+ }
...
}
}Additionaly, if you're explicitly setting kotlin-gradle-plugin version make sure kotlin version is set to 1.9.0:
buildscript {
+ ext.kotlin_version = '1.9.0'
///
dependencies {
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}- Optionally, modify your
app/build.gradleto add dependencies depending on the features you want to use:
Other optional dependencies can be added for optimized Face Login features:
- Add 'com.incode.sdk:model-mask-detection:2.0.0' to detect face mask during face login.
- Add 'com.incode.sdk:model-liveness-detection:2.0.0' to use local liveness by specifying .hybrid or .local
FaceAuthModefor face login. - Add 'com.incode.sdk:model-face-recognition:2.0.0' to use local face recognition by specifying .local
FaceAuthModefor face login.
Updating to latest version
Run flutter pub upgrade or flutter packages upgrade, and in case iOS SDK version was updated run pod install --repo-update and pod update IncdOnboarding inside your ios folder.
Usage example
- Initialize the SDK
IncodeOnboardingSdk.init(
apiKey: 'YOUR_API_KEY',
apiUrl: 'YOUR_API_URL',
testMode: false,
onError: (String error) {
IncodeSdkInitError? e = error.toIncodeSdkInitError();
switch (e) {
case IncodeSdkInitError.simulatorDetected:
print('Incode init failed, simulator detected: $IncodeSdkInitError.simulatorDetected');
break;
case IncodeSdkInitError.testModeEnabled:
print('Incode init failed, test mode enabled: $IncodeSdkInitError.testModeEnabled');
break;
default:
print('Incode init failed: $error');
break;
}
},
onSuccess: () {
// Update UI, safe to start Onboarding
print('Incode initialize successfully!');
},
);apiUrl and apiKey will be provided to you by Incode.
If you're running the app on a simulator, please set the testMode parameter to true.
In case initialization isn't successful, onError callback will be triggered and the error String will contain more information. Possible values are listed in the IncodeSdkInitError enum: simulatorDetected, testModeEnabled, jailbreakDetected and unknown.
- Configure Onboarding session
You should create an instance ofOnboardingSessionConfiguration:
OnboardingSessionConfiguration sessionConfig = OnboardingSessionConfiguration();Optionally, you can provide these parameters to the OnboardingSessionConfiguration object constructor:
- region:
ALLby default - onboardingValidationModules: list of
OnboardingValidationModuleitems. This list determines which modules are used for verification and calculation of the onboarding score. If you pass null as validationModuleList, the default values will be used: id, faceRecognition and liveness. - customFields: custom fields which are sent to the server.
- externalId: User identifier outside of Incode Omni database.
- externalCustomerId: This identifier links the onboarding session to an entity in an external system not part of the Incode Omni Platform. It could represent a prospect Id or a customer Id from the client's database, providing a bridge between the Incode session and the client's internal user management systems.
- interviewId: Unique identifier of an existion session
- token: Token of an existing session
- configurationId: Flow configurationId found on Incode dashboard.
- e2eEncryptionEnabled: Enable e2e encryption.
Specifying interviewId or token will return an existing session that will be resumed.
Specifying externalId will return an existing session in case a session with the same externalId was already started, otherwise new session will be created.
- Configure Onboarding Flow
You should create an instance of OnboardingFlowConfiguration:
OnboardingFlowConfiguration flowConfig = OnboardingFlowConfiguration()Depending on your needs you should specify the steps you want to include, ie.:
flowConfig.addIdScan();
flowConfig.addSelfieScan();
flowConfig.addFaceMatch();The steps will be executed in the order you added them to the flowConfig.
- Start the onboarding
IncodeOnboardingSdk.startOnboarding(
sessionConfig: sessionConfig,
flowConfig: flowConfig,
onSuccess: () {
print('Incode Onboarding completed!');
},
onError: (String error) {
print('Incode onboarding error: $error');
IncodeSdkFlowError? e = error.toIncodeSdkFlowError();
// Handle the error accordingly
switch (e) {
case IncodeSdkFlowError.rootDetected:
print('Incode SDK onError rooted device detected: $IncodeSdkFlowError.rootDetected');
break;
case IncodeSdkFlowError.hookDetected:
print('Incode SDK onError hooking frameworks detected: $IncodeSdkFlowError.hookDetected');
break;
case IncodeSdkFlowError.simulatorDetected:
print('Incode SDK onError detected simulator: $IncodeSdkFlowError.simulatorDetected');
break;
case IncodeSdkFlowError.permissionsDenied:
print('Incode SDK onError user denied permissions: $IncodeSdkFlowError.permissionsDenied');
break;
case IncodeSdkFlowError.badEnvDetected:
print('Incode SDK onError bad environment detected: $IncodeSdkFlowError.badEnvDetected');
break;
case IncodeSdkFlowError.virtualEnvDetected:
print('Incode SDK onError virtual environment detected: $IncodeSdkFlowError.virtualEnvDetected');
break;
case IncodeSdkFlowError.jailbreakDetected:
print('Incode SDK onError jailbreak detected: $IncodeSdkFlowError.jailbreakDetected');
break;
case IncodeSdkFlowError.faceAuthenticationFailed:
print('Incode SDK onError face authentication failed: $IncodeSdkFlowError.faceAuthenticationFailed');
break;
case IncodeSdkFlowError.unknown:
print('Incode SDK onError unknown error: $IncodeSdkFlowError.unknown');
break;
default:
print('Incode SDK onError called: $error');
break;
}
},
onSelfieScanCompleted: (SelfieScanResult result) {
print('Selfie completed result: $result');
},
onIdFrontCompleted: (IdScanResult result) {
print('onIdFrontCompleted result: $result');
},
onIdBackCompleted: (IdScanResult result) {
print('onIdBackCompleted result: $result');
},
onIdProcessed: (String ocrData) {
print('onIdProcessed result: $ocrData');
},
);Once all the steps are completed by the user, the onSuccess method will be called.
In case some error occurred that stopped the flow from completing, the onError method will be called and the error String will contain more information. Possible values are listed in IncodeSdkFlowError enum.
If user cancels the flow, the onUserCancelled method is triggered.
To listen for the results of the steps in the flow as soon as they're completed, you can add optional callback methods, ie. onSelfieScanCompleted that was added in the above example.
Optionally, if you want to store ID and Selfie capture session recordings, specify recordSessionConfig parameter to the startOnboarding method. Set OnboardingRecordSessionConfiguration.forcePermission to true if you wish to force the user to accept the recording permissions, otherwise the onboarding session will be aborted.
OnboardingRecordSessionConfiguration recordSessionConfig = OnboardingRecordSessionConfiguration(recordSession: true, forcePermission: false);
IncodeOnboardingSdk.startOnboarding(
sessionConfig: sessionConfig,
flowConfig: flowConfig,
recordSessionConfig: recordSessionConfig,
onSuccess: () {
print('Incode Onboarding completed!');
},
onError: (String error) {
print('Incode onboarding error: $error');
},
onSelfieScanCompleted: (SelfieScanResult result) {
print('Selfie completed result: $result');
},
onIdFrontCompleted: (IdScanResult result) {
print('onIdFrontCompleted result: $result');
},
onIdBackCompleted: (IdScanResult result) {
print('onIdBackCompleted result: $result');
},
onIdProcessed: (String ocrData) {
print('onIdProcessed result: $ocrData');
},
);Modules
The modules supported by the SDK are listed here, and elaborated in more detail throughout the rest of this document.
Phone- Ask the user to enter a phone number.Name- Ask the user to enter a name.Email- Ask the user to enter an email.IdScan- Ask the user to capture ID or Passport.ProcessId- Process the ID in case Id Scan was separated to front and back captures.SelfieScan- Ask the user to capture a selfie.FaceMatch- Perform a face match between captured ID and Selfie.Geolocation- Get the information about the users current location.GovernmentValidation- Perform government validation of the ID.VideoSelfie- Records the device's screen while the user needs to do a selfie, show his ID, answer a couple of questions and verbally confirms that he accept the terms and conditions. The recorded video is then uploaded and stored for later usage.UserScore- Shows the info and scoring for all the steps performed.Signature- Ask the user to draw a signature.DocumentScan- Ask the user to capture a document.Captcha- Ask the user to complete CAPTCHA.CURP- Validate user's curp from the ID.OCREdit- Review OCR data.EKYB- Enables a KYB validation step with the business information and an optional source for this information including: business name, addresses, city, state, postal code and bank account number.EKYC- Enables a KYC validation step with the user's information and an optional source for this information including: data obtained from the id, proof of address, or a manual capture.Approve- Based on a score approves the current onboarding session and adds the user to the omni database.MLConsent- Ask the user for Machine Learning consent.UserConsent- Ask the user for User consent.CombinedConsent- Ask the user for Data sharing consent.QRScan- Ask the user for QR scan.Antifraud- Gives ability to compare current interview with existing interviews and customers, detecting anomalies that could be signs of fraud.GlobalWatchlist- This module checks customer identities against sources of Sanctions, Politically Exposed Persons (PEPs), & Watchlists.CustomWatchlist- This module checks if the user is present inside Incode's watchlist. The watchlist is configured in Incode's dashboard.Aes- This module enables an advanced electronic signature to ensure legally binding and compliant document signing with enhanced security and authentication measures.- Face Authentication - Performs a selfie scan to authenticate the user as part of the flow or a workflow.
Modules configuration
Below is the list of all available modules, with additional configuration parameters.
- Phone
defaultRegionPrefix(optional): int?. Default region prefix for phone input. If set, will override the current default prefix based on the user's device region selection.otpVerificationEnabled(optional): bool?
- Name
- no additional parameters
- Email
otpVerificationEnabled(optional): bool?
- IdScan
showTutorials(optional, defaults totrue): bool?idType(optional):IdType.idorIdType.passport. If omitted, the app will display a chooser to the user.idCategory(optional):IdCategory.primaryorIdCategory.secondaryscanStep(otpional): If you wish to separate front and back ID scan, specifyScanStepType.frontorScanStepType.back.ScanStepType.bothis the default and will capture both front and back of the ID, and process the ID afterwards. If you specifyScanStepType.frontorScanStepType.backyou will have to addProcessIdmodule after the captures.showRetakeScreen(optional, defaults totrue): bool? - Specifyfalseto ommit the photo review screen for manual captures.showAutoCaptureRetakeScreen(optional, defaults tofalse): bool? - Specifytrueto show photo review screen for auto captures.enableFrontShownAsBackCheck(optional, defaults tofalse): bool? - Specifytrueto show realtime feedback to the user during back ID capture that he should capture the other side of the IDenableBackShownAsFrontCheck(optional, defaults tofalse): bool? - Specifytrueto show realtime feedback to the user during front ID capture that he should capture the other side of the IDenableRotationOnRetakeScreen(optional, defaults totrue): bool? - Specifyfalseto disable capture image rotation when user enters photo review screen.autocaptureUxMode(optional, defaults toIdScanAutocaptureUXMode.holdStill) - SpecifyIdScanAutocaptureUXMode.countdownto introduce 3-2-1 timer before ID is auto capturedautoCaptureBestFrameTimeout(optional, defaults to 25) - Timer that starts when ID is detected for the first time, defaults to 25 seconds. Manual capture mode will be activated If ID isn't autocaptured sucessfully before time runs out.autoCaptureNoIdTimeout(optional, defaults to 60) - Timer that starts when ID scan autocapture starts, defaults to 60 seconds. Manual capture mode will be activated if no ID is detected before time runs out.streamFrames(optional, defaults to false): boolean. Enables/disables streaming of the camera feed. It requires SDK-vcvariant.
- ProcessId (used only if
ScanStepType.frontorScanStepType.backwere specified asscanStepforIdScanmodule)idCategory(optional):IdCategory.primaryorIdCategory.secondaryenableIdSummaryScreen(optional, defaults totrue): bool? - Specifyfalseto disable ID capture summary screen- Note: Please make sure to call this module only after the both
ScanStepType.frontandScanStepType.backIdScans are completed.
- SelfieScan
showTutorials(optional, defaults totrue): bool?lensesCheck(optional, defaults totrue): bool?. Performs check if user is wearing glasses during Selfie Scan.cameraFacing(optional, defaults toIdScanCameraFacing.front): Specifies which camera will be used during Selfie capture. To use back camera instead, setIdScanCameraFacing.back.faceMaskCheck(optional, defaults tofalse): bool?. This checks if a person has a face mask on.streamFrames(optional, defaults to false): boolean. Enables/disables streaming of the camera feed. It requires SDK-vcvariant.
- FaceMatch
idCategory(optional, defaults toprimary):IdCategory.primaryor `IdCategory.secondarymatchType(optional):FaceMatchType.idSelfie,FaceMatchType.nfcSelfieorFaceMatchType.nfc3WayshowUserExists(optional, defaults totrue): boolean- Note: has to be specified after IDScan and SelfieScan modules.
- Geolocation
- no additional parameters
- GovernmentValidation
isBackgroundExecuted- (optional, defaults tofalse): bool?. Specify true to hide the module UI during its execution.
- VideoSelfie:
showTutorials(optional, defaults totrue): bool?. Show tutorial for video selfie.selfieScanMode(optional, defaults toselfieMatch):SelfieScanMode.selfieMatchorSelfieScanMode.faceMatch; Specify if you would like to do selfie comparison, or comparison with the photo from ID.selfieLivenessCheck(optional, defaults tofalse): bool?. Check for user liveness during video selfie.showIdScan(optional, defaults totrue): bool?. Ask for ID scan during video selfie.showDocumentScan(optional, defaults totrue): bool?. Ask for Proof of Address during video selfieshowVoiceConsent(optional, defaults totrue): bool?. Ask for Voice consent during video selfievoiceConsentQuestionsCount(optional, defaults to3): int?. Choose number of questions for video selfie voice consent steps.idScanCameraFacing(optional, defaults toback):IdScanCameraFacing.frontorIdScanCameraFacing.back; Specify if you would like to use front or back camera for ID scan
- UserScore
mode(optional, defaults toaccurate):UserScoreFetchMode.accurateorUserScoreFetchMode.fast. Ifaccuratethe 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.
- Approve
forceApproval(optional, defaults tofalse): bool? - iftruethe user will be force-approved
- Signature
- no additional parameters
- DocumentScan
showTutorials(optional, defaults totrue): bool?. Show tutorial for document scan.showDocumentProviderOptions(optional, defaults tofalse).documentType(optional, defaults toDocumentType.addressStatement).
- Captcha
- no additional parameters
- CURP
- no additional parameters
- OCREdit
isEditable(optional): defaults tofalse: bool?
- EKYB
checkBusinessName(optional): defaults totrue: bool?checkAddress(optional): defaults totrue: bool?checkTaxId(optional): defaults totrue: bool?
- EKYC
checkName(optional): defaults totrue: bool?checkEmail(optional): defaults totrue: bool?checkAddress(optional): defaults totrue: bool?checkPhone(optional): defaults totrue: bool?checkSsn(optional): defaults totrue: bool?checkDob(optional): defaults totrue: bool?checkNationality(optional): defaults totrue: bool?
- MLConsent
type: MLConsentType.gdpr or MLConsentType.us
- UserConsent
title: String, title for user consentcontent: String, content for user consent
- CombinedConsent
consentId: String, id for combined consent
- QRScan
showTutorials(optional, defaults totrue): bool?. Show tutorial for QR scan.
- Antifraud
- no additional parameters
- GlobalWatchlist
- no additional parameters
- CustomWatchlist
- no additional parameters
- Aes
uploadDocument(optional, defaults tofalse): bool?.downloadDocument(optional, defaults tofalse): bool?.
- NFCScan
idType(optional):IdType.idorIdType.passport. Id Type which should be used for NFC scanning. If nothing is set, Id Type will be reused if ID Scan module is enabled. If not, ID chooser screen will be presented so user can choose ID type for NFC scanning.showNFCSymbolConfirmationScreen(optional): defaults totrue: bool? If true, a screen asking the user if their document contains an NFC chip will be shown. If disabled, it's recommended to handle this case yourself to prevent a user without an NFC symbol on their passport from getting stuck.showInitialDataConfirmationScreen(optional): defaults totrue: bool? If true, Document OCR data confirmation screen will be shown before the first NFC scan.processNFCData(optional): defaults totrue: bool? If true, the data read from the NFC chip will be used to validate identity. How it's used depends on how the FaceMatch module is configured.
- FaceAuthentication
showTutorials(optional): defaults totrue: bool? If true, a tutorial screen will be shown before starting face authentication.autoCaptureTimeout(optional): defaults to16: number? Timeout in seconds for automatic face capture. If not set, the default timeout will be used.captureAttempts(optional): defaults to3: number? Number of allowed face capture attempts before failing the step.eyesClosedCheck(optional): defaults totrue: bool? If true, the SDK will check if the user's eyes are closed during authentication.headCoverCheck(optional): defaults totrue: bool? If true, the SDK will check for head coverings that may obstruct face recognition.lensesCheck(optional): defaults totrue: bool? If true, the SDK will check if the user is wearing lenses glasses.faceMaskCheck(optional): defaults totrue: bool? If true, the SDK will check if the user is wearing a face mask.
Modules interdependencies
ProcessIdmodule expectsIdScanbothScanStepType.frontorScanStepType.backto have executed.FaceMatchmodule expectsIdScanandSelfieScanto have executed, in order to perform the match. In other words,IdScanandSelfieScanmust precedeFaceMatchVideoSelfiemodule expectsIdScaninfaceMatchmode, orSelfieScaninselfieMatchmode.UserScoremodule should succeed all other modules (must be at the end)Approvemodule should succeed all other modules (must be at the end)- The
UserScoreandApprovemodules do not depend on each other, so their order can be arbitrary. Aesmodule expectsPhone,IdScanandSelfieScanto precede it.
SDK results
Phone
Specify onAddPhoneNumberCompleted to the startOnboarding method, to receive PhoneNumberResult:
phone: String, the phone number user entered
Name
Specify onAddFullNameCompleted to the startOnboarding method, to receive AddFullNameResult:
name: String, the name user entered
Email
Specify onAddEmailCompleted to the startOnboarding method, to receive AddEmailResult:
email: String, the email user entered
IdScan
- Specify
onIdFrontCompleted,onIdBackCompletedto thestartOnboardingmethod, to receiveIdScanResultresult:
image: Captured ID imagebase64Image: String?. Captured front ID in base64 formatcroppedFace: Cropped face from captured ID imagechosenIdType: User chosen type on ID selection screen-idorpassportclassifiedIdType: type of the captured IDidCategory: IdCategory. Category of the scanned IDfailReason: String?. Reason why ID scan failedissueName: String?. Detailed type of the IDissueYear: int?, year when the ID was issuedcountryCode: String?, Country code where the ID was issuedscanStatus: If status has a value other thanIdValidationStatus.okyou can consider the ID scan and/or validation did not come through successfully. Other status messages are:errorClassification,noFacesFound,errorCropQuality,errorGlare,errorSharpness,errorTypeMismatch,userCancelled,unknownError,errorAddress,errorPassportClassification,errorUnacceptableID.
- Specify
onIdProcessedto thestartOnboardingmethod, to receiveStringOCR result:
ocrData: String?. Raw JSON containing full OCR data ie.exteriorNumber,interiorNumber,typeOfId,documentFrontSubtype
SelfieScan
Specify onSelfieScanCompleted to the startOnboarding method, to receive SelfieScanResult:
image: Uint8List?. Captured Selfie imagespoofAttempt: bool.falsemeans that person trying to do selfie is a real person.truemeans it is a spoof attempt, meaning that person is trying to spoof the system by pretending to be someone else using a physical paper, digital photo or other methods.nilmeans that unexpected error happened so it couldn't be determined if the selfie scan was a spoof attempt or not.base64Images: SelfieScanBase64Images. Contains image, in different formats, taken during Selfie ScanselfieBase64: String?. Captured Selfie base64 imageselfieEncryptedBase64: String?. Captured Selfie encrypted base64 image
FaceMatch
Specify onFaceMatchCompleted to the startOnboarding method, to receive FaceMatchResult:
faceMatched: bool.truemeans person's selfie matched successfully with the front ID.falseit means that person's selfie isn't matched with the front ID image.nullit means that front ID image wasn't uploaded at all, so the face match service didn't have data to compare with selfieidCategory: IdCategory. Category of the ID that was used for face match.existingUser: bool. Indicates whether the user is new or existing one.existingInterviewId: String?. If user is existing user this field is populated with existing interview id.
Geolocation
Specify onGeolocationCompleted to the startOnboarding method, to receive GeoLocationResult:
city: String?colony: String?postalCode: String?state: String?street: String?
GovernmentValidation
Specify onGovernmentValidationCompleted to the startOnboarding method, to receive GovernmentValidationResult:
success: bool,trueif the government validation was performed successfully,falseotherwise.
VideoSelfie
Specify onVideoSelfieCompleted to the startOnboarding method, to receive VideoSelfieResult:
success: bool,trueif the video selfie was performed successfully,falseotherwise.
Antifraud
Specify onAntifraudCompleted to the startOnboarding method, to receive AntifraudResult:
success: bool,trueif the antifraud was passed successfully,falseotherwise.
UserScore
Specify onUserScoreFetched to the startOnboarding method, to receive UserScoreResult.
Example UserScoreResult for completion of the module:
{
ovarall: {
value: '0.0/100',
status: 'ok'
},
faceRecognition: {
value: '0.0/100',
status: 'warn',
},
liveness: {
value: '95.2/100',
status: 'manual',
},
idValidation: {
value: '79.0/100',
status: 'fail',
},
}The field status can have one of the following values: warning, unknown, manual, fail and ok.
Approve
Specify onApproveCompleted to the startOnboarding method, to receive ApprovalResult.
success: bool.trueif the approval was successful,falseotherwise.uuid: String?. Customer Id of newly created customer if approval was successful,nullotherwise.customerToken: String?. Customer token for newly created customer if approval was successful,nullotherwise.
Signature
Specify onSignatureCollected to the startOnboarding method, to receive SignatureResult.
signature: Uint8List?. Collected signature image.
Document
Specify onDocumentScanCompleted to the startOnboarding method, to receive DocumentScanResult.
image: Uint8List?. Document scan image.documentType: DocumentType. Type of scanned document.address: Map<String, dynamic>?. Address fetched from the document. Will be available only forDocumentType.addressStatementocrData: Raw JSON containing full OCR data
Captcha
Specify onCaptchaCompleted to the startOnboarding method, to receive CaptchaResult.
captcha: String?. Entered captcha.
CURP
Specify onCurpValidationCompleted to the startOnboarding method, to receive CurpValidationResult.
curp: String?. User's CURP.valid: bool?. Tells if user's CURP is valid. Null means there is no result (user decided to skip).data: Map<String, dynamic>?. User's CURP data.
OCREdit
Specify onOCREditCompleted to the startOnboarding method, to receive OCREditResult.
success: bool.trueif OCREdit completed successfully,falseotherwise.
EKYB
Specify onEKYBCompleted to the startOnboarding method, to receive EKYBResult.
success: bool.trueif eKYB scan completed successfully,falseotherwise.
EKYC
Specify onEKYCCompleted to the startOnboarding method, to receive EKYCResult.
success: bool.trueif eKYC scan completed successfully,falseotherwise.
MLConsent
Specify onMLConsentCompleted to the startOnboarding method, to receive MLConsentResult.
success: bool.trueif the user has given the machine learning consent,falseotherwise.
UserConsent
Specify onUserConsentCompleted to the startOnboarding method, to receive UserConsentResult.
success: bool.trueif the user has given consent,falseotherwise.
CombinedConsent
Specify onCombinedConsentCompleted to the startOnboarding method, to receive CombinedConsentResult.
success: bool.trueif the user has given the data sharing consent,falseotherwise.
QRScan
Specify onQRScanCompleted to the startOnboarding method, to receive QRScanResult.
success: bool.trueif QR scan completed successfully,falseotherwise.
GlobalWatchlist
Specify onGlobalWatchlistCompleted to the startOnboarding method, to receive GlobalWatchlistResult.
success: bool.trueif GlobalWatchlist completed successfully,falseotherwise.
CustomWatchlist
Specify onCustomWatchlistCompleted to the startOnboarding method, to receive CustomWatchlistResult.
success: bool.trueif CustomWatchlist completed successfully,falseotherwise.
Aes
Specify onAesCompleted to the startOnboarding method, to receive AesResult.
success: bool.trueif Aes completed successfully,falseotherwise.error: AesError.
NFCScan
Specify onNFCScanCompleted to the startOnboarding method, to receive NFCScanResult:
success: bool?. A bool value stating if the NFC scan was successful.birthDate: String?. A String in "yyMMdd" format of the date of birth of the document owner.compositeCheckDigit: String?. A character representing the digit used to check the integrity of all the data in the MRZ of the document.dateOfBirthCheckDigit: String?. A character representing the digit used to check the integrity of thebirthDatefield.documentCode: String?. A String representing what type of ICAO 9303 compliant document this is. For example, a passport booklet isTD3. Can be one of:TD1-3,MRVA, orMVRB.documentNumber: String?. A String representing the 9 most significant digits of the passport number, CIC, etc.documentNumberCheckDigit: String?. A character representing the digit used to check the integrity of thedocumentNumberfield.expirationDateCheckDigit: String?. A character representing the digit used to check the integrity of theexpireAtfield.expireAt: String?. A String in "yyMMdd" format of the document's expiration date.gender: String?. A String representing the gender of the document owner. Can be one of:M,F,UNKNOWN, orUNSPECIFIED.issuingStateOrOrganization: String?. A String containing the 3 Letter Code of which authority issued this document. For example, for US Passports, this code is:USA.nationality: String?. A String containing the 3 Letter Code of the document owner's nationality. For example, for UK Passports, this code is:GBR.optionalData1: String?. A String with the contents of the first optional data for TD-1 and 3 style MRZs.optionalData2: String?. An optional String with the contents of the second optional data for TD-1 style MRZs only.personalNumber: String?. A String with the personal number of the document owner if it's encoded inoptionalData1.personalNumberCheckDigit: String?. An optional Char representing the digit used to check the integrity of the personalNumber field. This is only populated if documentCode isTD3.primaryIdentifier: String?. A String representing the primary means of identifying the document. Typically, this is the document owner's last name.secondaryIdentifier: String?. A String representing secondary means of identifying the document. Typically, this is the document owner's other names besides the last.
FaceAuthentication
Specify onFaceAuthenticationCompleted to the startOnboarding method, to receive FaceAuthenticationResult:
status: A bool value stating if the face authentication was successful.customerUUID: String?. The unique identifier of the customer if the face authentication was successful.selfieBase64: String?. The base64 representation of the selfie image taken during face authentication.selfieEncryptedBase64: String?. The encrypted base64 representation of the selfie image taken during face authentication.error: String?. A String describing the error if the face authentication was not successful.
Advanced Usage
If you would like to use SDK in a way that the default flow builder doesn't provide,
you can use SDK APIs for advanced usage where you'll be able to fully customize the experience of the flow,
ie. by calling individual SDK modules, or grouping SDK modules in sections, and returning control to your host application in between.
Setup an onboarding session
Before calling any other Onboarding SDK components it is necessary to setup an onboarding session.
OnboardingSessionConfiguration sessionConfiguration =
OnboardingSessionConfiguration();
IncodeOnboardingSdk.setupOnboardingSession(
sessionConfig: sessionConfiguration,
onError: (String error) {
print('Incode onboarding session error: $error');
},
onSuccess: (OnboardingSessionResult result) {
print('Incode Onboarding session created! $result');
},
);Session configuration can be configured in the same way as explained in the Usage Example section Configure Onboarding session.
Configure section flow
Once the new onboarding session is created (See previous section), you can separate Onboarding SDK flow into multiple sections based on your needs.
IncodeOnboardingFlowConfiguration flowConfig = IncodeOnboardingFlowConfiguration();
flowConfig.addIdScan();Start onboarding section
Once the IncodeOnboardingFlowConfiguration is created call the following method:
IncodeOnboardingSdk.startNewOnboardingSection(
flowConfig: flowConfig,
flowTag: 'idSection',
onError: (String error) {
print('Incode onboarding session error: $error');
},
onIdFrontCompleted: (IdScanResult result) {
print('onIdFrontCompleted result: $result');
},
onIdBackCompleted: (IdScanResult result) {
print('onIdBackCompleted result: $result');
},
onIdProcessed: (String ocrData) {
print('onIdProcessed result: $ocrData');
},
onOnboardingSectionCompleted: (String flowTag) {
print('section completed');
},
);Start flow
Starts the flow based on the OnboardingSessionConfiguration provided - specify the configurationId, and optionally the interviewId if you want to resume a certain onboarding session and/or moduleId to start from a specific step within the flow.
OnboardingSessionConfiguration sessionConfig =
OnboardingSessionConfiguration(
configurationId: "YOUR_CONFIGURATION_ID",
interviewId: "YOUR_INTERVIEW_ID"); // optional
IncodeOnboardingSdk.startFlow(
sessionConfig: sessionConfig,
moduleId: 'YOUR_MODULE_ID', // optional, ie. "PHONE"
onError: (String error) {
print('Incode startFlow error: $error');
},
onSuccess: () {
print('Incode startFlow completed!');
},
onUserCancelled: () {
print('User cancelled');
},
);
Start flow from deep link
Starts the flow based on the deeplink URL. This method will read configurationId, interviewId and a step from which it should start.
IncodeOnboardingSdk.startFlowFromDeepLink(
url: 'YOUR_DEEPLINK_URL',
onError: (String error) {
print('Incode startFlowFromDeepLink error: $error');
},
onSuccess: () {
print('Incode startFlowFromDeepLink completed!');
},
onUserCancelled: () {
print('User cancelled');
},
);
Finish onboarding session
Make sure to call finishFlow() at the end of the flow (when you are sure user has finished all onboarding modules and you won't be reusing same interviewId again).
IncodeOnboardingSdk.finishFlow();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 need 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.
IncodeOnboardingSdk.startFaceLogin(
faceLogin: FaceLogin(customerUUID: "yourCustomerUUID"),
onSuccess: (FaceLoginResult result) {
print(result);
},
onError: (String error) {
print(error);
},
);FaceLoginResult will contain:
- image: selfie image
- spoofAttempt: boolean that indicates if user tried to spoof the system
- base64Images: base64 representations of the selfie image
- faceMatched: boolean that indicates if the faces matched
- customerUUID: unique user identifier if the user successfully authenticated
- interviewId: sessionId in which the user got approved
- interviewToken: session token in which the user got approved
- token: token that can be used for further API calls
- transactionId: unique identifier of face login attempt
- hasLenses: indicator if login attempt failed due to person wearing lenses
- hasFaceMask: indicator if login attempt failed due to person wearing a face mask.
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.
IncodeOnboardingSdk.startFaceLogin(
faceLogin: FaceLogin(),
onSuccess: (FaceLoginResult result) {
print(result);
},
onError: (String error) {
print(error);
},
);FaceLoginResult will contain:
- image: selfie image
- spoofAttempt: boolean that indicates if user tried to spoof the system
- base64Images: base64 representations of the selfie image
- faceMatched: boolean that indicates if the faces matched
- customerUUID: unique user identifier if the user successfully authenticated
- interviewId: sessionId in which the user got approved
- interviewToken: session token in which the user got approved
- token: token that can be used for further API calls
- transactionId: unique identifier of face login attempt
Face Login parametrization
Authorization modes
By default Face Login will perform server spoof and face recogniton check.
In order to optimize and speed up Face Login there are two other options that you can provide to FaceLogin parameter faceAuthMode: FaceAuthMode.hybrid and FaceAuthMode.local.
FaceAuthMode.hybrid will perform spoof check locally on the device, and if it is successful it will perform server face recognition check.
FaceAuthMode.local will perform both spoof check and face recognition check locally on the device, thus making it possible to authenticate users while being offline. Prerequisite for a successful offline face login is that the user was onboarded and approved on the same device.
To use FaceAuthMode.local mode on Android please add 'com.incode.sdk:model-liveness-detection:2.0.0' and 'com.incode.sdk:model-face-recognition:2.0.0' depenendcies to your app/build.gradle file.
To perform a one-time server authentication in case a user isn't found locally on the device during FaceAuthMode.local execution, specify faceAuthModeFallback to true. It works only in 1:1 Face Login mode.
To adjust spoof and recognition thresholds for FaceAuthMode.local and FaceAuthMode.hybrid modes, specify spoofThreshold and recognitionThreshold params to FaceLogin object.
FaceAuthMode.kiosk will perform only face recognition check on the server. It is currently only supported on Android platform.
To use FaceAuthMode.kiosk mode on Android please add 'com.incode.sdk:kiosk-login:1.0.0' dependency to your app/build.gradle file.
Face mask check
By default Face Login won't detect if people wear face masks.
To enable face mask check specify faceMaskCheck parameter to true in FaceLogin.
To use faceMaskCheck in Android please add 'com.incode.sdk:model-mask-detection:2.0.0' dependency to your app/build.gradle file.
Leneses check
By default Face Login will detect if people wear lenses.
To disable lenses check specify lensesCheck parameter to false in FaceLogin.
Log Authentication attempts
By default each authentication attempt is logged, and some statistics info like device used is being tracked.
Specify logAuthenticationEnabled false if you want to disable this to get faster performing authentications.
Manipulating locally stored identities
To be able to authenticate multiple users using 1:N and FaceAuhtMode.local mode you'll need to add these users to the local database. This section will describe which methods you can use to perform CRUD operations with locally stored identities.
Add Face
To add a single identity to the local dabtase, use addFace method and provide a FaceInfo object, that contains:
faceTemplate: String -> biometric representation of a user's facecustomerUUID: String -> unique customer identifer in Incode's databasetemplateId: String -> unique identifier of a biometric representation of a user's face in Incode's database
FaceInfo faceInfo = FaceInfo(faceTemplate: template,
customerUUID: uuid,
templateId: templateId)
IncodeOnboardingSdk.addFace(
faceInfo: faceInfo,
onSuccess: (bool result) {
print(result);
},
onError: (String error) {
print(error);
});Remove Face
To remove a single identity from the local database use removeFace method and provide a customerUUID:
IncodeOnboardingSdk.removeFace(
customerUUID: "your_customer_uuid",
onSuccess: (bool result) {
print(result);
},
onError: (String error) {
print(error);
});Get faces
To fetch all currently stored identities use getFaces method.
IncodeOnboardingSdk.getFaces(
onSuccess: (List<FaceInfo> faceInfos) => {
print("faceInfos: $faceInfos")},
onError: (String error) {
print(error);
});Set multiple faces
To add multiple identities at once you can use setFaces method and provide a list of FaceInfo objects, but keep in mind it will firstly wipe out all currently stored identities.
FaceInfo faceInfo =
FaceInfo("your_face_template", "your_customer_uuid", "your_template");
FaceInfo faceInfo2 =
FaceInfo("your_face_template2", "your_customer_uuid2", "your_template2");
final faceInfos = <FaceInfo>[
FaceInfo("your_face_template", "your_customer_uuid", "your_template"),
FaceInfo("your_face_template2", "your_customer_uuid2", "your_template2")
];
IncodeOnboardingSdk.setFaces(
faces: faceInfos,
onSuccess: (bool result) => {print("result: $result")},
onError: (String error) {
print(error);
});Clear face database
To clear local database use setFaces method and provide empty FaceInfo list of objects.
IncodeOnboardingSdk.setFaces(
faces: List.empty(),
onSuccess: (bool result) => {print("result: $result")},
onError: (String error) {
print(error);
});Non-UI ID Processing API
Processes IDs programmatically without displaying a user interface
IncodeOnboardingSdk.idProcess(
idCategory: IdCategory.primary,
onSuccess: (IdProcessResult result) {
print(result);
},
onError: (String error) {
print(error);
},
);IdProcessResult will contain:
ocrData: String?. Raw JSON containing full OCR data ie.exteriorNumber,interiorNumber,typeOfId,documentFrontSubtype
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. Set Up a Custom Server for E2EE
Initialize the SDK with a custom server for E2EE as follows:
IncodeOnboardingSdk.init(
apiKey: 'YOUR_API_KEY',
apiUrl: 'YOUR_API_URL',
e2eeUrl: 'YOUR E2EE URL HERE',
);2. Enable E2EE via OnboardingSessionConfiguration
OnboardingSessionConfiguration sessionConfig = OnboardingSessionConfiguration(e2eEncryptionEnabled: true);3. Pass the OnboardingSessionConfiguration Object
You can pass the OnboardingSessionConfiguration object to SDK when setup onboarding session:
IncodeOnboardingSdk.setupOnboardingSession(
sessionConfig: sessionConfiguration,
);or when starting a flow:
IncodeOnboardingSdk.startOnboarding(
sessionConfig: sessionConfig,
flowConfig: flowConfig,
);Customization
To change theme and resources (text, images and videos) on Android platform please look at a guide here.
To change resources on iOS platform please look at a guide here.
To change theme on iOS platform specify json theme configuration and call IncodeOnboardingSdk.setTheme(theme: theme):
Map<String, dynamic> theme = {
"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": "#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
}
}
},
"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
},
"separator": {
"alpha": 1.0,
"color": "#20263D",
"cornerRadius": 0,
"padding": 24,
"thickness": 1
},
"signature": {
"signatureColor": "#04BD19",
"canvasBorderColor": "#EC03FC"
},
"idAutocaptureCountdown": {
"backgroundColor": "#00B2FD",
"numberColor": "#FFFFFF"
}
},
};
IncodeOnboardingSdk.setTheme(theme: theme);Both platforms support the customization of ID v2 experience via IncodeOnboardingSdk.setTheme(theme: theme):
Android configuration guide for ID V2 scan flow can be found here.
iOS configuration guide for ID V2 scan flow can be found here.
Using SDK without an API KEY
To use the SDK without an API KEY, please follow these steps:
- provide only a specific
apiUrlonly to theinitmethod. - Afterwards, configure
OnboardingSessionConfigurationwith atoken - Provide it either to the
startOnboarding, or if you're using sections to thesetupOnboardingSessionand then start your sections.
Example code that showcases steps 1) and 2:
IncodeOnboardingSdk.init(
apiUrl: 'https://demo-api.incodesmile.com/0/',
onError: (String error) {
print('Incode SDK init failed: $error');
setState(() {
initSuccess = false;
});
},
onSuccess: () {
// Update UI, safe to start Onboarding
print('Incode initialize successfully!');
OnboardingSessionConfiguration sessionConfiguration = OnboardingSessionConfiguration(token: "YOUR_TOKEN");
// call `startOnboarding` or `setupOnboardingSession` and then start sections.
},
);Other Public API methods
SDK Mode
You can choose between two modes: SdkMode.standard and SdkMode.captureOnly. SdkMode.standard is the default, but if you would like to skip image upload and server validations for id and selfie scan you can specify captureOnly mode using method:
IncodeOnboardingSdk.setSdkMode(sdkMode: SdkMode.captureOnly);Allowing user to cancel the flow
You can use showCloseButton method to display an 'X' button on the top right of each module, so that user can cancel the flow at any point:
IncodeOnboardingSdk.showCloseButton(allowUserToCancel: true);Tracking events
- When onboarding has been started, information about events used to track all the user steps in their flow can be obtained using
onEventscallback.
Specify onEvents to the startOnboarding method, to receive OnEventsResult:
event: String - Unique identifier of the eventdata: String? - JSON string with additional event details
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'.
IncodeOnboardingSdk.setLocalizationLanguage('es');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: Map<String, dynamic>. Map of string keys and its values.
Map<String, dynamic> strings = {
/// iOS labels
'incdOnboarding.idChooser.title': 'My Custom chooser title',
/// Android labels
'onboard_sdk_id_type_chooser_title': 'My Custom chooser title',
};
IncodeOnboardingSdk.setString(strings: strings);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://developer.incode.com/docs/localization-guide#list-of-localizable-texts
For Android please check documentation here:
https://developer.incode.com/docs/user-guide-customization#32-dynamic-localization
Get Score API
You can use getUserScore method to fetch current onboarding session user score at any point:
IncodeOnboardingSdk.getUserScore(
onSuccess: (UserScoreResult result) {
print("userScore: $result");
},
onError: (String error) {
print("userScore error: $error");
});UserScoreResult has extendedUserScoreJsonData String field which contains full user data in a json format.
AddNom151Archive API
You can use addNOM151Archive method to generate and fetch Nom151Archive:
IncodeOnboardingSdk.addNOM151Archive(
onSuccess: (AddNom151Result addNom151Result) {
String? signature = addNom151Result.signature;
String? archiveUrl = addNom151Result.archiveUrl;
}, onError: (String error) {
print('Incode addNOM151Archive error: $error');
});AddNom151Result contains two String fields signature and archiveUrl as an and result.
Get user OCR data API
You can use getUserOCRData method to fetch user OCR data for a specific session:
IncodeOnboardingSdk.getUserOCRData(
token: "{SESSION_TOKEN}",
onSuccess: (GetUserOCRDataResult result) {
print(result); //
},
onError: (String error) {
print(error);
},
);GetUserOCRDataResult contains a String field ocrData, which represents full OCR data in a JSON format.
Running the example app
To run the example app, follow these steps:
- Navigate to root of the example folder. Create .env file. The file is added in .gitignore so it won't be pushed to the repository. It is used to store your own credentials. Example of the .env file content:
# Demo
DEMO_API_URL=YOUR_API_URL
DEMO_API_KEY=YOUR_API_KEY
DEMO_COMBINED_CONSENT_ID=YOUR_COMBINED_CONSENT_ID
DEMO_WORKFLOW_CONFIGURATION_ID=YOUR_WORKFLOW_CONFIGURATION_ID
DEMO_FLOW_CONFIGURATION_ID=YOUR_FLOW_CONFIGURATION_ID
DEMO_DEEP_LINK=YOUR_DEEP_LINK
# SaaS
SAAS_API_URL==YOUR_API_URL
SAAS_API_KEY=YOUR_API_KEY
SAAS_COMBINED_CONSENT_ID=YOUR_COMBINED_CONSENT_ID
SAAS_WORKFLOW_CONFIGURATION_ID=YOUR_WORKFLOW_CONFIGURATION_ID
SAAS_FLOW_CONFIGURATION_ID=YOUR_FLOW_CONFIGURATION_ID
SAAS_DEEP_LINK=YOUR_DEEP_LINK
- Run
flutter pub getto install dependencies. - Run the following commands to generate corresponding files for those env values:
flutter pub run build_runner clean
flutter pub run build_runner build --delete-conflicting-outputs
- The mandatory values to run the app properly are
apiKeyandapiUrl. Replace the other values in home.dart based on your needs. - Run the app.
Known issues
- Running the app on iOS simulator from VSCode isn't supported currently. Please run the app from Xcode for now if you want to test it on iOS Simulator.
NOTE: Don't forget to settestModetotruebefore running the app.
Updated 26 days ago
