跳转到主要内容

Flutter SDK 集成指南

文档对应版本。Flutter 插件 1.0.2 / iOS SDK 1.0.11 / Android SDK 1.0.11。本页依据更新日期为 2026 年 9 月 11 日的 WIDTH 集成指南。部署前请确认所选 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 一节)
凭据必须与构建所用环境一致 原生 SDK 是单环境构建 — 每个发布版只连一个 WIDTH 环境,环境在构建时就写死了。本版本绑定的原生 SDK 是生产环境的构建,所以 WIDTH 下发给你的 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 版本 — 不要手动覆盖原生依赖。