Flutter SDK
Drop-in Flutter plugin for the WIDTH verification flow (KYC and KYB). Wraps the native iOS and Android SDKs — mobile only (no web or desktop).
1.0.1 pins iOS SDK 1.0.5 and Android SDK 1.0.2. Each plugin release pins its native SDK versions — don't override them manually.環境要求
| Requirement | Minimum |
|---|---|
| Flutter | 3.10+ |
| iOS | 16.0+ deployment target, Xcode 16+, CocoaPods |
| Android | minSdk 26 (Android 8.0), compileSdk 36 |
Installation
Add to pubspec.yaml, then run flutter pub get:
dependencies:
flutter_width_identity_sdk_plugin:
git:
url: https://github.com/width-com/WidthIdentity-Flutter.git
ref: 1.0.1
iOS setup
Declare both sources in ios/Podfile and set the platform, then run cd ios && pod install:
source 'https://github.com/width-com/Specs.git' source 'https://cdn.cocoapods.org/' platform :ios, '16.0'
Android setup
Set minSdk 26 in android/app/build.gradle. If you enforce RepositoriesMode.FAIL_ON_PROJECT_REPOS, declare the repositories in android/settings.gradle:
dependencyResolutionManagement {
repositories {
maven { url = uri("https://maven.width.com/repository/sdk-releases/") }
google()
mavenCentral()
maven {
url = uri("https://cdn.veriff.me/android/")
content { includeGroup("com.veriff") }
}
maven {
url = uri("https://maven-master.regulaforensics.com/RegulaDocumentReader/")
content { includeGroupByRegex("com\\.regula.*") }
}
}
}
Permissions
iOS
Add to ios/Runner/Info.plist:
<key>NSCameraUsageDescription</key> <string>Used to capture identity documents and complete the liveness check.</string> <key>NSMicrophoneUsageDescription</key> <string>Used by the document verification provider during video capture.</string> <key>NSPhotoLibraryUsageDescription</key> <string>Used to select identity document images.</string>
Android
The native SDK's manifest merges permissions automatically. Runtime (dangerous) permissions: CAMERA and RECORD_AUDIO.
Quick start
import 'package:flutter_width_identity_sdk_plugin/flutter_width_identity_sdk_plugin.dart';
final sdk = WIDTHMobileSDK.init(sdkToken)
.withCredentials(appId: appId, apiKey: apiKey, domain: domain)
.withApplicant(customerId: 'C_abc123', email: 'user@example.com')
.withForcedDayNightMode(WIDTHDayNightMode.night)
.withHandlers(
onStatusChanged: (newStatus, prevStatus) { /* status change */ },
verificationHandler: (isApproved) { /* final decision */ },
)
.build();
final result = await sdk.launch();
switch (result.status) {
case WIDTHStatus.approved: // final decision: approved
case WIDTHStatus.finallyRejected: // final decision: rejected
case WIDTHStatus.pending: // under manual review
case WIDTHStatus.incomplete: // mid-flow exit; resumable
case WIDTHStatus.cancelled: // discarded; not resumable
case WIDTHStatus.failed: // see result.exception
}
Event logging (optional)
.withHandlers(
onEvent: (event) {
// event.level / event.tag / event.message
},
)
Handling results
launch() always resolves; it never throws for SDK-level failures.
| Status | When |
|---|---|
approved | Server approved |
finallyRejected | Server rejected |
pending | Under manual review |
incomplete | User exited mid-flow; resumable with the same customerId |
cancelled | User explicitly discarded (not resumable) |
failed | Internal error; see result.exception |
On failed, result.exception (WIDTHException) carries a type — initialization, network, api, permission, workflow, or unknown — with the original code (e.g. W-LIV-499) and message. result.executionId identifies the run for support.
API reference
| Symbol | Purpose |
|---|---|
WIDTHMobileSDK.init(accessToken) | Entry point; returns the builder |
WIDTHMobileSDKBuilder | withCredentials / withApplicant / withForcedDayNightMode / withHandlers / build() |
WIDTHMobileSDK.launch() | Presents the flow; resolves with the result |
WIDTHMobileSDKResult | status / success / exception / executionId |
WIDTHStatus / WIDTHException / WIDTHExceptionType | Status / error |
WIDTHSDKEvent / WIDTHLogLevel | Event log |
WIDTHDayNightMode | Forced theme |