full_identity_verification 2.1.8 copy "full_identity_verification: ^2.1.8" to clipboard
full_identity_verification: ^2.1.8 copied to clipboard

Flutter plugin for Blusalt Full Identity Verification SDK that supports both Android and iOS platforms.

full_identity_verification #

Full Identity Verification SDK for Android and iOS — document scanning combined with liveness detection.

Get your credentials from Blusalt

Features #

SDK Modes #

1. Full Identity SDK (Document Present)

The user physically scans their document. The SDK extracts document data and runs a liveness check in a single flow. Optionally filter which document types are available.

2. Document Absent — Custom Selector

No physical document is available. The user selects their document type from a list you provide, enters their ID number, and completes a liveness check.

3. Document Absent — ID Number

No physical document is available. You already know the document type and number; pass them directly and the SDK runs only the liveness check.


Liveness Types (LivenessFacialComparisonType) #

Value Description
dynamic User performs head movements (open mouth, shake head). Strictest — static images are detected and rejected.
action User performs a prompted action. High security.
varifocal Camera-based depth detection. Good balance of speed and security.
flash Screen-flash method. Works well in low-light conditions.

Usage #

dependencies:
  full_identity_verification: ^2.1.4
import 'package:full_identity_verification/full_identity_verification.dart';
import 'package:full_identity_verification/enums.dart';
import 'package:full_identity_verification/model.dart';

Initialize #

final _plugin = BlusaltFullIdentityVerification();

1. Full Identity SDK (Document Present) #

/// [documentTypeList] filters which document types appear in the SDK.
/// Pass null to show all types.
///
/// [timeoutDurationInSec] overrides the network timeout (default 120 s).
///
/// [enableEncryption] enables bi-directional payload encryption (default false).
///
/// [metadata] optional key-value pairs forwarded to the native SDK as-is.
startFullIdentitySDK() async {
  final result = await _plugin.startFullIdentitySDK(
    apiKey: 'your_api_key',
    appName: 'your_app_name',
    clientId: 'your_client_id',
    isDev: true, // set false for production
    reference: 'unique_reference',       // optional
    webhookUrl: 'https://your-webhook.com', // optional
    documentTypeList: [
      DocumentType.bvn,
      DocumentType.nin,
      DocumentType.passport,
      DocumentType.driverLicense,
      DocumentType.pvc,
    ],
    timeoutDurationInSec: 120,
    enableEncryption: false,
    livenessFacialComparisonType: LivenessFacialComparisonType.dynamic,
    showLivenessResult: false,
    metadata: {'userId': 'user_001', 'sessionId': 'abc-456'}, // optional
  );

  if (result?.blusaltFullIdentityProcess == BlusaltFullIdentityProcess.completed) {
    final doc = result!.fullIdentitySuccessData?.extractedDocumentData;
    final live = result.fullIdentitySuccessData?.livenessSuccessData;
    debugPrint('Name: ${doc?.firstName} ${doc?.lastName}');
    debugPrint('Liveness passed: ${live?.isPassProcedureValidation}');
  } else {
    debugPrint('Error ${result?.code}: ${result?.message}');
  }
}

2. Document Absent — Custom Selector #

/// [documentTypeList] defines which document types the user can pick from.
///
/// [livenessFacialComparisonType] controls the liveness method used.
///
/// [thresholdConfig] controls face-comparison strictness.
/// Pass null to use the SDK server default.
///
/// [metadata] optional key-value pairs forwarded to the native SDK as-is.
startDocAbsentWithCustomSelector() async {
  final result = await _plugin.startDocAbsentWithCustomSelector(
    apiKey: 'your_api_key',
    appName: 'your_app_name',
    clientId: 'your_client_id',
    isDev: true,
    documentTypeList: [DocumentType.bvn, DocumentType.nin],
    reference: 'unique_reference',
    webhookUrl: 'https://your-webhook.com',
    livenessFacialComparisonType: LivenessFacialComparisonType.dynamic, 
    showLivenessResult: false,
    thresholdConfig: ThresholdConfig(
      localThreshold: 85.0,
      priority: ThresholdPriority.serverWithLocalFallback,
    ),
    timeoutDurationInSec: 120,
    enableEncryption: false,
    metadata: {'userId': 'user_001', 'sessionId': 'abc-456'}, // optional
  );

  if (result?.blusaltFullIdentityProcess == BlusaltFullIdentityProcess.completed) {
    // handle success
  } else {
    debugPrint('Error ${result?.code}: ${result?.message}');
  }
}

3. Document Absent — ID Number #

/// [documentType] specifies the document type to verify against.
///
/// [documentNumber] is the ID number (e.g. BVN, NIN, passport number).
///
/// [startProcessOnGettingToFirstScreen] skips the "Continue" button on the
/// SDK's first screen and starts the process automatically.
///
/// [metadata] optional key-value pairs forwarded to the native SDK as-is.
startDocAbsentWithIdNumber() async {
  final result = await _plugin.startDocAbsentWithIdNumber(
    apiKey: 'your_api_key',
    appName: 'your_app_name',
    clientId: 'your_client_id',
    isDev: true,
    documentType: DocumentType.bvn,
    documentNumber: '12345678901',
    reference: 'unique_reference',
    webhookUrl: 'https://your-webhook.com',
    startProcessOnGettingToFirstScreen: false,
    livenessFacialComparisonType: LivenessFacialComparisonType.dynamic,
    showLivenessResult: false,
    thresholdConfig: ThresholdConfig(
      localThreshold: 85.0,
      priority: ThresholdPriority.serverWithLocalFallback,
    ),
    timeoutDurationInSec: 120,
    enableEncryption: false,
    metadata: {'userId': 'user_001', 'sessionId': 'abc-456'}, // optional
  );

  if (result?.blusaltFullIdentityProcess == BlusaltFullIdentityProcess.completed) {
    // handle success
  } else {
    debugPrint('Error ${result?.code}: ${result?.message}');
  }
}

Models #

ThresholdConfig #

Controls face-comparison strictness for doc-absent flows.

Property Type Required Description
localThreshold double No Threshold value 0–100. Higher = stricter.
priority ThresholdPriority No How the threshold is applied (default: serverWithLocalFallback)
ThresholdConfig(
  localThreshold: 85.0,
  priority: ThresholdPriority.serverWithLocalFallback,
)

Pass null to use the SDK's server-side default.


BlusaltFullIdentityResultResponse #

Field Type Description
blusaltFullIdentityProcess BlusaltFullIdentityProcess completed or notImplemented
fullIdentitySuccessData FullIdentitySuccessData? Document + liveness data on success
reference String? The reference you passed in
code String? Error code on failure
message String? Error message on failure
exception PlatformException? Raw platform exception if available

FullIdentitySuccessData #

Field Type Description
extractedDocumentData dynamic Parsed document fields (see below)
livenessSuccessData dynamic Liveness check results (see below)

Common document fields: firstName, lastName, middleName, dateOfBirth, gender, documentNumber, documentType, imageByte

Common liveness fields: isPassProcedureValidation, isPassFaceComparison, isPassFaceGenuiness, livenessImage, originalLivenessImage, originalImage


Enums #

DocumentType #

Value Description
bvn Bank Verification Number
nin National Identification Number
passport International Passport
driverLicense Driver's License
pvc Permanent Voter's Card

LivenessFacialComparisonType #

Value Description
dynamic Head-movement liveness (recommended)
action Prompted-action liveness
varifocal Camera depth detection
flash Screen-flash detection

ThresholdPriority #

Value Description
serverWithLocalFallback Use server threshold; fall back to localThreshold if unavailable (default)
localOnly Always use localThreshold
serverOnly Always use the server threshold; ignores localThreshold

BlusaltFullIdentityProcess #

Value Description
completed Verification completed successfully
notImplemented Platform not supported or an error occurred

Parameters Reference #

Common (all three methods) #

Parameter Type Required Description
apiKey String Yes Your Blusalt API key
appName String Yes Your application name
clientId String Yes Your Blusalt client ID
isDev bool Yes true for sandbox, false for production
reference String? No Your unique reference for this transaction
webhookUrl String? No URL to receive webhook notifications
timeoutDurationInSec int? No Network timeout in seconds (default: 120)
enableEncryption bool No Enable bi-directional payload encryption (default: false) - Encryption must be enabled on API key to use
thresholdConfig ThresholdConfig? No Face-comparison threshold config
livenessFacialComparisonType LivenessFacialComparisonType No Liveness method (default: dynamic)
showLivenessResult bool No Show the SDK's built-in result screen (default: true)
metadata Map<String, dynamic>? No Optional key-value pairs forwarded to the native SDK as-is

Full Identity SDK only #

Parameter Type Required Description
documentTypeList List<DocumentType>? No Filter available document types; null = all types

Doc Absent — Custom Selector only #

Parameter Type Required Description
documentTypeList List<DocumentType> Yes Document types the user can choose from

Doc Absent — ID Number only #

Parameter Type Required Description
documentType DocumentType Yes Document type to verify against
documentNumber String Yes The ID number
startProcessOnGettingToFirstScreen bool No Auto-start on first screen (default: false)

Example #

See the example/ directory for a complete sample app demonstrating all three SDK modes with all configurable options.

import 'package:full_identity_verification/full_identity_verification.dart';
import 'package:full_identity_verification/enums.dart';
import 'package:full_identity_verification/model.dart';

final _plugin = BlusaltFullIdentityVerification();

Future<void> runVerification() async {
  final result = await _plugin.startFullIdentitySDK(
    apiKey: 'API_KEY',
    appName: 'MyApp',
    clientId: 'CLIENT_ID',
    isDev: false,
    documentTypeList: [DocumentType.nin, DocumentType.passport],
  );

  if (result?.blusaltFullIdentityProcess == BlusaltFullIdentityProcess.completed) {
    final doc = result!.fullIdentitySuccessData?.extractedDocumentData;
    final live = result.fullIdentitySuccessData?.livenessSuccessData;
    print('${doc?.firstName} ${doc?.lastName}');
    print('Liveness passed: ${live?.isPassProcedureValidation}');
  } else {
    print('Failed — ${result?.code}: ${result?.message}');
  }
}

Installation #

Android #

Step 1 — GitHub credentials

Create a github.properties file in the root of your /android folder:

USERNAME_GITHUB=YourGitHubUsername
TOKEN_GITHUB=YourClassicPersonalAccessToken

Grant the token access to read packages at minimum. If you see "Unauthorized" during a Gradle sync, regenerate the token and tick all package-related boxes.

Step 2 — Project-level build.gradle

buildscript {
    ext.kotlin_version = '1.9.+'

    dependencies {
        classpath 'com.android.tools.build:gradle:7.3.+'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}

allprojects {
    def githubPropertiesFile = rootProject.file("github.properties")
    def githubProperties = new Properties()
    githubProperties.load(new FileInputStream(githubPropertiesFile))

    repositories {
        maven {
            name "GitHubPackages"
            url 'https://maven.pkg.github.com/Blusalt-FS/Liveness-Only-Android-Package'
            credentials {
                username githubProperties['USERNAME_GITHUB']
                password githubProperties['TOKEN_GITHUB']
            }
        }
        maven {
            name "GitHubPackages"
            url 'https://maven.pkg.github.com/Blusalt-FS/Blusalt_Document_Verification-Android-Package'
            credentials {
                username githubProperties['USERNAME_GITHUB']
                password githubProperties['TOKEN_GITHUB']
            }
        }
        maven {
            name "GitHubPackages"
            url 'https://maven.pkg.github.com/Blusalt-FS/Full-Identity-SDK-Android-Package'
            credentials {
                username githubProperties['USERNAME_GITHUB']
                password githubProperties['TOKEN_GITHUB']
            }
        }
    }
}

Step 3 — Minimum SDK version

In /android/app/build.gradle:

android {
    defaultConfig {
        minSdkVersion 24
    }
}

Step 4 — ProGuard (if minify is enabled)

In /android/app/proguard-rules.pro:

-keep public class com.megvii.**{*;}
-keep class net.blusalt.liveness_native.** { *; }
-keep class net.blusalt.identityverify.** { *; }
-keep class net.blusalt.fullidentity.** { *; }

Enable it in /android/app/build.gradle:

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

iOS #

Minimum deployment target: iOS 14.0

cd ios && pod install

Add camera permission to ios/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
<string>Required for identity document scanning and liveness detection</string>

📱 Note on iOS #

  1. Physical device only — iOS Simulators are not supported.

  2. Ensure FullIdentityFramework.xcframework is linked In your Xcode workspace, navigate to Pods > FullIdentityFramework.xcframework and confirm it is linked to your app's build target.

  3. Add required system frameworks If you encounter build errors related to MediaPlayer or WebKit:

    • Open Xcode → TargetsRunnerGeneralFrameworks, Libraries, and Embedded Content
    • Add: AVFoundation.framework, CoreMedia.framework, CoreMotion.framework, MediaPlayer.framework, SystemConfiguration.framework, WebKit.framework

Error Handling #

The SDK never throws — it always returns a BlusaltFullIdentityResultResponse. Check the blusaltFullIdentityProcess field:

final result = await _plugin.startFullIdentitySDK(...);

if (result == null) {
  // unexpected null — treat as failure
  return;
}

switch (result.blusaltFullIdentityProcess) {
  case BlusaltFullIdentityProcess.completed:
    // success — read result.fullIdentitySuccessData
    break;
  case BlusaltFullIdentityProcess.notImplemented:
    // failure — read result.code and result.message
    debugPrint('Code: ${result.code}');
    debugPrint('Message: ${result.message}');
    break;
}

Support #

For issues or questions contact Blusalt support or raise an issue in this repository.

0
likes
140
points
1.03k
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter plugin for Blusalt Full Identity Verification SDK that supports both Android and iOS platforms.

Homepage

License

BSD-3-Clause (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface

More

Packages that depend on full_identity_verification

Packages that implement full_identity_verification