full_identity_verification 0.1.9
full_identity_verification: ^0.1.9 copied to clipboard
Flutter plugin for Blusalt Full Identity Verification SDK that supports both Android and iOS platforms.
Blusalt Full Identity Verification Flutter Plugin #
A Flutter plugin for Blusalt Full Identity Verification SDK that supports both Android and iOS platforms.
Features #
- Full Identity SDK: Complete identity verification with document scanning and liveness check
- Document Absent with Custom Selector: Identity verification where user selects document type from a list
- Document Absent with ID Number: Identity verification by providing document type and number directly
- Cross-platform: Works on both Android (API 16+) and iOS (11.0+)
- Native Integration: Uses native Blusalt SDKs for optimal performance
Getting Started #
Prerequisites #
Android
- Min SDK: 16
- Compile SDK: 31
- Kotlin: 1.7.10+
iOS
- iOS 14.0+
- Swift 5.0+
- Xcode 13.0+
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
full_identity_verification: ^lastVersion
Setup #
Android Setup
Step 1
Create a [github.properties] file in root of android folder and put below into content. Replace values with your github credentials from github and make sure to grant necessary permissions especially for github packages
USERNAME_GITHUB=SampleUsername
TOKEN_GITHUB=SampleClassicToken
Step 2
Add below to project level gradle file /android/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
Change the minimum Android sdk version to 24 (or higher) in your /android/app/build.gradle file.
android {
...
defaultConfig {
...
minSdkVersion 24
}
...
}
Step 4
If you're experiencing crashes or timeouts.
Add below to your progaurd.pro file if using progaurd or minify is enabled
/android/app/proguard-rules.pro
-keep public class com.megvii.**{*;}
-keep class net.blusalt.liveness_native.** { *; }
Enable proguard in /android/app/build.gradle file like below.
android {
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
...
}
Note on Android: #
If you are getting an error on android which says "Unauthorized" when gradle is downloading or building, generate a new github token that have access to clone, read and write to repo, access github packages. If you don't know which to tick, tick all boxes. Cheers
iOS Setup
The plugin includes the necessary frameworks. Just run:
cd ios && pod install
Minimum iOS Deployment = 14
Add one row to the ios/Runner/Info.plist:
with the key Privacy - Camera Usage Description and a usage description.
<key>NSCameraUsageDescription</key>
<string>your usage description here</string>
📱 Note on iOS #
-
Physical Device Requirement
This liveness feature only works on a physical iOS device. iOS Simulators are not supported and may not reflect actual behavior. -
Ensure
FullIdentityFramework.xcframeworkis Linked
In your Xcode workspace:
- Navigate to
Pods>FullIdentityFramework.xcframework - Confirm that it is properly linked and included in your app’s build target.
- Add Required Frameworks to Xcode
If you encounter errors related toMediaPlayerorWebKit, follow these steps:
- Open your project in Xcode.
- Under the
TARGETSsection, click on Runner. - Go to the General tab and scroll to Frameworks, Libraries, and Embedded Content.
- Click the
+button and add the following frameworks:AVFoundation.frameworkCoreMedia.frameworkCoreMotion.frameworkMediaPlayer.frameworkSystemConfiguration.frameworkWebKit.framework
Usage #
Import the package #
import 'package:full_identity_verification/full_identity_verification.dart';
import 'package:full_identity_verification/enums.dart';
Initialize the plugin #
final _fullIdentityPlugin = BlusaltFullIdentityVerification();
1. Full Identity SDK (Document Present) #
Use this when users will physically scan their documents:
final result = await _fullIdentityPlugin.startFullIdentitySDK(
apiKey: 'your_api_key',
appName: 'your_app_name',
clientId: 'your_client_id',
isDev: true, // Set to false for production
reference: 'unique_reference',
webhookUrl: 'https://your-webhook-url.com',
documentTypeList: [
DocumentType.bvn,
DocumentType.nin,
DocumentType.passport,
DocumentType.driverLicense,
DocumentType.pvc,
],
timeoutDurationInSec: 120,
);
if (result?.blusaltFullIdentityProcess == BlusaltFullIdentityProcess.completed) {
// Success - Access data
final documentData = result?.fullIdentitySuccessData?.extractedDocumentData;
final livenessData = result?.fullIdentitySuccessData?.livenessSuccessData;
print('First Name: ${documentData?.firstName}');
print('Last Name: ${documentData?.lastName}');
print('Document Number: ${documentData?.documentNumber}');
print('Liveness Passed: ${livenessData?.isPassProcedureValidation}');
} else {
// Handle error
print('Error: ${result?.message}');
}
2. Document Absent with Custom Selector #
Use this when document is not available but user can select document type:
final result = await _fullIdentityPlugin.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-url.com',
livenessFacialComparisonType: LivenessFacialComparisonType.motional,
thresholdInPercent: 85.0, // Optional: 0-100, higher = stricter
timeoutDurationInSec: 120,
);
// Handle result same as above
3. Document Absent with ID Number #
Use this when you already have the document type and number:
final result = await _fullIdentityPlugin.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-url.com',
livenessFacialComparisonType: LivenessFacialComparisonType.motional,
thresholdInPercent: 85.0,
timeoutDurationInSec: 120,
);
// Handle result same as above
Models #
BlusaltFullIdentityResultResponse #
Main response model containing:
blusaltFullIdentityProcess: Status (completed/notImplemented)exception: Exception if any error occurredcode: Error code if applicablemessage: Error message if applicablereference: Your reference stringfullIdentitySuccessData: Success data containing document and liveness info
FullIdentitySuccessData #
Success data containing:
extractedDocumentData: Document informationlivenessSuccessData: Liveness check results
ExtractedDocumentData #
Document information:
firstName: First name from documentlastName: Last name from documentmiddleName: Middle name from documentphoneNumber: Phone number if availableemail: Email if availabledateOfBirth: Date of birthgender: GenderdocumentNumber: Document ID numberdocumentType: Type of documentimageByte: Base64 encoded image from document
LivenessSuccessData #
Liveness check results:
isPassProcedureValidation: Overall validation statusisPassFaceComparison: Face comparison result (for doc-absent flows)isPassFaceGenuiness: Face genuineness resultlivenessImage: Base64 encoded liveness imageoriginalLivenessImage: Base64 encoded original liveness imageoriginalImage: Base64 encoded original image (for comparison)
Enums #
BlusaltFullIdentityProcess #
completed: Process completed successfullynotImplemented: Platform not supported or error occurred
DocumentType #
bvn: Bank Verification Numbernin: National Identification Numberpassport: International PassportdriverLicense: Driver's Licensepvc: Permanent Voter's Card
LivenessFacialComparisonType #
motional: User performs head movements (more secure)still: User takes a still photo (faster)
DocumentAvailabilityType #
present: Physical document available for scanningabsent: Document not physically available
Parameters #
Common Parameters #
| 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 | Use development environment |
| 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) |
Full Identity SDK Parameters #
| Parameter | Type | Required | Description |
|---|---|---|---|
| documentTypeList | List<DocumentType> | No | Filter available document types |
Document Absent Parameters #
| Parameter | Type | Required | Description |
|---|---|---|---|
| documentTypeList | List<DocumentType> | Yes* | Available document types (*custom selector only) |
| documentType | DocumentType | Yes* | Specific document type (*ID number only) |
| documentNumber | String | Yes* | Document ID number (*ID number only) |
| livenessFacialComparisonType | LivenessFacialComparisonType | No | Liveness check type (default: motional) |
| thresholdInPercent | double | No | Face comparison threshold 0-100 (default: SDK default 90-94) |
Error Handling #
try {
final result = await _fullIdentityPlugin.startFullIdentitySDK(...);
if (result != null) {
if (result.blusaltFullIdentityProcess == BlusaltFullIdentityProcess.completed) {
// Success
} else {
// Failed
print('Error Code: ${result.code}');
print('Error Message: ${result.message}');
}
}
} catch (e) {
print('Exception: $e');
}
Platform-Specific Notes #
Android #
- The plugin uses the native Blusalt Full Identity SDK for Android
- Requires camera, storage, and microphone permissions
- Minimum Android version: API 16 (Android 4.1)
iOS #
- The plugin uses the native Blusalt Full Identity Framework for iOS
- Requires camera and photo library permissions
- Minimum iOS version: 11.0
Permissions #
Android (AndroidManifest.xml) #
The plugin automatically requests these permissions:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
iOS (Info.plist) #
Add these keys to your Info.plist:
<key>NSCameraUsageDescription</key>
<string>We need camera access for identity verification</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need photo library access for identity verification</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need microphone access for liveness detection</string>
Example #
See the example directory for a complete sample app demonstrating all three SDK modes.
Support #
For issues, questions, or contributions, please contact Blusalt support or visit the Blusalt developer portal.
License #
This plugin is licensed under LICENSE.