Flutter身份验证与KYC审核插件flutter_accura_kyc的使用
Flutter身份验证与KYC审核插件flutter_accura_kyc的使用
简介
flutter_accura_kyc
是一个基于 Accura Scan 的数字用户验证系统插件。它支持多种文档扫描功能,包括 MRZ、OCR、条形码、银行卡等,并且可以用于身份验证和 KYC 审核。
安装
在 pubspec.yaml
文件中添加以下依赖:
flutter pub add flutter_accura_kyc
或者通过本地路径安装:
flutter pub add <绝对路径到(flutter_accura_kyc)文件夹>
注意事项:
下载插件后,可以通过本地路径将 flutter_accura_kyc
添加到项目中。
安卓配置
权限设置
在 AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
配置 Gradle
在根目录的 build.gradle
文件末尾添加 jcenter()
:
buildscript {
repositories {
...
jcenter()
}
}
allprojects {
repositories {
...
jcenter()
}
}
在 app/build.gradle
中设置 Accura SDK:
android {
defaultConfig {
...
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
packagingOptions {
pickFirst 'lib/arm64-v8a/libcrypto.so'
pickFirst 'lib/arm64-v8a/libssl.so'
pickFirst 'lib/armeabi-v7a/libcrypto.so'
pickFirst 'lib/armeabi-v7a/libssl.so'
pickFirst 'lib/x86/libcrypto.so'
pickFirst 'lib/x86/libssl.so'
pickFirst 'lib/x86_64/libcrypto.so'
pickFirst 'lib/x86_64/libssl.so'
pickFirst '**/libjsc.so'
pickFirst '**/libc++_shared.so'
pickFirst 'lib/x86/libc++_shared.so'
pickFirst 'lib/x86_64/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libopencv_java4.so'
pickFirst 'lib/arm64-v8a/libopencv_java4.so'
}
}
iOS 配置
权限设置
在 Info.plist
文件中添加以下权限:
<key>NSCameraUsageDescription</key>
<string>App usage camera for scan documents.</string>
<key>NSMicrophoneUsageDescription</key>
<string>App usage microphone for oral verification.</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>App usage speech recognition for oral verification.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App usage photos for get document picture.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>App usage photos for save document picture.</string>
设置 Accura 许可证
Accura 提供三种许可证以启用完整的功能。从 这里 生成自己的许可证。
许可证类型:
- key.license:必备许可证,用于初始化 Accura SDK。
- accuraface.license:用于人脸匹配百分比计算。
- accuraactiveliveness.license:用于活体检测。
安卓配置
将三个许可证放入 android/app/src/main/assets/
目录中。
iOS 配置
在 Xcode 中将许可证拖入项目根目录,并确保勾选 “复制如果需要” 和 “项目名称”。
使用方法
导入库
在 Dart 文件中导入插件:
import 'package:flutter_accura_kyc/flutter_accura_kyc.dart';
获取许可证配置
获取许可证的所有可用功能:
await FlutterAccuraKyc.getMetaData()
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
设置自定义配置
为 Accura SDK 设置自定义消息和配置:
let config = {
"ACCURA_ERROR_CODE_MOTION": '保持文档稳定',
"ACCURA_ERROR_CODE_DOCUMENT_IN_FRAME": '保持文档在框架内',
"ACCURA_ERROR_CODE_BRING_DOCUMENT_IN_FRAME": '将卡片靠近框架',
"ACCURA_ERROR_CODE_PROCESSING": '处理中...',
"ACCURA_ERROR_CODE_BLUR_DOCUMENT": '文档模糊检测',
"ACCURA_ERROR_CODE_FACE_BLUR": '面部模糊检测',
"ACCURA_ERROR_CODE_GLARE_DOCUMENT": '文档反光检测',
"ACCURA_ERROR_CODE_HOLOGRAM": '检测到全息图',
"ACCURA_ERROR_CODE_DARK_DOCUMENT": '低光照检测',
"ACCURA_ERROR_CODE_PHOTO_COPY_DOCUMENT": '无法接受复印件',
"ACCURA_ERROR_CODE_FACE": '未检测到人脸',
"ACCURA_ERROR_CODE_MRZ": '未检测到 MRZ',
"ACCURA_ERROR_CODE_PASSPORT_MRZ": '护照 MRZ 未检测到',
"ACCURA_ERROR_CODE_ID_MRZ": '身份证 MRZ 未检测到',
"ACCURA_ERROR_CODE_VISA_MRZ": '签证 MRZ 未检测到',
"ACCURA_ERROR_CODE_WRONG_SIDE": '扫描文档错误面',
"ACCURA_ERROR_CODE_UPSIDE_DOWN_SIDE": '文档倒置,请正确放置',
"IS_SHOW_LOGO": true,
"SCAN_TITLE_OCR_FRONT": '扫描 OCR 文档正面',
"SCAN_TITLE_OCR_BACK": '扫描 OCR 文档背面',
"SCAN_TITLE_OCR": '扫描',
"SCAN_TITLE_BANKCARD": '扫描银行卡',
"SCAN_TITLE_BARCODE": '扫描条形码',
"SCAN_TITLE_MRZ_PDF417_FRONT": '扫描文档正面',
"SCAN_TITLE_MRZ_PDF417_BACK": '现在扫描文档背面',
"SCAN_TITLE_DLPLATE": '扫描车牌'
};
await FlutterAccuraKyc.setupAccuraConfig([config])
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
扫描 MRZ 文档
let config = [{ enableLogs: false }, MRZType, CountryList, AppOrientation];
await FlutterAccuraKyc.startMRZ(config)
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
扫描 OCR 文档
let config = [{ enableLogs: false }, CountryId, CardId, CardName, CardType, AppOrientation];
await FlutterAccuraKyc.startOcrWithCard(config)
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
扫描条形码
let config = [{ enableLogs: false }, BarcodeType, AppOrientation];
await FlutterAccuraKyc.startBarcode(config)
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
扫描银行卡
let config = [{ enableLogs: false }, AppOrientation];
await FlutterAccuraKyc.startBankCard(config)
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
获取人脸匹配百分比
var accuraConfs = { enableLogs: false, with_face: true, face_uri: 'uri of face'};
var config = {
"feedbackTextSize": 18,
"feedBackframeMessage": '框住你的脸',
"feedBackAwayMessage": '远离手机',
"feedBackOpenEyesMessage": '保持眼睛睁开',
"feedBackCloserMessage": '靠近手机',
"feedBackCenterMessage": '移动到中心',
"feedBackMultipleFaceMessage": '检测到多张人脸',
"feedBackHeadStraightMessage": '保持头部直立',
"feedBackBlurFaceMessage": '检测到人脸模糊',
"feedBackGlareFaceMessage": '检测到反光',
"setBlurPercentage": 80,
"setGlarePercentage_0": -1,
"setGlarePercentage_1": -1,
};
let passArgs = [accuraConfs, config, AppOrientation];
await FlutterAccuraKyc.startFaceMatch(passArgs)
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
活体检测
var accuraConfs = { enableLogs: false, with_face: true, face_uri: 'uri of face' };
var config = {
"feedbackTextSize": 18,
"feedBackframeMessage": '框住你的脸',
"feedBackAwayMessage": '远离手机',
"feedBackOpenEyesMessage": '保持眼睛睁开',
"feedBackCloserMessage": '靠近手机',
"feedBackCenterMessage": '移动到中心',
"feedBackMultipleFaceMessage": '检测到多张人脸',
"feedBackHeadStraightMessage": '保持头部直立',
"feedBackBlurFaceMessage": '检测到人脸模糊',
"feedBackGlareFaceMessage": '检测到反光',
"setBlurPercentage": 80,
"setGlarePercentage_0": -1,
"setGlarePercentage_1": -1,
"isSaveImage": true,
"liveness_url": 'your liveness url',
"contentType": 'form_data',
"feedBackLowLightMessage": '低光照检测',
"feedbackLowLightTolerence": 39,
"feedBackStartMessage": '将你的脸放在椭圆形内',
"feedBackLookLeftMessage": '看向左肩',
"feedBackLookRightMessage": '看向右肩',
"feedBackOralInfoMessage": '大声说出每个数字',
"enableOralVerification": false,
"codeTextColor": 'white'
};
let passArgs = [accuraConfs, config, AppOrientation];
await FlutterAccuraKyc.startLiveness(passArgs)
.then((value) => {
dynamic result = json.decode(value);
})
.onError((error, stackTrace) => {
print("Error: $error");
});
示例代码
以下是完整的示例代码:
import 'dart:ffi';
import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:flutter_accura_kyc/flutter_accura_kyc.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:dropdown_search/dropdown_search.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'ResultScreen.dart';
void main() {
runApp(MaterialApp(
home: MyApp(),
debugShowCheckedModeBanner: false,
));
}
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String _platformVersion = 'Unknown';
dynamic _result = {'isValid': false};
String language = 'en';
Map<String, dynamic> countrySelected = {};
Map<String, dynamic> cardSelected = {};
Map<String, dynamic> mrzSelected = {};
Map<String, dynamic> barcodeSelected = {};
String mrzCountryList = 'all';
List<Map<String, dynamic>> mrzList = [
{"label": "Passport", "value": "passport_mrz"},
{"label": "Mrz ID", "value": "id_mrz"},
{"label": "Visa Card", "value": "visa_mrz"},
{"label": "Other", "value": "other_mrz"}
];
List<String> ocrCountryDropdownOptions = [''];
List<String> ocrCardDropdownOptions = [''];
List<String> mrzDropdownOptions = [''];
List<String> barcodeDropdownOptions = [''];
dynamic sdkConfig;
String selectedCardString = "";
[@override](/user/override)
void initState() {
super.initState();
requestForPermission();
getMetaData();
}
Future<bool> requestForPermission() async {
List<bool> grantStatus = [];
var status = true;
Map<Permission, PermissionStatus> statuses = await [
Permission.camera,
Permission.storage,
Permission.microphone,
].request();
print(statuses);
for (var i = 0; i < statuses.length; i++) {
if (statuses[i] != PermissionStatus.granted) {
grantStatus.add(true);
} else {
grantStatus.add(false);
}
}
for (var item in grantStatus) {
if (!item) {
status = false;
}
}
return status;
}
String getOrientation() {
if (MediaQuery.of(context).orientation.toString().contains('landscape')) {
return 'landscape';
}
return 'portrait';
}
void showFlutterToast(msg) {
Fluttertoast.showToast(
msg: msg,
gravity: ToastGravity.BOTTOM,
toastLength: Toast.LENGTH_SHORT);
}
Future<void> getMetaData() async {
try {
await FlutterAccuraKyc.getMetaData()
.then((value) => {setupConfigData(json.decode(value))})
.onError((error, stackTrace) => {
showFlutterToast("Error :" + error.toString())
});
} on PlatformException {}
if (!mounted) return;
}
void setupConfigData(obj) {
setState(() {
sdkConfig = obj;
});
print("setupConfigData $obj");
setupAccuraConfig();
List<String> tempList1 = [];
for (var item in mrzList) {
tempList1.add(item["label"]);
}
List<String> tempList2 = [];
for (var item in obj['barcodes']) {
tempList2.add(item['name']);
}
List<String> tempList3 = [];
for (var item in obj['countries']) {
tempList3.add(item['name']);
}
setState(() {
mrzDropdownOptions = tempList1;
barcodeDropdownOptions = tempList2;
ocrCountryDropdownOptions = tempList3;
});
}
Future<void> setupAccuraConfig() async {
try {
var config = {
"ACCURA_ERROR_CODE_MOTION": this.language == 'en'
? 'Keep Document Steady'
: 'حافظ على ثبات المستند',
"ACCURA_ERROR_CODE_DOCUMENT_IN_FRAME": this.language == 'en'
? 'Keep document in frame'
: 'احتفظ بالمستند في الإطار',
"ACCURA_ERROR_CODE_BRING_DOCUMENT_IN_FRAME": this.language == 'en'
? 'Bring card near to frame'
: 'إحضار البطاقة بالقرب من الإطار',
"ACCURA_ERROR_CODE_PROCESSING": this.language == 'en'
? 'Processing'
: 'يعالج',
"ACCURA_ERROR_CODE_BLUR_DOCUMENT": this.language == 'en'
? 'Blur detect in document'
: 'كشف التمويه في المستند',
"ACCURA_ERROR_CODE_FACE_BLUR": this.language == 'en'
? 'Blur detected over face'
: 'تم الكشف عن ضبابية على الوجه',
"ACCURA_ERROR_CODE_GLARE_DOCUMENT": this.language == 'en'
? 'Glare detect in document'
: 'كشف الوهج في المستند',
"ACCURA_ERROR_CODE_HOLOGRAM": this.language == 'en'
? 'Hologram Detected'
: 'تم الكشف عن صورة ثلاثية الأبعاد',
"ACCURA_ERROR_CODE_DARK_DOCUMENT": this.language == 'en'
? 'Low lighting detected'
: 'تم الكشف عن إضاءة منخفضة',
"ACCURA_ERROR_CODE_PHOTO_COPY_DOCUMENT": this.language == 'en'
? 'Can not accept Photo Copy Document'
: 'لا يمكن قبول مستند نسخ الصور',
"ACCURA_ERROR_CODE_FACE": this.language == 'en'
? 'Face not detected'
: 'لم يتم الكشف عن الوجه',
"ACCURA_ERROR_CODE_MRZ": this.language == 'en'
? 'MRZ not detected'
: 'لم يتم الكشف عن MRZ',
"ACCURA_ERROR_CODE_PASSPORT_MRZ": this.language == 'en'
? 'Passport MRZ not detected'
: 'لم يتم الكشف عن MRZ جواز سفر',
"ACCURA_ERROR_CODE_ID_MRZ": this.language == 'en'
? 'ID card MRZ not detected'
: 'لم يتم الكشف عن بطاقة الهوية MRZ',
"ACCURA_ERROR_CODE_VISA_MRZ": this.language == 'en'
? 'Visa MRZ not detected'
: 'لم يتم الكشف عن Visa MRZ',
"ACCURA_ERROR_CODE_WRONG_SIDE": this.language == 'en'
? 'Scanning wrong side of document'
: 'مسح الجانب الخطأ من المستند',
"ACCURA_ERROR_CODE_UPSIDE_DOWN_SIDE": this.language == 'en'
? 'Document is upside down. Place it properly'
: 'المستند مقلوب. ضعه بشكل صحيح',
"IS_SHOW_LOGO": false,
"SCAN_TITLE_OCR_FRONT": this.language == 'en'
? 'Scan Front Side of'
: 'مسح الجانب الأمامي من',
"SCAN_TITLE_OCR_BACK": this.language == 'en'
? 'Scan Back Side of'
: 'مسح الجانب الخلفي من',
"SCAN_TITLE_OCR": this.language == 'en' ? 'Scan' : 'مسح',
"SCAN_TITLE_BANKCARD": this.language == 'en'
? 'Scan Bank Card'
: 'مسح البطاقة المصرفية',
"SCAN_TITLE_BARCODE": this.language == 'en'
? 'Scan Barcode'
: 'مسح الرمز الشريطى',
"SCAN_TITLE_MRZ_PDF417_FRONT": this.language == 'en'
? 'Scan Front Side of Document'
: 'مسح الوجه الأمامي للمستند',
"SCAN_TITLE_MRZ_PDF417_BACK": this.language == 'en'
? 'Now Scan Back Side of Document'
: 'الآن مسح الجانب الخلفي من المستند',
"SCAN_TITLE_DLPLATE": this.language == 'en'
? 'Scan Number Plate'
: 'مسح رقم اللوحة'
};
await FlutterAccuraKyc.setupAccuraConfig([config])
.then((value) => {
setState(() {
print("RESULT:- $value");
})
})
.onError((error, stackTrace) => {
showFlutterToast("Error :" + error.toString())
});
} on PlatformException {}
}
Future<void> startOCR() async {
try {
var config = [
{"enableLogs": false},
countrySelected['id'],
cardSelected['id'],
cardSelected['name'],
cardSelected['type'],
getOrientation()
];
print('startOCR:- $config');
await FlutterAccuraKyc.startOcrWithCard(config)
.then((value) => {
setState(() {
_result = json.decode(value);
print("RESULT:- $_result");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultScreen(data: _result)));
})
})
.onError((error, stackTrace) => {
showFlutterToast("Error :" + error.toString())
});
} on PlatformException {}
}
Future<void> startMRZ() async {
try {
var config = [
{"enableLogs": false},
this.mrzSelected["value"],
this.mrzCountryList,
getOrientation()
];
print('startMRZ:- $config');
await FlutterAccuraKyc.startMRZ(config)
.then((value) => {
setState(() {
_result = json.decode(value);
print("RESULT:- $_result");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultScreen(data: _result)));
})
})
.onError((error, stackTrace) => {
showFlutterToast("Error :" + error.toString())
});
} on PlatformException {}
}
Future<void> startBarcode() async {
try {
var config = [
{"enableLogs": false},
this.barcodeSelected["name"],
getOrientation()
];
print('startBarcode:- $config');
await FlutterAccuraKyc.startBarcode(config)
.then((value) => {
setState(() {
_result = json.decode(value);
print("RESULT:- $_result");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultScreen(data: _result)));
})
})
.onError((error, stackTrace) => {
showFlutterToast("Error :" + error.toString())
});
} on PlatformException {}
}
Future<void> startBankCard() async {
try {
var config = [
{"enableLogs": false},
getOrientation()
];
print('startBankCard:- $config');
await FlutterAccuraKyc.startBankCard(config)
.then((value) => {
setState(() {
_result = json.decode(value);
print("RESULT:- $_result");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ResultScreen(data: _result)));
})
})
.onError((error, stackTrace) => {
showFlutterToast("Error :" + error.toString())
});
} on PlatformException {}
}
void onChangeMRZ(value) {
setState(() {
mrzSelected = mrzList.where((i) => i["label"] == value).first;
});
}
void onChangeBarcode(value) {
var selected =
sdkConfig!['barcodes'].where((i) => i['name'] == value).first;
print("SELECTED:- $selected");
setState(() {
barcodeSelected = selected;
});
}
void onChangeCountry(value) {
var selected =
sdkConfig!['countries'].where((i) => i['name'] == value).first;
List<String> tempList = [];
for (var item in selected['cards']) {
tempList.add(item['name']);
}
setState(() {
countrySelected = selected;
cardSelected = {};
selectedCardString = "";
ocrCardDropdownOptions = tempList;
});
}
void onChangeCard(value) {
var selectedCard =
countrySelected['cards'].where((i) => i['name'] == value).first;
setState(() {
cardSelected = selectedCard;
});
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Accura Flutter'),
backgroundColor: Colors.red[800],
),
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/background.png"),
fit: BoxFit.cover,
),
),
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(20),
child: Center(
child: sdkConfig == null
? CircularProgressIndicator()
: !sdkConfig['isValid']
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
"assets/images/license.png",
height: 150,
width: 150,
),
Text(
"License you provided for sacnning is invalid please visit www.accurascan.com for more information.",
textAlign: TextAlign.center,
),
],
)
: Column(
children: [
sdkConfig['isOCR']
? Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5.0,
),
],
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(15))),
padding: EdgeInsets.all(15),
child: Column(
children: [
Text(
'Scan OCR Documents',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
Container(
height: 20,
),
DropdownSearch<String>(
mode: Mode.MENU,
showSearchBox: true,
showSelectedItems: true,
items: ocrCountryDropdownOptions,
label: "Select Country",
onChanged: (value) =>
onChangeCountry(value),
selectedItem: ""),
Container(
height: 20,
),
DropdownSearch<String>(
mode: Mode.MENU,
showSelectedItems: true,
items: ocrCardDropdownOptions,
label: "Select Card",
onChanged: (value) =>
onChangeCard(value),
selectedItem: selectedCardString),
Container(
height: 20,
),
ElevatedButton(
onPressed: countrySelected.length != 0 &&
cardSelected.length != 0
? () => {startOCR()}
: null,
style: ElevatedButton.styleFrom(
primary: Colors.red[800]),
child: Text("START SCAN",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
)),
)
],
),
)
: Container(),
Container(
height: 20,
),
sdkConfig['isMRZ']
? Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5.0,
),
],
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(15))),
padding: EdgeInsets.all(15),
child: Column(
children: [
Text(
'Scan MRZ Documents',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
Container(
height: 20,
),
DropdownSearch<String>(
mode: Mode.MENU,
showSelectedItems: true,
items: mrzDropdownOptions,
label: "Select MRZ Type",
onChanged: (value) =>
onChangeMRZ(value),
selectedItem: ""),
Container(
height: 20,
),
ElevatedButton(
onPressed: mrzSelected.length != 0
? () => {startMRZ()}
: null,
style: ElevatedButton.styleFrom(
primary: Colors.red[800]),
child: Text("START SCAN",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
)),
)
],
),
)
: Container(),
Container(
height: 20,
),
sdkConfig['isBarcode']
? Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5.0,
),
],
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(15))),
padding: EdgeInsets.all(15),
child: Column(
children: [
Text(
'Scan Barcode Documents',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
Container(
height: 20,
),
DropdownSearch<String>(
mode: Mode.MENU,
showSelectedItems: true,
items: barcodeDropdownOptions,
label: "Select Barcode Type",
popupItemDisabled: (String s) =>
s.startsWith('I'),
onChanged: (value) =>
onChangeBarcode(value),
selectedItem: ""),
Container(
height: 20,
),
ElevatedButton(
onPressed: barcodeSelected.length != 0
? () => {startBarcode()}
: null,
style: ElevatedButton.styleFrom(
primary: Colors.red[800]),
child: Text("START SCAN",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
)),
)
],
),
)
: Container(),
Container(
height: 20,
),
sdkConfig['isBankCard']
? Container(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey,
blurRadius: 5.0,
),
],
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(15))),
padding: EdgeInsets.all(15),
child: Column(
children: [
Text(
'Scan Bankcard',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold),
),
Container(
height: 20,
),
Text(
'You can scan any bank card here by tap on "START SCAN" button.',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.bold,
color: Colors.grey[600]),
),
Container(
height: 20,
),
ElevatedButton(
onPressed: () => {startBankCard()},
style: ElevatedButton.styleFrom(
primary: Colors.red[800]),
child: Text("START SCAN",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
)),
)
],
),
)
: Container(),
],
),
),
),
),
),
);
}
}
更多关于Flutter身份验证与KYC审核插件flutter_accura_kyc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter应用中集成身份验证和KYC(Know Your Customer)审核功能,可以使用 flutter_accura_kyc
插件。这个插件通常用于与AccuraScan的KYC服务集成,以进行身份证件验证、人脸识别等操作。以下是如何使用 flutter_accura_kyc
插件的步骤:
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 flutter_accura_kyc
插件的依赖:
dependencies:
flutter:
sdk: flutter
flutter_accura_kyc: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来安装依赖。
2. 配置插件
在 android/app/build.gradle
文件中,确保 minSdkVersion
至少为 21:
android {
defaultConfig {
minSdkVersion 21
...
}
...
}
3. 初始化插件
在你的Flutter应用中初始化 flutter_accura_kyc
插件。通常,你需要在 main.dart
或某个初始化文件中进行初始化。
import 'package:flutter_accura_kyc/flutter_accura_kyc.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化Accura KYC
await FlutterAccuraKyc.initialize(
licenseKey: 'YOUR_LICENSE_KEY', // 从AccuraScan获取的许可证密钥
country: 'US', // 默认国家代码
isShowLogs: true, // 是否显示日志
);
runApp(MyApp());
}
4. 启动KYC流程
在你的应用中,你可以通过调用 startKyc
方法来启动KYC流程。通常,你会在用户点击某个按钮时触发这个流程。
import 'package:flutter/material.dart';
import 'package:flutter_accura_kyc/flutter_accura_kyc.dart';
class KycScreen extends StatelessWidget {
Future<void> startKyc() async {
try {
final result = await FlutterAccuraKyc.startKyc(
country: 'US', // 国家代码
documentType: 'PASSPORT', // 证件类型,如PASSPORT, DRIVING_LICENSE等
isShowLogs: true,
);
// 处理KYC结果
print('KYC Result: $result');
} catch (e) {
print('KYC Error: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('KYC Verification'),
),
body: Center(
child: ElevatedButton(
onPressed: startKyc,
child: Text('Start KYC'),
),
),
);
}
}
5. 处理KYC结果
startKyc
方法会返回一个包含KYC结果的对象。你可以根据返回的结果进行进一步的处理,例如将结果发送到服务器或显示给用户。
final result = await FlutterAccuraKyc.startKyc(
country: 'US',
documentType: 'PASSPORT',
isShowLogs: true,
);
if (result['status'] == 'SUCCESS') {
// KYC成功
print('KYC Successful: ${result['data']}');
} else {
// KYC失败
print('KYC Failed: ${result['error']}');
}
6. 其他功能
flutter_accura_kyc
插件可能还提供其他功能,例如人脸识别、OCR(光学字符识别)等。你可以根据插件的文档来使用这些功能。
7. 注意事项
- 许可证密钥:你需要从AccuraScan获取有效的许可证密钥。
- 网络连接:KYC流程通常需要网络连接,确保设备在启动KYC时处于联网状态。
- 权限:确保你的应用已经请求了必要的权限,例如相机权限、存储权限等。
8. 调试与日志
在开发过程中,你可以启用日志来帮助调试。通过设置 isShowLogs
为 true
,你可以在控制台中看到详细的日志信息。
await FlutterAccuraKyc.initialize(
licenseKey: 'YOUR_LICENSE_KEY',
country: 'US',
isShowLogs: true,
);
9. 发布应用
在发布应用之前,确保你已经禁用了调试日志,并且使用了正确的生产环境许可证密钥。
await FlutterAccuraKyc.initialize(
licenseKey: 'YOUR_PRODUCTION_LICENSE_KEY',
country: 'US',
isShowLogs: false,
);