Flutter SDK 集成指南
概述
WIDTH Identity SDK 以即插即用的 Flutter 插件形式提供身份驗證流程(KYC 與 KYB)。你添加一個依賴、調用一個入口;原生 SDK 全屏呈現完整的採集 / 活體 / 審覈界面,並返回單一結果。該插件封裝原生 iOS 與 Android SDK — 僅支持 iOS 與 Android(不支持 web 或桌面)。
1.0.2 — 綁定 iOS SDK 1.0.11 與
Android SDK 1.0.11。升級插件即一併升級原生
SDK;不要手動覆蓋原生依賴。
系統要求
| 要求 | 最低版本 |
|---|---|
| Flutter | 3.10+ |
| iOS | 16.0+(部署目標)、Xcode 16+、CocoaPods |
| Android | minSdk 26(Android 8.0)、compileSdk 36,並開啓 core library desugaring(見下文 Android 一節) |
domain /
accessToken 也必須是生產憑據。用別的環境的 token,過不了
SDK 的安全初始化,報錯表現爲 W-RISK-102。
安裝
插件倉庫、以及它 iOS 側要拉的那個私有 Specs 倉庫,都要先給你的 GitHub
賬號開通訪問權 — 在那之前,flutter pub get 和
pod install 都只會提示倉庫不存在。
該插件通過 WIDTH 的私有 Git 倉庫分發。將它添加到
pubspec.yaml:
dependencies:
flutter_width_identity_sdk_plugin:
git:
url: https://github.com/width-com/WidthIdentity-Flutter.git
ref: 1.0.2然後執行 flutter pub get。
iOS
原生 WidthIdentity pod 從 WIDTH 的私有 Specs 倉庫解析。在
ios/Podfile 頂部聲明兩個 source 並設置 platform:
source 'https://github.com/width-com/Specs.git' source 'https://cdn.cocoapods.org/' # default trunk, for any public pods platform :ios, '16.0'
然後執行 cd ios && pod install。
Android
在 android/app/build.gradle 中設置
minSdk 26。插件會自動註冊 WIDTH Maven
倉庫、供應商採集引擎倉庫(Veriff、Regula)以及原生依賴。
原生 SDK 內置的 AWS 活體引擎要求兩項構建配置 — 都加在你自己的 App 上,兩項都不涉及你的源碼:
// android/app/build.gradle.kts
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
}
該引擎的 Amplify AAR 在元數據裏聲明瞭「requires core library
desugaring」,AGP 會在 App 模塊上強制校驗,與你的
minSdk 是多少無關;不開啓,構建直接失敗。
# android/gradle.properties — AGP 9 only android.uniquePackageNames=false
AGP 9 的清單合併會校驗庫命名空間的唯一性,而活體引擎傳遞引入的兩個產物(com.google.ai.edge.litert:litert-support
與 litert-support-api)聲明瞭同一個命名空間
org.tensorflow.lite.support —
這是上游的打包缺陷。不加這個開關,構建會以
Validation failed, exiting 失敗。
若你的項目啓用了
RepositoriesMode.FAIL_ON_PROJECT_REPOS,則改爲在
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.*") }
}
}
}權限
iOS — 添加到
ios/Runner/Info.plist。相機、麥克風、語音識別三項必填;照片庫那一項可選:
<!-- Required: document capture and liveness. -->
<key>NSCameraUsageDescription</key>
<string>Used to capture identity documents and complete the liveness check.</string>
<!-- Required: the document verification provider records background audio
(anti-fraud) — the app crashes at runtime without this key. -->
<key>NSMicrophoneUsageDescription</key>
<string>Used by the document verification provider during video capture.</string>
<!-- Required by App Store ingestion; never requested at runtime (a linked but
unreachable API inside the AWS liveness component). -->
<key>NSSpeechRecognitionUsageDescription</key>
<string>This app does not request speech recognition.</string>
<!-- Optional: only if your app also lets users pick a document image from the
photo library. -->
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to select identity document images.</string>
Android — 原生 SDK 的 manifest
會自動合併所需權限,你無需聲明。運行時(危險級)權限是
CAMERA 與
RECORD_AUDIO(後者由內置的採集 / 活體引擎引入),由 SDK
在其自有 Activity 內部申請。完整權限清單見
Android 章「權限」節,並需把每一項反映到你的 Google Play Data Safety(數據安全)申報中。
快速開始
引入插件,用鏈式調用構建 SDK,再
await sdk.launch()。當原生流程關閉時該 future 完成。
import 'package:flutter_width_identity_sdk_plugin/flutter_width_identity_sdk_plugin.dart';
final sdk = WIDTHMobileSDK.init(sdkToken)
.withCredentials(domain: domain) // tenant routing domain (appId/apiKey are inside the token)
.withApplicant(customerId: 'C_abc123', email: 'user@example.com')
.withEventType(WIDTHEventType.kyc) // optional; omit → user picks KYC/KYB in-SDK
.withForcedDayNightMode(WIDTHDayNightMode.night) // optional; omit → follows system
.withLanguage(WIDTHLanguage.zh) // optional; omit → English (never the device locale)
.withHandlers(
onStatusChanged: (newStatus, prevStatus) { /* terminal status change */ },
verificationHandler: (isApproved) { /* final approve / reject only */ },
)
.build();
final result = await sdk.launch(); // resolves when the native flow closes
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 / waiting; resumable
case WIDTHStatus.cancelled: // discarded; not resumable
case WIDTHStatus.failed: // see result.exception
}事件日誌(可選)
傳入
onEvent handler,可在你自己的管道(Crashlytics、DataDog
等)中接收 SDK 生命週期事件(INFO / WARN / ERROR);回調觸發前已脫敏
PII(個人身份信息)。
.withHandlers(
onEvent: (event) {
// event.level / event.tag / event.message
},
)界面語言(可選)
withLanguage(WIDTHLanguage.zh) 把整個流程切成簡體中文
— 包括 SDK 自身的文案,以及後端返回的
{en, zh} 動態內容。不傳就是英文:原生 SDK
從不跟隨設備語言,所以已有的集成不會受影響。
內置的第三方採集頁面另有限制:證件掃描商只有在設備聯網、且租戶的集成開啓了中文時才顯示中文,否則仍是英文;證件閱讀器只支持簡體中文。
結果處理
launch() 總會完成;對 SDK 級別的失敗不會拋出異常。
result.status |
何時 |
|---|---|
approved |
服務端通過 |
finallyRejected |
服務端拒絕 |
pending |
提交在帶外進行人工審覈 |
incomplete |
用戶中途退出或決定仍在等待;用相同
customerId 可恢復
|
cancelled |
用戶主動放棄驗證;不可恢復 |
failed |
內部錯誤;見 result.exception
|
當爲
.failed
時,result.exception(WIDTHException)帶一個
type —
initialization、network、api、permission、workflow、unknown
之一 — 並保留原始 code(如 W-LIV-499)與
message。result.executionId
標識該次運行,便於支持排查。
API 參考
| 符號 | 用途 |
|---|---|
WIDTHMobileSDK.init(accessToken) |
入口,返回 builder |
WIDTHMobileSDKBuilder |
withCredentials / withApplicant /
withEventType / withForcedDayNightMode /
withLanguage / withHandlers /
build()
|
WIDTHMobileSDK.launch() |
呈現流程;以結果完成 |
WIDTHMobileSDKResult |
status / success /
exception /
executionId
|
WIDTHStatus / WIDTHException /
WIDTHExceptionType
|
狀態 / 錯誤 |
WIDTHSDKEvent / WIDTHLogLevel |
事件日誌 |
WIDTHEventType |
可選的 KYC / KYB 流程預選 |
WIDTHDayNightMode |
強制主題 |
WIDTHLanguage |
可選的界面語言(en 爲默認值 /
zh)
|
pubspec.yaml 中的
ref 標籤並執行
flutter pub get。每個插件版本都綁定了它驗證過的原生 SDK
版本 — 不要手動覆蓋原生依賴。