Tích hợp Flutter SDK
Hướng dẫn tích hợp eKYC Flutter plugin, phiên bản 1.0.0. Entry point là singleton CakeEkycPlugin. Đây là nền tảng duy nhất expose đầy đủ khả năng tùy biến giao diện.
Yêu cầu build
| Thông tin | Mô tả |
|---|---|
| Flutter SDK | >=3.0.0 <4.0.0 |
| iOS | iOS 13+, Xcode 16.2 |
| Android | Gradle 7.4, minSdkVersion 21, targetSdkVersion 33 |
Cài đặt
dependencies:
cake_image_quality:
path: ../relative/path/to/cake_image_quality
cake_ekyc_plugin:
path: ../relative/path/to/cake_ekyc_pluginflutter pub getKhởi tạo và cấu hình
initialize trả về true khi thành công.
Future<void> initEkycPlugin() async {
final config = Config(
accessToken: AccessToken.newInstance("<ACCESS_TOKEN>"),
baseUrl: "<BASE_URL>",
languageCode: "vi", // vi cho tiếng Việt, en cho tiếng Anh
logger: logger,
exposeImage: false, // true sẽ ghi ảnh CCCD và selfie ra file local — chỉ bật khi thật sự cần
);
await CakeEkycPlugin.instance.initialize(config);
}| Tham số | Kiểu | Bắt buộc | Mặc định | Mô tả |
|---|---|---|---|---|
baseUrl | String | Có | — | Base URL cho các network request. |
accessToken | AccessToken? | Có | — | Provider cung cấp authentication token. |
languageCode | String | Không | vi | vi hoặc en. |
logger | Logger? | Không | — | Sink nhận log. |
exposeImage | bool? | Không | false | Lưu ảnh vào file cục bộ. Mặc định plugin không làm việc này. |
uiSetting | EkycUISetting? | Không | — | Tùy biến giao diện. Xem bên dưới. |
fontSources | List<FontSource>? | Không | — | Font cần đăng ký trước khi sử dụng. |
Chụp thẻ NID
takeNID trả về một Either<EkycFailure, NIDCardResult>; dùng fold để lấy giá trị bên trong.
Future<void> takeNID() async {
CakeEkycPlugin.instance.eventStream.listen((event) {
debugPrint("[EKYC] event => eventId = ${event.eventId}"); // params có thể chứa ảnh — không ghi log
});
final config = TakeNIDConfig(
cardType: CardType.cccd,
cardSides: [CardSide.front, CardSide.back],
requiredReview: true,
enableAutoCapture: true,
requiredScanQR: false,
captureOnly: false);
final idCardResult = await CakeEkycPlugin.instance.takeNID(config);
idCardResult.fold((failure) {
debugPrint("[EKYC] failure: code = ${failure.code}, message = ${failure.message}");
}, (idCardResult) async {
// Nhận và xử lý kết quả thẻ NID tại đây
});
}INFO
Cờ tự động chụp có tên enableAutoCapture trong config của Flutter, nhưng là autoCaptureEnable trên Android và iOS — và ngay cả trang tài liệu tham chiếu của Flutter cũng liệt kê nó là autoCaptureEnable. Hãy xác nhận lại với phiên bản plugin bạn đang cài đặt.
Truyền mặt còn lại
EkycImage frontSide;
final idCardResult = await CakeEkycPlugin.instance.takeNID(TakeNIDConfig(
cardSides: [CardSide.back],
otherSideImages: {CardSide.front: frontSide})
);Lỗi
| Trường | Kiểu | Mô tả |
|---|---|---|
EkycFailure.userCancelErrorCode | 40001 | Người dùng nhấn back. |
EkycFailure.timeOutErrorCode | 40000 | Timeout. |
EkycFailure.cameraErrorCode | 40003 | Mở camera thất bại. Chỉ Android. |
EkycFailure.permissionErrorCode | 40002 | Các quyền chưa được cấp. |
EkycFailure.nidSanityFailed | 60000 | Kiểm tra sanity thất bại. |
EkycFailure.nidTamperingFailed | 60001 | Kiểm tra giả mạo thất bại. |
EkycFailure.unexpectedErrorCode | 50000 | Runtime exception. |
Chụp khuôn mặt
Future<void> takeFaces() async {
CakeEkycPlugin.instance.eventStream.listen((event) {
debugPrint("[EKYC] event => eventId = ${event.eventId}"); // params có thể chứa ảnh — không ghi log
});
final config = TakeFaceConfig(captureOnly: false);
final selfieResult = await CakeEkycPlugin.instance.takeFaces(config);
selfieResult.fold((failure) {
debugPrint("[EKYC] failure: code = ${failure.code}, message = ${failure.message}");
}, (selfieResult) async {
// xử lý kết quả selfie tại đây
});
}Lỗi chất lượng ở đây mang faceSanityFailed (60002) hoặc faceLivenessFailed (60003).
Tùy biến giao diện
SDK có năm màn hình: Chụp CCCD, Xác nhận CCCD, Quét mã QR, Selfie và Loading. Truyền một EkycUISetting vào Config.
final uiSetting = EkycUISetting(
darkThemeSetting: dartThemeSetting,
lightThemeSetting: lightThemeSetting,
nidCaptureScreenSetting: nidCaptureScreenSetting,
nidConfirmScreenSetting: nidConfirmScreenSetting,
nidFeedbackLookupTable: nidFeedbackLookupTable,
scanQRScreenSetting: scanQRScreenSetting,
selfieScreenSetting: selfieScreenSetting,
selfieFeedbackLookupTable: selfieFeedbackLookupTable,
loadingScreenSetting: loadingScreenSetting,
);
Future<void> initEkycPlugin() async {
final config = Config(
accessToken: AccessToken.newInstance("<ACCESS_TOKEN>"),
baseUrl: "<BASE_URL>",
enableLog: false,
uiSetting: uiSetting,
fontSources: fontResources
);
await CakeEkycPlugin.instance.initialize(config);
}Theme mặc định theo từng màn hình
Theo mặc định, mỗi màn hình kế thừa từ darkThemeSetting hoặc lightThemeSetting, với màu nền lấy từ primaryColor của theme đó.
| Trường | Kiểu | Mô tả |
|---|---|---|
| Chụp CCCD | dark | Kế thừa darkThemeSetting. |
| Xác nhận CCCD | light | Kế thừa lightThemeSetting. |
| Quét mã QR | dark | Kế thừa darkThemeSetting. |
| Selfie | dark | Kế thừa darkThemeSetting. |
| Loading | light | Kế thừa lightThemeSetting. |
Thiết lập theo từng màn hình
NIDCaptureScreenSetting nidCaptureScreenSetting = NIDCaptureScreenSetting(
backgroundColor: "#000000",
title: {CardSide.front: frontTitle, CardSide.back: backTitle},
autoCaptureSwitch: autoCaptureSwitch,
backIcon: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
);NIDConfirmScreenSetting nidConfirmScreenSetting = NIDConfirmScreenSetting(
title: {CardSide.front: frontTitle, CardSide.back: backTitle},
description: description,
acceptBtn: acceptBtn,
denyBtn: denyBtn,
backIcon: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
backgroundColor: "#FAFAFA"
);NIDScanQRScreenSetting scanQRScreenSetting = NIDScanQRScreenSetting(
title: title,
description: description,
backIcon: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
backgroundColor: "#FAFAFA"
);SelfieScreenSetting selfieScreenSetting = SelfieScreenSetting(
backgroundColor: "#000000",
title: title,
backIcon: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
);LoadingScreenSetting loadingScreenSetting = LoadingScreenSetting(
backgroundColor: "#FFFFFF",
title: title,
description: description,
bgImage: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
);Đăng ký font
Khai báo font trong pubspec.yaml, sau đó đăng ký chúng với SDK.
fonts:
- family: BitcountGridDouble
fonts:
- asset: fonts/BitcountGridDouble-Bold.ttf
- asset: fonts/BitcountGridDouble-Light.ttf
- asset: fonts/BitcountGridDouble-Regular.ttf
- asset: fonts/BitcountGridDouble-Medium.ttffinal fontResources = <FontSource>[
FontSource.asset(path: "packages/your_package_name/fonts/BitcountGridDouble-Bold.ttf"),
FontSource.asset(path: "packages/your_package_name/fonts/BitcountGridDouble-Light.ttf"),
FontSource.asset(path: "packages/your_package_name/fonts/BitcountGridDouble-Regular.ttf"),
FontSource.asset(path: "packages/your_package_name/fonts/BitcountGridDouble-Medium.ttf"),
];Tải ảnh lên
Future<void> testUpload() async {
final either = await CakeEkycPlugin.instance.upload(file: filePath, label: label, metaData: metaData);
either.fold((failure) {
debugPrint("[EKYC] failure: code = ${failure.code}, message = ${failure.message}");
}, (result) async {
// Gửi kết quả về backend của bạn; không ghi log — nó chứa dữ liệu định danh.
});
}Xem Tổng quan Mobile SDK § Nhãn ảnh để biết các giá trị label được phép.
Các lệnh gọi API riêng lẻ
final sanity = await CakeEkycPlugin.instance.checkNIDSanity(
imageId: "front_or_back_nid_image_id",
imageId2: "front_or_back_nid_image_id",
cardType: "vn.national_id",
specialTypeId: null);
final tampering = await CakeEkycPlugin.instance.checkNIDTampering(
imageId: "front_or_back_nid_image_id",
imageId2: "front_or_back_nid_image_id",
cardType: "vn.national_id",
level: null);
final nidInfo = await CakeEkycPlugin.instance.readNIDInfo(
imageId: "front_or_back_nid_image_id",
imageId2: "front_or_back_nid_image_id",
cardType: "vn.national_id");
final faceSanity = await CakeEkycPlugin.instance.checkFaceSanity(imageId: "face_image_id");
final faceLiveness = await CakeEkycPlugin.instance.checkFaceLiveness(imageIds: ["face_image_id"]);
final compared = await CakeEkycPlugin.instance.compareFaces(imageId: "face_1", imageId2: "face_2");| Phương thức | API |
|---|---|
checkNIDSanity | Xác minh ID Card Sanity |
checkNIDTampering | Phát hiện giả mạo thẻ ID |
readNIDInfo | Đọc thông tin thẻ ID |
checkFaceSanity | Xác minh sanity khuôn mặt |
checkFaceLiveness | Xác minh liveness khuôn mặt |
compareFaces | So sánh khuôn mặt |
Bước tiếp theo
- Tài liệu tham chiếu Flutter SDK — mọi class, thuộc tính và phương thức công khai
- Tổng quan Mobile SDK — các khái niệm dùng chung giữa các nền tảng