Flutter SDK Integration
Integration guide for the eKYC Flutter plugin, version 1.0.0. The entry point is the CakeEkycPlugin singleton. This is the only platform that exposes full UI theming.
Build Specifications
| What | Description |
|---|---|
| Flutter SDK | >=3.0.0 <4.0.0 |
| iOS | iOS 13+, Xcode 16.2 |
| Android | Gradle 7.4, minSdkVersion 21, targetSdkVersion 33 |
Installation
dependencies:
cake_image_quality:
path: ../relative/path/to/cake_image_quality
cake_ekyc_plugin:
path: ../relative/path/to/cake_ekyc_pluginflutter pub getInitialize and Configure
initialize returns true on success.
Future<void> initEkycPlugin() async {
final config = Config(
accessToken: AccessToken.newInstance("<ACCESS_TOKEN>"),
baseUrl: "<BASE_URL>",
languageCode: "vi", // vi for Vietnamese, en for English
logger: logger,
exposeImage: false, // true writes ID and selfie images to local files — keep false unless you must
);
await CakeEkycPlugin.instance.initialize(config);
}| Param | Type | Required | Default | Description |
|---|---|---|---|---|
baseUrl | String | Yes | — | Base URL for network requests. |
accessToken | AccessToken? | Yes | — | Authentication token provider. |
languageCode | String | No | vi | vi or en. |
logger | Logger? | No | — | Log sink. |
exposeImage | bool? | No | false | Save images to local files. By default the plugin does not. |
uiSetting | EkycUISetting? | No | — | UI theming. See below. |
fontSources | List<FontSource>? | No | — | Fonts to register before use. |
Take NID Card
takeNID returns an Either<EkycFailure, NIDCardResult>; unwrap it with fold.
Future<void> takeNID() async {
CakeEkycPlugin.instance.eventStream.listen((event) {
debugPrint("[EKYC] event => eventId = ${event.eventId}"); // params can carry images — don't log them
});
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 {
// Receive and handle NID card result here
});
}INFO
The auto-capture flag is named enableAutoCapture in the Flutter config, but autoCaptureEnable on Android and iOS — and the Flutter reference page itself lists it as autoCaptureEnable. Verify against the plugin version you have installed.
Passing the other side
EkycImage frontSide;
final idCardResult = await CakeEkycPlugin.instance.takeNID(TakeNIDConfig(
cardSides: [CardSide.back],
otherSideImages: {CardSide.front: frontSide})
);Errors
| Field | Type | Description |
|---|---|---|
EkycFailure.userCancelErrorCode | 40001 | User pressed back. |
EkycFailure.timeOutErrorCode | 40000 | Timeout. |
EkycFailure.cameraErrorCode | 40003 | Opening the camera failed. Android only. |
EkycFailure.permissionErrorCode | 40002 | Permissions were not granted. |
EkycFailure.nidSanityFailed | 60000 | Sanity check failed. |
EkycFailure.nidTamperingFailed | 60001 | Tampering check failed. |
EkycFailure.unexpectedErrorCode | 50000 | Runtime exception. |
Take Faces
Future<void> takeFaces() async {
CakeEkycPlugin.instance.eventStream.listen((event) {
debugPrint("[EKYC] event => eventId = ${event.eventId}"); // params can carry images — don't log them
});
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 {
// handle selfie result here
});
}Quality failures here carry faceSanityFailed (60002) or faceLivenessFailed (60003).
Customize UI
The SDK has five screens: National ID capture, National ID confirm, QR code scanning, Selfie and Loading. Pass an EkycUISetting into 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);
}Default theme per screen
By default every screen inherits from darkThemeSetting or lightThemeSetting, with the background taken from that theme's primaryColor.
| Field | Type | Description |
|---|---|---|
| National ID capture | dark | Inherits darkThemeSetting. |
| National ID confirm | light | Inherits lightThemeSetting. |
| QR code scanning | dark | Inherits darkThemeSetting. |
| Selfie | dark | Inherits darkThemeSetting. |
| Loading | light | Inherits lightThemeSetting. |
Per-screen settings
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"),
);Register fonts
Declare the fonts in pubspec.yaml, then register them with the 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"),
];Upload Image
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 {
// Send the result to your backend; never log it — it holds identity data.
});
}See Mobile SDK Overview § Image Labels for permitted label values.
Individual API Calls
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");| Method | API |
|---|---|
checkNIDSanity | Verify ID Card Sanity |
checkNIDTampering | Detect ID Card Tampering |
readNIDInfo | Read ID Card Info |
checkFaceSanity | Verify Face Sanity |
checkFaceLiveness | Verify Face Liveness |
compareFaces | Compare Faces |
Next Steps
- Flutter SDK Reference — every public class, property and method
- Mobile SDK Overview — concepts shared across platforms