Migration Guide

Migration guide

Migration to 4.2.0

Updates to document chooser behavior in IdScan module

The visibility of the document chooser screen is now controlled only by the "Show document chooser screen" flag on the Dashboard or showIdTypeChooser in the SDK. Setting idType alone no longer hides the chooser and will be ignored.

If you previously pre-set idType (either using idType: ... in the SDK or via the Dashboard) and expected the chooser to be hidden, you must now explicitly disable it or update the Flow configuration accordingly:

{
  module: "addId",
  idType: "passport",
  showIdTypeChooser: "false"
}

Android color palette changes

If you previously customized the application appearance using a config JSON:

{
    "colorPalette": {
        "negative500": "#FF5A5F",
        "negative600": "#E71111",
        "positive500": "#189F60",
        "positive600": "#189F60"
    }
}

These keys have now been migrated to the following values:

  • negative500 -> negative400
  • negative600 -> negative500
  • positive500 -> positive400
  • positive600 -> positive500

iOS color palette changes

V2 theme default colorPalette values and the JSON keys used for positive and negative semantic colors have changed. If you customize the V2 theme, update your palette to match About Colors in the iOS Customization Guide v2.

ID Capture V2 - Error Screen Customization for Android

Wrong document side customization:

If you previously customized the Wrong document side error screen, add the following new string resources:

Add these strings:

<string name="onboard_sdk_id_capture_error_side_front">Capture the front side of the ID</string>
<string name="onboard_sdk_id_capture_error_side_back">Capture the back side of the ID</string>

Previous string:

<string name="onboard_sdk_id_capture_error_side">You’ve scanned the wrong document side. Please scan your document again.</string>

This string is no longer used.

No internet connection customization:

If you previously customized the No internet connection error screen, add the following new string resource:

Add this string:

<string name="onboard_sdk_no_internet_title">No internet connection</string>

Previous string:

<string name="onboard_sdk_id_capture_error_title">There was a problem</string>

The previously used string is still in use for other error screens and should be kept in your resources.

Retry button customization:

The retry button is now customized using a different string resource:

<string name="onboard_sdk_id_capture_retry">Refresh</string>

Previous string:

<string name="onboard_sdk_no_network_snackbar_action_text">Retry</string>

The previously used string is still in use for other error screens and should be kept in your resources.

Selfie V2 - Error Screen Customization for Android

No internet connection customization:

If you previously customized the No internet connection error screen, add the following new string resource:

Add this string:

<string name="onboard_sdk_no_internet_title">No internet connection</string>

Previous string:

<string name="onboard_sdk_face_scan_failed_feedback_selfie_capture_failed_title">There was a problem</string>

The previously used string is still in use for other error screens and should be kept in your resources.

Changes in behavior for device environment detection for Android

The behavior when detecting device environment vulnerabilities has changed:

  • Hook or virtual environment detection: Detecting hook or virtual environment vulnerabilities in the SDK triggers a native crash, which cannot be caught or handled by application code, resulting in immediate app termination.
  • Emulator and root detection: The flow is not aborted when emulator and root checks are detected. The onboarding process continues normally.

API Changes

The following initializeSDK() method optional parameters have been removed:

  • disableVirtualEnvironmentDetection
  • disableRootDetection
  • disableEmulatorDetection
  • disableHookCheck

If you were using these parameters in your code, remove them from your initializeSDK() method call as device environment checks can no longer be disabled.

Added ability to pass SessionConfig to startFaceLogin() method for Android

Now you can supply an optional sessionConfig parameter to the startFaceLogin(), like this:

  let sessionConfig = {}; // Optional

  cordova.exec(
    function (result) {
      console.log("Face login Success: " + result);
    },
    function (error) {
      console.log("Face login Error: " + error);
    }, 
    "Cplugin", 
    "startFaceLogin",
    [sessionConfig]
  );

This allows enabling of end-to-end encryption (E2EE) in Face Login mode on Android.

Added ability to pass showIdTypeChooser parameter to the addId module

Now you can supply an optional showIdTypeChooser parameter to the addId module. It will be used by the SDK to decide whether to show the document type chooser. By default, if not supplied, showIdTypeChooser param is true.

{
  module: "addId", 
  idType: "passport", 
  showIdTypeChooser: "false"
}

setupOnboardingSession now accepts a session config object

The setupOnboardingSession method now expects a JSON object as the first argument instead of a plain string configurationId.

If you previously passed configurationId as a string, the method will silently fall back to an empty session configuration, which may cause unexpected behavior.

Before:

cordova.exec(resolve, reject, "Cplugin", "setupOnboardingSession", ["your-config-id"]);

After:

var sessionConfig = {
  configurationId: "your-config-id",
  // other optional fields:
  // token: "...",
  // e2eEncryptionEnabled: true,
  // mergeSessionRecordings: false,
  // validationModules: [...],
  // externalId: "...",
  // externalCustomerId: "...",
  // interviewId: "...",
};
cordova.exec(resolve, reject, "Cplugin", "setupOnboardingSession", [sessionConfig]);

Migration: Wrap your configurationId (and any other session parameters) in a JSON object and pass that object as the first element of the arguments array.

The same applies to startWorkflow and startFlow, which also accept a session config object as the first argument.

Updated startOnboardingSection method with additional parameters

You now have to provide recordSessionConfig and sectionTag parameters when calling startOnboardingSection to set the session recording configuration and section tagging.

Expected crashes when running in a virtual environment on Android

It is expected that the app crashes with the following stacktraces when a virtual environment is used. For example:

java.lang.NullPointerException
	at com.incode.welcome_sdk.ThemeConfiguration$Builder.setLabelSmallStyle(SourceFile:1066)
	at com.incode.welcome_sdk.f.c(SourceFile:150)
	at com.incode.welcome_sdk.data.local.m.as(SourceFile:22)
	at com.incode.welcome_sdk.IncodeWelcome.startOnboardingSection(SourceFile:18)
java.lang.NullPointerException: Attempt to get length of null array
	at com.incode.welcome_sdk.data.IncodeWelcomeRepository.d(SourceFile:320)
	at com.incode.welcome_sdk.data.IncodeWelcomeRepository.i(SourceFile:214)

Selfie V2 - No Internet Error Screen Retry Button Change on Android

Retry button customization:

The retry button label shown on the Selfie Scan no internet error screen now uses a dedicated string resource:

<string name="onboard_sdk_face_scan_retry">Refresh</string>

Previous string:

<string name="onboard_sdk_try_again">Try again</string>

If you override onboard_sdk_try_again to customize the retry button on the no internet screen, you must now override onboard_sdk_face_scan_retry instead. The onboard_sdk_try_again string is still used for other retry scenarios.

Selfie V2 - Capture-Only Mode Success Screen Text Change on Android

Success label customization:

In capture-only mode, the Selfie Scan success screen now uses a different string resource:

<string name="onboard_sdk_face_captured">Face captured!</string>

Previous string:

<string name="onboard_sdk_enroll_success">Success!</string>

The previously used string is still in use for non-capture-only mode and should be kept in your resources.

ID Capture and Selfie V2 - Permission Open Settings Screen Text Change on Android

Open settings button customization:

The Open settings label shown on the Permission open settings screen now uses a dedicated string resource:

<string name="onboard_sdk_permission_allow_permission_action">Allow permission</string>

Previous string:

<string name="onboard_sdk_permission_open_setting_action">Open settings</string>

The previously used string is still in use for the Geolocation module and should be kept in your resources.

String Customization on iOS

Removed localization key incdOnboarding.curp.add.generate

Renamed localization keys:

  • incdOnboarding.curp.generation.last.name.placeholder -> incdOnboarding.curp.generation.first.last.name.placeholder
  • incdOnboarding.curp.generation.name.placeholder -> incdOnboarding.curp.generation.first.name.placeholder

Migration to 4.1.0

Upload error screen customization on Android:

If you previously customized the upload error screen, add the following new string resource:

Add this string: <string name="onboard_sdk_validation_error_button_text">Scan your ID</string>

Previous string: <string name="onboard_sdk_id_capture_tutorial_title">Scan your ID</string>

This string is now used only for customizing the ID Capture V2 tutorial screen title.

Changed default values in FaceMatch module config on Android (optional)

With the move to UxV2, the showUserExists config is now false by default.

Migrate any custom ThemeConfiguration to the V2 equivalent on Android

If your previous integration had any UI customization in supported modules through Theme Configuration, these customizations will now need to be migrated to the equivalents in UXv2. See the Migrating Theme Configurations to UXv2 Guide for more details.

Migration to 4.0.0

Update string resources for the "Need Help" screen in the IdScan v2 module on Android

The "Need Help" screen has been redesigned on Android, and the customizable strings have been replaced. If you override any of the following strings in your app, replace them with the new ones listed below.

No action is required if you do not override these strings.

Replaced string resources

Replace overrides of:

<string name="onboard_sdk_id_capture_help_title">Need help?</string>
<string name="onboard_sdk_id_capture_help_subtitle">Some considerations</string>
<string name="onboard_sdk_id_capture_help_manual_photo_button_text">Take the photo manually</string>
<string name="onboard_sdk_id_capture_help_align_title">Center your document in the frame</string>
<string name="onboard_sdk_id_capture_help_align_subtitle">The photo will be taken automatically</string>
<string name="onboard_sdk_id_capture_help_blur_title">Avoid blurriness on the document</string>
<string name="onboard_sdk_id_capture_help_blur_subtitle">Zoom in and out, or tap on the document</string>
<string name="onboard_sdk_id_capture_help_glare_title">Avoid glare on the document</string>
<string name="onboard_sdk_id_capture_help_glare_subtitle">Find a better lighting to avoid reflections</string>
<string name="onboard_sdk_id_capture_help_darkness_title">Avoid darkness on the document</string>
<string name="onboard_sdk_id_capture_help_darkness_subtitle">Find a place with better lighting</string>

with:

<string name="onboard_sdk_id_capture_common_issues_title">Common issues</string>
<string name="onboard_sdk_id_capture_common_issues_glare_title">Glare present</string>
<string name="onboard_sdk_id_capture_common_issues_glare_subtitle">Tilt the ID slightly up or down to minimize the reflection</string>
<string name="onboard_sdk_id_capture_common_issues_blur_title">Blur present</string>
<string name="onboard_sdk_id_capture_common_issues_blur_subtitle">Move ID further away or closer to your phone until the image is focused</string>
<string name="onboard_sdk_id_capture_common_issues_info_not_readable_title">Info is not readable</string>
<string name="onboard_sdk_id_capture_common_issues_info_not_readable_subtitle">Minimize camera shake by holding your phone steady</string>
<string name="onboard_sdk_id_capture_common_issues_try_again_button">@string/onboard_sdk_try_again</string>

Upgrade compileSdk on Android

With the update of the internal CameraX dependencies, you will need to upgrade your project's compileSdk to level 35:

compileSdk 35

Update Gradle Wrapper on Android

Android Gradle Wrapper 8.6.0 requires Gradle 8.7 or higher. Update your Gradle wrapper configuration in gradle/wrapper/gradle-wrapper.properties:

distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip

If you use any of the following optional dependencies on Android, make sure to update to the latest versions

implementation 'com.incode.sdk:nfc:1.5.2'

Response Key Name Changes (Breaking Changes)

This version introduces breaking changes to ensure cross-platform consistency between Android and iOS response structures. The following response keys have been renamed:

Phone Number Module

Before:

{
  "phone": {
    "phone": "+1234567890"
  }
}

After:

{
  "phoneData": {
    "phone": "+1234567890"
  }
}

Migration: Update your code to use phoneData instead of phone when accessing phone number results.

  cordova.exec(function(winParam) {
-   const phoneNumber = winParam.phone.phone;
+   const phoneNumber = winParam.phoneData.phone;
  }, function(err) {
    console.log("Error: "+ err);
  }, "Cplugin", "startOnboardingSection", [{"module":"addPhone"}]);

Signature Module

Before:

{
  "signaturePath": {
    "status": "success"
  }
}

After:

{
  "signatureData": {
    "status": "success"
  }
}

Migration: Update your code to use signatureData instead of signaturePath when accessing signature results.

  cordova.exec(function(winParam) {
-   const status = winParam.signaturePath.status;
+   const status = winParam.signatureData.status;
  }, function(err) {
    console.log("Error: "+ err);
  }, "Cplugin", "startOnboardingSection", [{"module":"addSignature"}]);

Face Match Module - Existing User Field

Before:

{
  "faceMatchData": {
    "status": "match",
    "confidence": 1,
    "isExistingUser": true,
    "isFaceMatched": true,
    "isNameMatched": true
  }
}

After:

{
  "faceMatchData": {
    "status": "match",
    "confidence": 1,
    "existingUser": true,
    "isFaceMatched": true,
    "isNameMatched": true
  }
}

Migration: Update your code to use existingUser instead of isExistingUser when accessing face match results.

  cordova.exec(function(winParam) {
-   const isExisting = winParam.faceMatchData.isExistingUser;
+   const isExisting = winParam.faceMatchData.existingUser;
  }, function(err) {
    console.log("Error: "+ err);
  }, "Cplugin", "startOnboardingSection", [{"module":"addFaceMatch"}]);

Geolocation Module

Before:

{
  "geodata": {
    "addressFields": {
      "city": "Belgrade",
      "colony": "Zvezdara",
      "postalCode": "",
      "street": "Banjska",
      "state": ""
    }
  }
}

After:

{
  "geoLocationData": {
    "addressFields": {
      "city": "Belgrade",
      "colony": "Zvezdara",
      "postalCode": "",
      "street": "Banjska",
      "state": ""
    }
  }
}

Migration: Update your code to use geoLocationData instead of geodata when accessing geolocation results.

  cordova.exec(function(winParam) {
-   const city = winParam.geodata.addressFields.city;
+   const city = winParam.geoLocationData.addressFields.city;
  }, function(err) {
    console.log("Error: "+ err);
  }, "Cplugin", "startOnboardingSection", [{"module":"addGeolocation"}]);

User Consent Module (New Standardized Key)

Before:

// User consent result was previously returned inconsistently or not at all

After:

{
  "userConsentData": {
    "status": true
  }
}

Migration: If you're using the user consent module, the result is now consistently returned under the userConsentData key on both platforms.

  cordova.exec(function(winParam) {
    const consentGiven = winParam.userConsentData.status;
    // Process consent status
  }, function(err) {
    console.log("Error: "+ err);
  }, "Cplugin", "startOnboardingSection", [
    {"module":"addUserConsent", "title":"Privacy Policy", "content":"..."}
  ]);

Why These Changes?

These changes ensure that the JavaScript layer receives identical response structures from both Android and iOS platforms, making it easier to write cross-platform code without platform-specific conditionals.

Document Validation Module - documentData Structure

After (Version 4.0.0):

{
  "documentData": {
    "type": "addressStatement",     
    "image": "<base64String>",      
    "address": {                    
      "city": "",
      "colony": "",
      "postalCode": "",
      "street": "",
      "state": ""
    },
    "data": "<rawData>"            
  }
}

Migration: The structure is now standardized with clear field names. The type field indicates the document type (e.g., "addressStatement", "medicalDoc", "paymentProof"), image contains the base64-encoded image, and address contains structured address information when available.

ID Scan Module - frontIdData and backIdData Structure

Before:

{
  "frontIdData": {
    "scanStatus": "success",
    "idImageBase64": "<base64String>",
    // ... other Gson-serialized fields
  }
}

After (Version 4.0.0):

{
  "frontIdData": {
    "status": "ok",                   // Renamed from 'scanStatus'. On success: "ok", on error: "unknown", "errorClassification", "errorGlare", "errorSharpness", "errorReadability", "errorInCapture" (iOS only), "errorUnacceptableID" (iOS only), "wrongSide" (iOS only)
    "image": "<base64String>",        // Renamed from 'idImageBase64'
    "classifiedIdType": "ID",         // Classified document type
    "idCategory": "primary",          // 'primary' or 'secondary'
    "chosenIdType": "id"             // Chosen ID type: 'id' or 'passport'
  }
}

Migration: Update your code to use the new field names:

  cordova.exec(function(winParam) {
-   const scanStatus = winParam.frontIdData.scanStatus;
+   const scanStatus = winParam.frontIdData.status;
-   const idImage = winParam.frontIdData.idImageBase64;
+   const idImage = winParam.frontIdData.image;
+   const idCategory = winParam.frontIdData.idCategory;
  }, function(err) {
    console.log("Error: "+ err);
  }, "Cplugin", "startOnboardingSection", [{"module":"addFrontId"}]);

Note: The same structure applies to backIdData.

ID Process Module - processIdData Structure

After (Version 4.0.0):

{
  "processIdData": {
    "extendedOcrData": "<jsonString>",  // Extended OCR data as JSON string
    "data": {                            // Structured OCR data
      "address": {                       // Address fields
        "city": "",
        "colony": "",
        "postalCode": "",
        "street": "",
        "state": ""
      },
      "fullAddress": "",                 // Complete address string
      "birthDate": 0,                    // Timestamp in milliseconds
      "expirationDate": 0,               // Unix timestamp
      "gender": "",
      "name": "",                        // Full name
      "issueDate": 0,                    // Unix timestamp
      "numeroEmisionCredencial": ""      // Credential emission number
    }
  }
}

Migration: The OCR data is now structured with clear field names and types. Date fields are provided as timestamps for easier manipulation. Access the structured data through the data field:

cordova.exec(function(winParam) {
  const ocrData = winParam.processIdData.data;
  const fullName = ocrData.name;
  const birthDate = new Date(ocrData.birthDate);
  const address = ocrData.address.city;
}, function(err) {
  console.log("Error: "+ err);
}, "Cplugin", "startOnboardingSection", [{"module":"processId"}]);

Selfie Scan Module - selfieData Structure

After (Version 4.0.0):

{
  "selfieData": {
    "status": "success",           
    "image": "<base64String>",     
    "spoofAttempt": false         
  }
}

Migration: The structure now includes explicit status and spoof detection fields for better fraud prevention handling.

Government Validation Module - govresult Structure

Before:

{
  "govresult": true  
}

After (Version 4.0.0):

{
  "govresult": {
    "status": true  
  }
}

Migration: Update your code to access the status field within the govresult object:

  cordova.exec(function(winParam) {
-   const isValidated = winParam.govresult;
+   const isValidated = winParam.govresult.status;
  }, function(err) {
    console.log("Error: "+ err);
  }, "Cplugin", "startOnboardingSection", [{"module":"governmentValidation"}]);

Approve Module - approveData Structure

After (Version 4.0.0):

{
  "approveData": {
    "status": "approved",           
    "id": "<uuid>",                 
    "customerToken": "<token>"     
  }
}

Migration: The approve result is now structured with clear field names. Previously all fields from the ApproveResult object were serialized via Gson. Now only the essential fields are exposed with consistent naming.

cordova.exec(function(winParam) {
  const approvalStatus = winParam.approveData.status;
  const sessionId = winParam.approveData.id;
  const token = winParam.approveData.customerToken;
}, function(err) {
  console.log("Error: "+ err);
}, "Cplugin", "startOnboardingSection", [{"module":"approve"}]);

NFC Scan Module - nfcData Structure

After (Version 4.0.0):

{
  "nfcData": {
    "birthDate": "",                        
    "compositeCheckDigit": "",              
    "dateOfBirthCheckDigit": "",            
    "documentCode": "",                     
    "documentNumber": "",                  
    "documentNumberCheckDigit": "",          
    "expirationDateCheckDigit": "",         
    "expireAt": "",                         
    "gender": "",                           
    "issuingStateOrOrganization": "",       
    "nationality": "",                      
    "optionalData1": "",                    
    "optionalData2": "",                    
    "personalNumber": "",                   
    "personalNumberCheckDigit": "",         
    "primaryIdentifier": "",                
    "secondaryIdentifier": "",              
    "status": true                          
  }
}

Migration: The NFC data structure provides comprehensive passport/ID chip information read from NFC-enabled documents. All fields are extracted from the MRZ (Machine Readable Zone) and chip data.

Migration to 3.0.0

  • It is mandatory that all sample apps now have to provide a source from where to fetch Incode's Android dependency from. For suggested method please check out the README.md page and its Additional Steps for Android section.

Migration to 2.9.0

Optional dependencies

For Android, if you use any of the following optional dependencies, make sure to update to the latest versions

implementation 'com.incode.sdk:video-streaming:1.6.0'
implementation 'com.incode.sdk:extensions:1.2.1'
implementation 'com.incode.sdk:model-face-recognition:3.5.1'
implementation 'com.incode.sdk:model-id-face-detection:3.5.1'
implementation 'com.incode.sdk:model-liveness-detection:3.2.1'

Android minSdk changes

For Android, if you use the video-streaming dependency, you need to upgrade your minSdk to 24 or higher. The requirement is coming from the OpenTok dependency, which now requires a minimum SDK version of 24. This update is necessary to ensure compatibility with the 16KB page size support mandated by Google starting from November 1st 2025. More info (https://developer.android.com/guide/practices/page-sizes).

Migration to 2.7.0

For Android, if you use any of the following optional dependencies, make sure to update to the latest versions

implementation 'com.incode.sdk:model-face-recognition:3.5.0'
implementation 'com.incode.sdk:model-id-face-detection:3.5.0'

The qr-face-login dependency is no longer available and has been removed in this version of the SDK. Please update your project configuration accordingly. Remove the qr-face-login dependency from your build.gradle:

  • Update Android minSdkVersion in you Android projects's build.gradle:
  buildscript {
    ext {
-    minSdkVersion = 21
+    minSdkVersion = 23
    }
  }

Remove com.incode.sdk:camera:1.1.0 dependency in your app’s build.gradle file:

  dependencies {
-    implementation 'com.incode.sdk:camera:1.1.0'
  }

Migration to 2.5.0

  • Update Android to compileSdk=34. It can be done by updating cordova-android package in package.json:
+ "cordova-android": "^13.0.0",
  • Update iOS deployment target to minimum version 13.0 and swift version to 5.0. Update config.xml:
+ <platform name="ios">
+    <preference name="SwiftVersion" value="5.0" />
+    <preference name="deployment-target" value="13.0" />
+ </platform>