Flutter身份验证与KYC插件vtcc_ekyc_flutter的使用
Flutter身份验证与KYC插件vtcc_ekyc_flutter的使用
本项目是一个基于Flutter的插件包,用于实现身份验证和KYC(Know Your Customer)功能。该插件包包括了适用于Android和iOS平台的具体实现代码。
开始使用
要开始使用vtcc_ekyc_flutter
插件,请确保你已经安装了Flutter开发环境,并且了解如何创建一个新的Flutter项目。
初始化项目
首先,创建一个新的Flutter项目:
flutter create vtcc_ekyc_example
cd vtcc_ekyc_example
然后,在你的pubspec.yaml
文件中添加vtcc_ekyc_flutter
依赖项:
dependencies:
flutter:
sdk: flutter
vtcc_ekyc_flutter: ^1.0.0 # 请根据实际版本进行替换
运行flutter pub get
来获取依赖项。
示例代码
以下是完整的示例代码,展示了如何在Flutter应用中使用vtcc_ekyc_flutter
插件。
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:multi_select_flutter/multi_select_flutter.dart';
import 'package:vtcc_ekyc_flutter/models/config/ekyc_config.dart';
import 'package:vtcc_ekyc_flutter/models/kyc_result.dart';
import 'package:vtcc_ekyc_flutter/models/kyc_ui_result.dart';
import 'package:vtcc_ekyc_flutter/vtcc_ekyc_flutter.dart';
import 'package:vtcc_ekyc_flutter/vtcc_ekyc_flutter_method_channel.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: TestPage(),
);
}
}
class TestPage extends StatefulWidget {
[@override](/user/override)
State<TestPage> createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
String _platformVersion = 'Unknown';
final _vtccEkycFlutterPlugin = VtccEkycFlutter();
final channel = MethodChannelVtccEkycFlutter();
final trackingLogs = <String>[].toList(growable: true);
var isResultModalVisible = false;
var isTrackingLogVisible = false;
KycUIResult? ekycUIResult;
KycResult? ekycResult;
var normalFlow = FlowType.EKYC_FULL;
var uiFlow = UiFlowType.ID_CARD_FRONT;
var sdkType = SdkType.UI_ONLY;
var isShowAutoCaptureButton = true;
var autoCaptureMode = true;
var isDebug = false;
var isShowHelp = true;
var isEnableVoiceHelp = true;
var flashMode = true;
var isDefaultBackground = true;
var isDefaultPopupBackground = true;
var isDefaultButtonColor = true;
var isDefaultText = true;
var isSkipConfirmScreen = false;
var isImageId = false;
var isCacheImage = false;
var isCacheVideo = false;
var isSmallButtonRadius = false;
var isTestFont = false;
var zoomLevel = 1;
var iouThreshold = 0.92;
var iouCaptureTime = 1000;
var idCardBoxPercentage = 0.025;
var proxyUrl = 'http://ekyc.spower.asia';
var token =
'eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJzcG93ZXIiLCJpYXQiOjE2NzgxMTk2NDUsImV4cCI6Mjg4NzcxOTY0NX0.chpQiH_vlgiCUeLZO30C1YZvUzH7eV6F7SyNqIFyE5qcPZOCLMIfTO9hznXXRogB8DC1YLSs3-46xCIVbUEJOw';
var requestId = '';
var xRequestId = '';
var clientCode = 'spower';
var userId = '02323123213';
var userIdType = UserIdType.PHONE_NUM_TYPE;
var isCardQualityCheck = true;
var isCardSpoofCheck = true;
var isIdCardAbbr = true;
var idCardMinRatio = 0.6;
var cardRetakeLimit = 10;
var frontIdCardId = 'j21sss21321e3';
var idCardCameraMode = CameraMode.BACK;
var idCardTypes = <IdCardType>[IdCardType.CMND, IdCardType.CCCD];
var isFaceSearch = false;
var isFaceSave = false;
var isFaceUpdate = false;
var isFaceQuality = true;
var isFaceLiveness = true;
var faceRetakeLimit = 10;
var faceMinRatio = 0.25;
var faceMaxRatio = 0.7;
var selfieCameraMode = CameraMode.FRONT;
var isAdvancedLiveness = true;
var isAdvancedLivenessFaceMatching = false;
var leftAngle = 30;
var rightAngle = 30;
var challengeRetakeLimit = 4;
var advancedDuration = 20;
var faceGuideUrl = 'https://api24cdn.vtmoney.vn/vtmoney3.mov';
var isNfcChipVerify = false;
var isNfc = false;
var nfcCardNumber = '038096005533';
var nfcBirthDate = '07/08/1996';
var nfcExpiredDate = '07/08/2036';
[@override](/user/override)
void initState() {
super.initState();
initPlatformState();
channel.registerTracking(onTracking);
}
void onTracking(Map<String, dynamic> trackObject) {
final now = DateTime.now();
String formatter = DateFormat.Hms().format(now); // 28/03/2020
trackingLogs.add(formatter);
trackingLogs.add(jsonEncode(trackObject));
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
String platformVersion;
// Platform messages may fail, so we use a try/catch PlatformException.
// We also handle the message potentially returning null.
try {
platformVersion = "Fuck";
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// If the widget was removed from the tree while the asynchronous platform
// message was in flight, we want to discard the reply rather than calling
// setState to update our non-existent appearance.
if (!mounted) return;
setState(() {
_platformVersion = platformVersion;
});
}
void startEkyc() async {
trackingLogs.clear();
final advancedConfig = AdvancedLivenessConfig(
leftAngle: leftAngle,
rightAngle: rightAngle,
challengeRetakeLimit: challengeRetakeLimit,
duration: advancedDuration,
);
final nfcUiConfig = NfcUiConfig(
idNumber: nfcCardNumber,
expiredDate: nfcExpiredDate,
birthDate: nfcBirthDate,
);
// const idCardTypesStr = idCardTypes.filter(item => item.checked).map(item => item.name as IdCardType);
final fontConfig = FontConfig(
regularFontName: 'RobotoMono-Regular',
regularFontSize: 14,
boldFontName: 'RobotoMono-Bold',
boldFontSize: 14,
);
final config = EkycConfig(
advancedGuideVideoUrl: faceGuideUrl,
advancedLivenessConfig: advancedConfig,
autoCaptureMode: autoCaptureMode,
backgroundColor: isDefaultBackground ? '#66000000' : '#FFB84C',
buttonColor: isDefaultButtonColor ? '#EE0033' : '#FFB84C',
popupBackgroundColor: isDefaultPopupBackground ? '#EFEFEE' : '#EDE7F6',
textColor: isDefaultText ? '#FFFFFF' : '#1B9C85',
cardRetakeLimit: cardRetakeLimit,
clientCode: clientCode,
enableVoiceHelp: isEnableVoiceHelp,
faceMaxRatio: faceMaxRatio,
faceMinRatio: faceMinRatio,
faceRetakeLimit: faceRetakeLimit,
flash: flashMode,
flowType: normalFlow,
frontIdCardId: frontIdCardId,
idCardAbbr: isIdCardAbbr,
idCardBoxPercentage: idCardBoxPercentage,
idCardCameraMode: idCardCameraMode,
idCardMinRatio: idCardMinRatio,
idCardTypes: idCardTypes,
isAdvancedLiveness: isAdvancedLiveness,
isAdvancedMatching: isAdvancedLivenessFaceMatching,
isCacheImage: isCacheImage,
isCardQualityCheck: isCardQualityCheck,
isCardSpoofCheck: isCardSpoofCheck,
isDebug: isDebug,
isFaceLiveness: isFaceLiveness,
isFaceQuality: isFaceQuality,
isFaceSave: isFaceSave,
isFaceSearch: isFaceSearch,
isFaceUpdate: isFaceUpdate,
isImageId: isImageId,
isNfc: isNfc,
isSaveVideo: isCacheVideo,
nfcUiConfig: nfcUiConfig,
nfcVerifyOption:
isNfcChipVerify ? NfcVerifyOption.CHIP_DATA_VERIFY : NfcVerifyOption.FACE_VERIFY,
proxyUrl: proxyUrl,
requestId: requestId,
sdkType: sdkType,
selfieCameraMode: selfieCameraMode,
showAutoCaptureButton: isShowAutoCaptureButton,
showHelp: isShowHelp,
skipConfirmScreen: isSkipConfirmScreen,
uiFlowType: uiFlow,
userId: userId,
userIdType: userIdType,
xRequestId: xRequestId,
zoom: zoomLevel,
token: token,
iouThreshold: iouThreshold,
iouCaptureTime: iouCaptureTime,
fontConfig: isTestFont ? fontConfig : null,
buttonCornerRadius: isSmallButtonRadius ? 12 : null,
);
try {
if (sdkType == SdkType.UI_ONLY) {
final result = await channel.startUIOnlyFlow(config);
ekycUIResult = result;
} else {
final result = await channel.startNormalFlow(config);
ekycResult = result;
}
} on Exception catch (e) {
final a = e;
}
}
void openResult(BuildContext context) {
if (sdkType == SdkType.UI_ONLY) {
showDialogForUIOnly();
} else {
showDialogForNormalOnly();
}
}
void showDialogForNormalOnly() {
if (ekycResult == null) {
return;
}
final result = ekycResult!;
final localFrontCardFullImage = result.localFrontCardFullImage ?? "";
final localBackCardFullImage = result.localBackCardFullImage ?? "";
final localFaceFullImage = result.localFaceFullImage ?? "";
final localFrontIdCardUploadImage = result.localFrontIdCardUploadImage ?? "";
final localBackIdCardUploadImage = result.localBackIdCardUploadImage ?? "";
final localFaceUploadImage = result.localFaceUploadImage ?? "";
result.localFrontCardFullImage = '';
result.localBackCardFullImage = '';
result.localFaceFullImage = '';
result.localFrontIdCardUploadImage = '';
result.localBackIdCardUploadImage = '';
result.localFaceUploadImage = '';
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext builder) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title: const Text("Kết quả EKYC"),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
jsonEncode(result.toJson()),
textAlign: TextAlign.left,
),
createImage("localFrontCardFullImage", localFrontCardFullImage),
createImage("localBackCardFullImage", localBackCardFullImage),
createImage("localFaceFullImage", localFaceFullImage),
createImage("localFrontIdCardUploadImage", localFrontIdCardUploadImage),
createImage("localBackIdCardUploadImage", localBackIdCardUploadImage),
createImage("localFaceUploadImage", localFaceUploadImage),
],
),
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('OK'),
),
],
);
},
);
}
void showDialogForUIOnly() {
if (ekycUIResult == null) {
return;
}
final result = ekycUIResult!;
final localCroppedImage = result.localCroppedImage ?? "";
result.localCroppedImage = "";
final localFullImage = result.localFullImage ?? "";
result.localFullImage = "";
String left = "";
String right = "";
if (result.advanceImageDataList != null && result.advanceImageDataList!.isNotEmpty) {
left = result.advanceImageDataList![0].localImage ?? "";
right = result.advanceImageDataList![1].localImage ?? "";
result.advanceImageDataList![0].localImage = '';
result.advanceImageDataList![1].localImage = '';
}
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext builder) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title: const Text("Kết quả EKYC"),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
jsonEncode(result.toJson()),
textAlign: TextAlign.left,
),
createImage("Ảnh crop", localCroppedImage),
createImage("Ảnh Full", localFullImage),
createImage("Ảnh Quay Trái", left),
createImage("Ảnh Quay Phải", right),
],
),
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('OK'),
),
],
);
},
);
}
void showTracking() {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext builder) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title: const Text("Kết quả Tracking"),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: trackingLogs
.map(
(e) => Text(
e,
textAlign: TextAlign.left,
),
)
.toList(),
),
),
actions: <Widget>[
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text('OK'),
),
],
);
},
);
}
final normalFlows = FlowType.values.map((e) => e.name).toList(growable: false);
final uiFlows = UiFlowType.values.map((e) => e.name).toList(growable: false);
final sdkTypes = SdkType.values.map((e) => e.name).toList(growable: false);
final userIdTypes = UserIdType.values.map((e) => e.name).toList(growable: false);
final cameraModes = CameraMode.values.map((e) => e.name).toList(growable: false);
final _items =
IdCardType.values.map((card) => MultiSelectItem<String>(card.name, card.name)).toList();
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
createButton("Start EKYC", startEkyc),
createButton("Open Result", () {
openResult(context);
}),
createButton("Show Tracking", showTracking),
Container(
width: double.infinity,
color: Colors.yellow,
padding: const EdgeInsets.only(top: 16, bottom: 8),
child: const Text(
"Config chung",
style: TextStyle(fontSize: 20),
),
),
createSelect("Normal Flow Type", normalFlow.name, normalFlows, (value) {
normalFlow = FlowType.values.firstWhere((element) => element.name == value);
}),
createSelect("Ui Flow Type", uiFlow.name, uiFlows, (value) {
uiFlow = UiFlowType.values.firstWhere((element) => element.name == value);
}),
createSelect("SDK Type", sdkType.name, sdkTypes, (value) {
sdkType = SdkType.values.firstWhere((element) => element.name == value);
}),
createSwitch("Show Auto Capture Button", isShowAutoCaptureButton, (value) {
isShowAutoCaptureButton = value;
}),
createSwitch("Auto Capture Mode", autoCaptureMode, (value) {
autoCaptureMode = value;
}),
createSwitch("Debug", isDebug, (value) {
isDebug = value;
}),
createSwitch("Show Help", isShowHelp, (value) {
isShowHelp = value;
}),
createSwitch("Enable Voice Help", isEnableVoiceHelp, (value) {
isEnableVoiceHelp = value;
}),
createSwitch("Flash Mode On", flashMode, (value) {
flashMode = value;
}),
createSwitch("Default Background", isDefaultBackground, (value) {
isDefaultBackground = value;
}),
createSwitch("Default Popup Background Color", isDefaultPopupBackground, (value) {
isDefaultPopupBackground = value;
}),
createSwitch("Default Button Color", isDefaultButtonColor, (value) {
isDefaultButtonColor = value;
}),
createSwitch("Default Text", isDefaultText, (value) {
isDefaultText = value;
}),
createSwitch("Skip Confirm Screen", isSkipConfirmScreen, (value) {
isSkipConfirmScreen = value;
}),
createSwitch("Image Id", isImageId, (value) {
isImageId = value;
}),
createSwitch("Cache Image", isCacheImage, (value) {
isCacheImage = value;
}),
createSwitch("Save Video", isCacheVideo, (value) {
isCacheVideo = value;
}),
createSwitch("Test Small Button Radius", isSmallButtonRadius, (value) {
isSmallButtonRadius = value;
}),
createSwitch("Test Another Font", isTestFont, (value) {
isTestFont = value;
}),
createInput("Zoom Level", zoomLevel.toString(), (value) {
zoomLevel = int.parse(value);
}),
createInput("IOU Threshold", iouThreshold.toString(), (value) {
iouThreshold = double.parse(value);
}),
createInput("IOU Capture Time", iouCaptureTime.toString(), (value) {
iouCaptureTime = int.parse(value);
}),
createInput("IdCard Capture Box", idCardBoxPercentage.toString(), (value) {
idCardBoxPercentage = double.parse(value);
}),
createInput("IdCard Capture Box", idCardBoxPercentage.toString(), (value) {
idCardBoxPercentage = double.parse(value);
}),
Container(
width: double.infinity,
color: Colors.yellow,
padding: const EdgeInsets.only(top: 16, bottom: 16),
margin: const EdgeInsets.only(top: 16, bottom: 16),
child: const Text(
"Config Authentication",
style: TextStyle(fontSize: 20),
),
),
createInput("Proxy Url", proxyUrl, (value) {
proxyUrl = value;
}),
createInput("Client Code", clientCode, (value) {
clientCode = value;
}),
createInput("Token", token, (value) {
token = value;
}),
createInput("Request Id", requestId, (value) {
requestId = value;
}),
createInput("X Request Id", xRequestId, (value) {
xRequestId = value;
}),
createInput("User Id", userId, (value) {
userId = value;
}),
createSelect("User Id Type", userIdType.name, userIdTypes, (value) {
userIdType = UserIdType.values.firstWhere((element) => element.name == value);
}),
Container(
width: double.infinity,
color: Colors.yellow,
padding: const EdgeInsets.only(top: 16, bottom: 16),
margin: const EdgeInsets.only(top: 16, bottom: 16),
child: const Text(
"Card Config",
style: TextStyle(fontSize: 20),
),
),
MultiSelectDialogField(
onConfirm: (val) {
idCardTypes = IdCardType.values
.where(
(element) => val.where((element1) => element1 == element.name).isNotEmpty)
.toList();
// _selectedAnimals5 = val;
},
// dialogWidth: MediaQuery.of(context).size.width * 0.7,
items: _items,
initialValue: idCardTypes
.map((e) => e.name)
.toList(), // setting the value of this in initState() to pre-select values.
),
createSelect("Card Camera", idCardCameraMode.name, cameraModes, (value) {
idCardCameraMode = CameraMode.values.firstWhere((element) => element.name == value);
}),
createSwitch("Card Quality Check", isCardQualityCheck, (value) {
isCardQualityCheck = value;
}),
createSwitch("Card Spoof Check", isCardSpoofCheck, (value) {
isCardSpoofCheck = value;
}),
createSwitch("Card Abbr", isIdCardAbbr, (value) {
isIdCardAbbr = value;
}),
createInput("Card Retake Limit", cardRetakeLimit.toString(), (value) {
cardRetakeLimit = int.parse(value);
}),
createInput("Card Min Ratio", idCardMinRatio.toString(), (value) {
idCardMinRatio = double.parse(value);
}),
createInput("Front Card Image Id", frontIdCardId, (value) {
frontIdCardId = value;
}),
Container(
width: double.infinity,
color: Colors.yellow,
padding: const EdgeInsets.only(top: 16, bottom: 16),
margin: const EdgeInsets.only(top: 16, bottom: 16),
child: const Text(
"Face Config",
style: TextStyle(fontSize: 20),
),
),
createSwitch("Face Quality Check", isFaceQuality, (value) {
isFaceQuality = value;
}),
createSwitch("Face Liveness", isFaceLiveness, (value) {
isFaceLiveness = value;
}),
createSwitch("Face Search", isFaceSearch, (value) {
isFaceSearch = value;
}),
createSwitch("Face Save", isFaceSave, (value) {
isFaceSave = value;
}),
createSwitch("Face Update", isFaceUpdate, (value) {
isFaceUpdate = value;
}),
createSelect("Selfie Camera", selfieCameraMode.name, cameraModes, (value) {
selfieCameraMode = CameraMode.values.firstWhere((element) => element.name == value);
}),
createInput("Face Retake Limit", faceRetakeLimit.toString(), (value) {
faceRetakeLimit = int.parse(value);
}),
createInput("Face Min Ratio", faceMinRatio.toString(), (value) {
faceMinRatio = double.parse(value);
}),
createInput("Face Max Ratio", faceMaxRatio.toString(), (value) {
faceMaxRatio = double.parse(value);
}),
Container(
width: double.infinity,
color: Colors.yellow,
padding: const EdgeInsets.only(top: 16, bottom: 16),
margin: const EdgeInsets.only(top: 16, bottom: 16),
child: const Text(
"Face Advanced Config",
style: TextStyle(fontSize: 20),
),
),
createSwitch("Advanced Liveness", isAdvancedLiveness, (value) {
isAdvancedLiveness = value;
}),
createSwitch("Advanced Liveness FaceMatching", isAdvancedLivenessFaceMatching,
(value) {
isAdvancedLivenessFaceMatching = value;
}),
createInput("Left Angle", leftAngle.toString(), (value) {
leftAngle = int.parse(value);
}),
createInput("Right Angle", rightAngle.toString(), (value) {
rightAngle = int.parse(value);
}),
createInput("Challenge Retake Limit", challengeRetakeLimit.toString(), (value) {
challengeRetakeLimit = int.parse(value);
}),
createInput("Advanced Liveness Duration", advancedDuration.toString(), (value) {
advancedDuration = int.parse(value);
}),
createInput("Advanced Guide - Video URL", faceGuideUrl, (value) {
faceGuideUrl = value;
}),
Container(
width: double.infinity,
color: Colors.yellow,
padding: const EdgeInsets.only(top: 16, bottom: 16),
margin: const EdgeInsets.only(top: 16, bottom: 16),
child: const Text(
"NFC Config",
style: TextStyle(fontSize: 20),
),
),
createSwitch("Nfc Chip Data Verify", isNfcChipVerify, (value) {
isNfcChipVerify = value;
}),
createSwitch("Is NFC", isNfc, (value) {
isNfc = value;
}),
createInput("NFC ID Card Number", nfcCardNumber, (value) {
nfcCardNumber = value;
}),
createInput("Birthday dd/mm/yyyy", nfcBirthDate, (value) {
nfcBirthDate = value;
}),
createInput("Expired Date dd/mm/yyyy", nfcExpiredDate, (value) {
nfcExpiredDate = value;
}),
],
),
),
),
);
}
Widget createImage(String text, String imageData) {
if (imageData.isEmpty) {
return const SizedBox();
}
return Column(
children: [Text(text), Image.memory(base64Decode(imageData))],
);
}
Widget createButton(String text, VoidCallback t) {
return SizedBox(
width: double.infinity,
child: ElevatedButton(onPressed: t, child: Text(text)),
);
}
Widget createInput(String text, String initValue, ValueChanged<String> t) {
return Column(
children: [
Text(text),
TextFormField(
initialValue: initValue,
decoration: InputDecoration(
hintText: text,
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.blue, width: 1)),
),
onChanged: (value) {
t.call(value);
},
),
],
);
}
Widget createSelect(
String text, String selectedItem, List<String> values, ValueChanged<String> t) {
return Row(children: [
Expanded(
flex: 2,
child: Text(text),
),
DropdownButton<String>(
value: selectedItem,
elevation: 16,
style: const TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.deepPurpleAccent,
),
onChanged: (String? value) {
// This is called when the user selects an item.
setState(() {
if (value != null) {
t.call(value);
}
});
},
items: values.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
)
]);
}
Widget createSwitch(String text, bool value, ValueChanged<bool> t) {
return Row(
children: [
Expanded(
flex: 4,
child: Text(text, softWrap: true),
),
Switch(
// This bool value toggles the switch.
value: value,
activeColor: Colors.red,
onChanged: (bool value) {
// This is called when the user toggles the switch.
setState(() {
t.call(value);
});
},
),
],
);
}
}
更多关于Flutter身份验证与KYC插件vtcc_ekyc_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter身份验证与KYC插件vtcc_ekyc_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
vtcc_ekyc_flutter
是一个用于在 Flutter 应用中集成身份验证和 KYC(Know Your Customer)功能的插件。这个插件通常与第三方服务(如 VTCC)集成,以提供身份验证、人脸识别、身份证验证等功能。以下是如何在 Flutter 应用中使用 vtcc_ekyc_flutter
插件的步骤。
1. 添加依赖
首先,在 pubspec.yaml
文件中添加 vtcc_ekyc_flutter
插件的依赖:
dependencies:
flutter:
sdk: flutter
vtcc_ekyc_flutter: ^1.0.0 # 请根据实际情况使用最新版本
然后,运行 flutter pub get
以安装依赖。
2. 配置插件
在使用插件之前,可能需要进行一些配置,例如设置 API 密钥或配置服务端地址。这些配置通常可以在插件的文档中找到。
3. 初始化插件
在应用的 main.dart
或适当的位置初始化插件:
import 'package:vtcc_ekyc_flutter/vtcc_ekyc_flutter.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化插件
await VtccEkycFlutter.initialize(
apiKey: 'your_api_key', // 替换为你的 API 密钥
baseUrl: 'https://your-api-endpoint.com', // 替换为你的 API 地址
);
runApp(MyApp());
}
4. 使用插件进行身份验证和 KYC
在需要执行身份验证或 KYC 的地方调用插件的相应方法。以下是一些常见的操作示例:
4.1. 人脸识别
try {
final result = await VtccEkycFlutter.faceRecognition(
imagePath: 'path_to_image', // 替换为图像路径
);
print('Face Recognition Result: $result');
} catch (e) {
print('Error during face recognition: $e');
}
4.2. 身份证验证
try {
final result = await VtccEkycFlutter.idCardVerification(
frontImagePath: 'path_to_front_image', // 替换为身份证正面图像路径
backImagePath: 'path_to_back_image', // 替换为身份证背面图像路径
);
print('ID Card Verification Result: $result');
} catch (e) {
print('Error during ID card verification: $e');
}
4.3. 活体检测
try {
final result = await VtccEkycFlutter.livenessDetection(
imagePath: 'path_to_image', // 替换为图像路径
);
print('Liveness Detection Result: $result');
} catch (e) {
print('Error during liveness detection: $e');
}
5. 处理结果
插件通常会返回一个包含验证结果的 Map
或自定义对象。你可以根据这些结果来决定应用的下一步操作。
if (result['status'] == 'success') {
// 验证成功,继续后续操作
} else {
// 验证失败,显示错误信息
}
6. 错误处理
确保在使用插件时捕获并处理可能出现的错误。这有助于提高应用的健壮性。
try {
final result = await VtccEkycFlutter.faceRecognition(
imagePath: 'path_to_image',
);
print('Face Recognition Result: $result');
} catch (e) {
print('Error during face recognition: $e');
}