didit_sdk 3.2.0
didit_sdk: ^3.2.0 copied to clipboard
Didit Identity Verification SDK for Flutter. Wraps native iOS and Android SDKs for document scanning, NFC passport reading, face verification, and liveness detection.
DiditSDK for Flutter #
A Flutter plugin for Didit Identity Verification. Wraps the native iOS and Android SDKs with a unified Dart API for document scanning, NFC passport reading, face verification, and liveness detection.
Requirements #
| Requirement | Minimum Version |
|---|---|
| Flutter | 3.3+ |
| Dart | 3.11+ |
| iOS | 13.0+ (NFC requires iOS 15.0+) |
| Android | API 23+ (6.0 Marshmallow) |
Installation #
Add the dependency to your pubspec.yaml:
dependencies:
didit_sdk: ^3.2.0
Then run:
flutter pub get
iOS Setup #
Add the DiditSDK podspec to your ios/Podfile (it's not on CocoaPods trunk):
# Inside your target block:
pod 'DiditSDK', :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/main/DiditSDK.podspec'
Then install dependencies:
cd ios
pod install
Android Setup #
Add the following packaging rule to your android/app/build.gradle.kts inside the android block:
android {
packaging {
resources {
pickFirsts += "META-INF/versions/9/OSGI-INF/MANIFEST.MF"
}
}
}
This resolves a duplicate metadata file shipped by the SDK's cryptography dependencies (BouncyCastle). Without it the build will fail with a mergeDebugJavaResource error.
Permissions #
iOS #
Add the following keys to your app's Info.plist:
| Permission | Info.plist Key | Description | Required |
|---|---|---|---|
| Camera | NSCameraUsageDescription |
Document scanning and face verification | Yes |
| NFC | NFCReaderUsageDescription |
Read NFC chips in passports/ID cards | If using NFC |
| Location | NSLocationWhenInUseUsageDescription |
Geolocation for fraud prevention | Optional |
<key>NSCameraUsageDescription</key>
<string>Camera access is required for identity verification.</string>
<key>NFCReaderUsageDescription</key>
<string>NFC is used to read passport chip data for identity verification.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location access is used to detect your country for identity verification.</string>
NFC Configuration (for passport/ID chip reading)
-
Add NFC Capability in Xcode:
- Select your target > Signing & Capabilities > + Capability > Near Field Communication Tag Reading
-
Add ISO7816 Identifiers to
Info.plist:<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key> <array> <string>A0000002471001</string> </array>
Android #
The following permissions are declared in the native SDK's AndroidManifest.xml and merged automatically:
| Permission | Description | Required |
|---|---|---|
INTERNET |
Network access for API communication | Yes |
ACCESS_NETWORK_STATE |
Detect network availability | Yes |
CAMERA |
Document scanning and face verification | Yes |
NFC |
Read NFC chips in passports/ID cards | If using NFC |
Camera and NFC hardware features are declared as optional (android:required="false"), so your app can be installed on devices without these features.
Quick Start #
import 'package:didit_sdk/sdk_flutter.dart';
final result = await DiditSdk.startVerification('your-session-token');
switch (result) {
case VerificationCompleted(:final session):
print('Status: ${session.status}');
print('Session ID: ${session.sessionId}');
case VerificationCancelled():
print('User cancelled');
case VerificationFailed(:final error):
print('Error: ${error.type} - ${error.message}');
}
Integration Methods #
The SDK supports two integration methods:
Method 1: Session Token (Recommended for Production) #
Create a session on your backend using the Create Verification Session API, then pass the token to the SDK:
// Your backend creates a session and returns the token
final sessionToken = await yourBackend.createVerificationSession(userId);
// Pass the token to the SDK
final result = await DiditSdk.startVerification(sessionToken);
This approach gives you full control over:
- Associating sessions with your users (
vendor_data) - Setting custom metadata
- Configuring callbacks per session
Method 2: Workflow ID (Simpler Integration) #
For simpler integrations, the SDK can create sessions directly using your workflow ID:
final result = await DiditSdk.startVerificationWithWorkflow(
'your-workflow-id',
vendorData: 'user-123',
contactDetails: ContactDetails(email: 'user@example.com'),
config: DiditConfig(loggingEnabled: true),
);
Configuration #
Customize the SDK behavior by passing a DiditConfig object:
final result = await DiditSdk.startVerification(
'your-session-token',
config: DiditConfig(
languageCode: 'es', // Force Spanish language
fontFamily: 'Avenir', // Custom font
loggingEnabled: true, // Debug logging
),
);
Configuration Options #
| Option | Type | Default | Description |
|---|---|---|---|
languageCode |
String? |
Device locale | ISO 639-1 language code (e.g. "en", "fr", "ar") |
fontFamily |
String? |
System font | Custom font family name |
loggingEnabled |
bool |
false |
Enable SDK debug logging |
All fields are optional. If no config is provided, the SDK uses sensible defaults.
languageCode #
Sets the language for the entire verification UI. Pass an ISO 639-1 code (e.g. "en", "fr", "es", "ar"). If not set, the SDK automatically detects the device locale and falls back to English.
// Force French
await DiditSdk.startVerification(token, config: DiditConfig(languageCode: 'fr'));
// Use device locale (default)
await DiditSdk.startVerification(token);
fontFamily #
Overrides the font used throughout the SDK UI. The font must be registered in your app's native configuration:
- iOS: Add the font file to your Xcode project and list it in
Info.plistunderUIAppFonts. - Android: Place the font file in
android/app/src/main/res/font/.
await DiditSdk.startVerification(token, config: DiditConfig(fontFamily: 'Avenir'));
loggingEnabled #
Enables verbose debug logging from the native SDK. Useful during development to inspect the SDK's internal state, API calls, and error details. Should be disabled in production.
await DiditSdk.startVerification(token, config: DiditConfig(loggingEnabled: true));
Language Support #
The SDK supports 40+ languages. If no language is specified, the SDK uses the device locale with English as fallback.
Supported Languages
| Language | Code | Language | Code |
|---|---|---|---|
| English | en |
Korean | ko |
| Arabic | ar |
Lithuanian | lt |
| Bulgarian | bg |
Latvian | lv |
| Bengali | bn |
Macedonian | mk |
| Catalan | ca |
Malay | ms |
| Czech | cs |
Dutch | nl |
| Danish | da |
Norwegian | no |
| German | de |
Polish | pl |
| Greek | el |
Portuguese | pt |
| Spanish | es |
Portuguese (Brazil) | pt-BR |
| Estonian | et |
Romanian | ro |
| Persian | fa |
Russian | ru |
| Finnish | fi |
Slovak | sk |
| French | fr |
Slovenian | sl |
| Hebrew | he |
Serbian | sr |
| Hindi | hi |
Swedish | sv |
| Croatian | hr |
Thai | th |
| Hungarian | hu |
Turkish | tr |
| Armenian | hy |
Ukrainian | uk |
| Indonesian | id |
Uzbek | uz |
| Italian | it |
Vietnamese | vi |
| Japanese | ja |
Chinese (Simplified) | zh |
| Georgian | ka |
Chinese (Traditional) | zh-TW |
| Montenegrin | cnr |
Somali | so |
Advanced Options #
These options are only available with startVerificationWithWorkflow, where the SDK creates the session on your behalf.
Contact Details (Prefill & Notifications) #
Provide contact details to prefill verification forms and enable email notifications:
final result = await DiditSdk.startVerificationWithWorkflow(
'your-workflow-id',
contactDetails: ContactDetails(
email: 'user@example.com',
sendNotificationEmails: true,
emailLang: 'en',
phone: '+14155552671',
),
);
| Field | Type | Description |
|---|---|---|
email |
String? |
Email address for verification notifications |
sendNotificationEmails |
bool? |
Whether to send status update emails |
emailLang |
String? |
ISO 639-1 language code for notification emails |
phone |
String? |
Phone number in E.164 format (e.g. "+14155552671") |
Expected Details (Cross-Validation) #
Provide expected user details for automatic cross-validation with extracted document data:
final result = await DiditSdk.startVerificationWithWorkflow(
'your-workflow-id',
expectedDetails: ExpectedDetails(
firstName: 'John',
lastName: 'Doe',
dateOfBirth: '1990-05-15',
nationality: 'USA',
country: 'USA',
),
);
| Field | Type | Format | Description |
|---|---|---|---|
firstName |
String? |
— | Expected first name |
lastName |
String? |
— | Expected last name |
dateOfBirth |
String? |
YYYY-MM-DD |
Expected date of birth |
gender |
String? |
— | Expected gender |
nationality |
String? |
ISO 3166-1 alpha-3 | Expected nationality (e.g. "USA", "GBR") |
country |
String? |
ISO 3166-1 alpha-3 | Expected country of residence |
address |
String? |
— | Expected address |
identificationNumber |
String? |
— | Expected document ID number |
ipAddress |
String? |
— | Expected IP address |
portraitImage |
String? |
— | Base64-encoded portrait image for face comparison |
All fields are optional.
Custom Metadata #
Store custom JSON metadata with the session (not displayed to user):
final result = await DiditSdk.startVerificationWithWorkflow(
'your-workflow-id',
vendorData: 'user-123',
metadata: '{"internalId": "abc123", "source": "mobile-app"}',
);
Verification Results #
Both startVerification and startVerificationWithWorkflow return a Future<VerificationResult>. The result is a sealed class — use pattern matching to determine the outcome.
Result Types #
| Type | Description | Fields |
|---|---|---|
VerificationCompleted |
Verification flow completed | session (always present) |
VerificationCancelled |
User cancelled the flow | session (optional) |
VerificationFailed |
An error occurred | error (always present), session (optional) |
SessionData #
| Property | Type | Description |
|---|---|---|
sessionId |
String |
The unique session identifier |
status |
VerificationStatus |
approved, pending, or declined |
VerificationError #
| Property | Type | Description |
|---|---|---|
type |
VerificationErrorType |
Error category (see table below) |
message |
String |
Human-readable error description |
Error Types #
| Error Type | Description |
|---|---|
sessionExpired |
The session has expired |
networkError |
Network connectivity issue |
cameraAccessDenied |
Camera permission not granted |
notInitialized |
SDK not initialized (Android only) |
apiError |
API request failed |
unknown |
Other error with message |
Complete Result Handling Example #
import 'package:didit_sdk/sdk_flutter.dart';
Future<void> verify(String token) async {
final result = await DiditSdk.startVerification(token);
switch (result) {
case VerificationCompleted(:final session):
switch (session.status) {
case VerificationStatus.approved:
print('Approved! Session: ${session.sessionId}');
// User is verified — grant access
case VerificationStatus.pending:
print('Under review. Session: ${session.sessionId}');
// Show "verification in progress" UI
case VerificationStatus.declined:
print('Declined. Session: ${session.sessionId}');
// Handle declined verification
}
case VerificationCancelled(:final session):
print('User cancelled.');
if (session != null) {
print('Session: ${session.sessionId}');
}
// Maybe show retry option
case VerificationFailed(:final error):
print('Error [${error.type}]: ${error.message}');
// Handle error — show retry or contact support
}
}
API Reference #
DiditSdk.startVerification(token, {config}) #
Start verification with an existing session token.
| Parameter | Type | Required | Description |
|---|---|---|---|
token |
String |
Yes | Session token from the Didit API |
config |
DiditConfig? |
No | SDK configuration options |
Returns: Future<VerificationResult>
DiditSdk.startVerificationWithWorkflow(workflowId, {...}) #
Start verification by creating a new session with a workflow ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
workflowId |
String |
Yes | Workflow ID that defines verification steps |
vendorData |
String? |
No | Your user identifier or reference |
metadata |
String? |
No | Custom JSON metadata for the session |
contactDetails |
ContactDetails? |
No | Prefill contact information |
expectedDetails |
ExpectedDetails? |
No | Expected identity details for cross-validation |
config |
DiditConfig? |
No | SDK configuration options |
Returns: Future<VerificationResult>
Running the Example App #
The repository includes a fully functional example app.
iOS #
cd example
flutter pub get
cd ios && pod install && cd ..
flutter run
To run on a real device, open example/ios/Runner.xcworkspace in Xcode, configure your signing team, and select your device.
Android #
cd example
flutter pub get
flutter run
License #
Copyright (c) 2026 Didit. All rights reserved.