Flutter身份验证与KYC插件vtcc_ekyc的使用
Flutter身份验证与KYC插件vtcc_ekyc的使用
本示例展示了如何在Flutter项目中使用vtcc_ekyc_flutter
插件来实现身份验证和KYC(Know Your Customer)功能。
开始使用
本项目是一个用于Flutter平台的插件包,包含适用于Android和/或iOS的平台特定实现代码。以下是一些帮助你开始使用Flutter开发的资源:
- 官方文档:在线文档,提供教程、示例、移动开发指导以及完整的API参考。
示例代码
以下是使用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/models/config/ekyc_config.dart';
import 'package:vtcc_ekyc/models/kyc_result.dart';
import 'package:vtcc_ekyc/models/kyc_ui_result.dart';
import 'package:vtcc_ekyc/vtcc_ekyc_flutter.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 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 isRestricted = true;
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();
_vtccEkycFlutterPlugin.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));
}
// 平台消息异步,因此我们初始化在一个异步方法中。
Future<void> initPlatformState() async {
String platformVersion;
// 平台消息可能会失败,所以我们使用一个try/catch PlatformException。
// 我们还处理了消息可能返回null的情况。
try {
platformVersion = "Fuck";
} on PlatformException {
platformVersion = 'Failed to get platform version.';
}
// 如果小部件在异步平台消息飞行时从树中被移除,我们应该丢弃回复而不是调用setState来更新我们的不存在的外观。
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 faceAdvancedMode = isRestricted
? FaceAdvancedMode.RESTRICTED
: FaceAdvancedMode.UNRESTRICTED;
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,
faceAdvancedMode: faceAdvancedMode,
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 _vtccEkycFlutterPlugin.startUIOnlyFlow(config);
ekycUIResult = result;
} else {
final result = await _vtccEkycFlutterPlugin.startNormalFlow(config);
ekycResult = result;
}
openResult(context);
} 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);
}),
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("Is Restricted Mode", isRestricted, (value) {
isRestricted = value;
}),
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的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter身份验证与KYC插件vtcc_ekyc的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter应用中集成身份验证和KYC(Know Your Customer)功能,通常需要使用第三方插件或SDK。vtcc_ekyc
是一个用于越南市场的KYC插件,它可以帮助开发者快速集成KYC功能到Flutter应用中。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 vtcc_ekyc
插件的依赖。
dependencies:
flutter:
sdk: flutter
vtcc_ekyc: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 初始化插件
在使用 vtcc_ekyc
之前,通常需要进行初始化。你可以在 main.dart
或其他适当的地方进行初始化。
import 'package:vtcc_ekyc/vtcc_ekyc.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 初始化vtcc_ekyc
await VtccEkyc.initialize(
apiKey: 'your_api_key',
apiSecret: 'your_api_secret',
);
runApp(MyApp());
}
3. 使用 vtcc_ekyc
进行身份验证和KYC
vtcc_ekyc
提供了多种方法来进行身份验证和KYC操作。以下是一个简单的示例,展示如何使用 vtcc_ekyc
进行身份证验证。
import 'package:flutter/material.dart';
import 'package:vtcc_ekyc/vtcc_ekyc.dart';
class KYCVerifyPage extends StatefulWidget {
[@override](/user/override)
_KYCVerifyPageState createState() => _KYCVerifyPageState();
}
class _KYCVerifyPageState extends State<KYCVerifyPage> {
String _verificationResult = '';
Future<void> _verifyIDCard() async {
try {
// 调用vtcc_ekyc进行身份证验证
final result = await VtccEkyc.verifyIDCard(
frontImagePath: 'path_to_front_image',
backImagePath: 'path_to_back_image',
);
setState(() {
_verificationResult = result ? '验证成功' : '验证失败';
});
} catch (e) {
setState(() {
_verificationResult = '验证失败: $e';
});
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('KYC 验证'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: _verifyIDCard,
child: Text('验证身份证'),
),
SizedBox(height: 20),
Text(_verificationResult),
],
),
),
);
}
}