GitHub Repository
View source code and examples on GitHub
pub.dev Package
didit_sdk
Native SDK: This is the recommended approach for Flutter apps. The SDK wraps the native iOS and Android SDKs via platform channels for the best user experience, optimized camera handling, and full NFC support.
Requirements
Platform Requirements
Installation
pubspec.yaml:
Native SDK variants
didit_sdk bundles the complete native SDK.
To ship a smaller binary, depend on a variant package instead - it exposes exactly the same Dart API and pins the matching native SDK on both platforms:
package:didit_sdk_core/sdk_flutter.dart.
iOS Setup
The plugin supports both of Flutter’s iOS dependency managers: Swift Package Manager and CocoaPods.Swift Package Manager
If your Flutter version has Swift Package Manager support enabled (opt in withflutter config --enable-swift-package-manager on Flutter 3.24+), the plugin is consumed as a Swift package automatically.
No Podfile configuration is needed - the native DiditSDK dependency resolves from GitHub on its own.
Set your app’s iOS deployment target in Xcode (Runner target and project) to the minimum for your chosen package: 15.0 for didit_sdk and didit_sdk_nfc, 13.0 for didit_sdk_core and didit_sdk_autodetection.
CocoaPods
Withdidit_sdk, the plugin selects the native iOS SDK variant from $DiditSdkIosVariant, a Ruby global you set in your app’s ios/Podfile (the DiditSDK pod is not on CocoaPods trunk):
didit_sdk_core, didit_sdk_autodetection, didit_sdk_nfc), it pins its native subspec directly and ignores $DiditSdkIosVariant - keep your Podfile’s pod line and deployment target matched to that variant (for example pod 'DiditSDK/Core', :podspec => ... with platform :ios, '13.0').
The
all and nfc variants require a deployment target of iOS 15.0+; core and autodetection can target iOS 13.0. When switching variants, clean CocoaPods first (rm -rf Pods Podfile.lock) so the previous SDK variant is not reused.Android Setup
By default the plugin depends on the full Android SDK including NFC. To build without NFC, add this toandroid/gradle.properties:
me.didit:didit-sdk to me.didit:didit-sdk-core, removing the NFC reader module and its JMRTD/SCUBA/BouncyCastle dependencies.
When NFC is enabled (default), add this packaging rule to android/app/build.gradle.kts to resolve a duplicate metadata file from BouncyCastle:
mergeDebugJavaResource error. The rule is not needed when diditSdkAndroidNfcEnabled=false.
The Android native SDK resolves from a remote GitHub Maven repository (since plugin 3.4.0) — no manual Maven configuration is needed in your app.
Permissions
iOS
Add the following keys to your app’sInfo.plist:
NFC Configuration
To enable NFC reading for passports and ID cards with chips:-
Add NFC Capability in Xcode:
- Select your target > Signing & Capabilities > + Capability > Near Field Communication Tag Reading
-
Add ISO7816 Identifiers to
Info.plist:
- Add an entitlements file with NFC tag reading enabled:
com.apple.developer.nfc.readersession.formats entitlement.
This NFC configuration is not needed for the core or autodetection variants ($DiditSdkIosVariant), or for the didit_sdk_core / didit_sdk_autodetection packages — none of them read chips.
Android
The following permissions are declared in the SDK’sAndroidManifest.xml and merged automatically:
Camera and NFC hardware features are declared as optional (
android:required="false"), so your app can be installed on devices without these features. When diditSdkAndroidNfcEnabled=false, the Android NFC permission and feature are not added by the SDK.
Runtime Permissions
The SDK handles Android runtime permission requests automatically. When the user reaches a step that requires camera access:- The SDK prompts for camera permission if not already granted
- If the user denies the permission, an error message is displayed with a Try Again button
- If the user grants the permission, the verification flow continues
startVerification() — the SDK manages this internally.
Quick Start
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:- 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 — no backend needed:Advanced session parameters (
contact_details, expected_details, metadata) are only supported through the Session Token method, where your backend calls the Create Session API with full parameter support. Pass the returned session_token to DiditSdk.startVerification().Configuration
Customize the SDK behavior by passing aDiditConfig object:
startVerificationWithWorkflow, pass config as a named parameter:
Configuration Options
Theming & Colors: Colors, backgrounds, and intro screen settings are configured through your White Label settings in the Didit Console, not in the SDK configuration. This ensures consistent branding across all platforms.
Language Support
The SDK supports 53 languages. If no language is specified, the SDK uses the device locale with English as fallback.Advanced Session Parameters
Parameters likecontact_details, expected_details, and metadata are only supported through the Session Token method. Your backend calls POST /v3/session/ with full parameter support, then passes the returned session_token to the SDK.
The Dart
startVerificationWithWorkflow method only accepts workflowId, vendorData, and config. Pre-3.4.0 versions exposed contactDetails, expectedDetails, and metadata parameters, but these were removed because the Unilink endpoint does not honour them.Handling Results
BothstartVerification and startVerificationWithWorkflow return a Future<VerificationResult>. The result is a sealed class — use pattern matching to determine the outcome.
Result Cases
SessionData Properties
Error Types
TheVerificationErrorType enum exposes the following cases:
Complete Result Handling Example
End-to-End Example (Backend Session → Flutter SDK → Webhook)
The production-ready integration: your backend creates the session, your Flutter app receives thesession_token, and the SDK runs the flow. The final decision is delivered to your backend via webhook — never trust the client-side result alone.