Flutter SDK Integration
Capturing faces for FaceAuthen with the CAKE eKYC Flutter plugin, version 1.0.0. The entry point is CakeEkycPlugin. This is the only platform with 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
yaml
dependencies:
cake_image_quality:
path: ../relative/path/to/cake_image_quality
cake_ekyc_plugin:
path: ../relative/path/to/cake_ekyc_pluginbash
flutter pub getInitialize
dart
Future<void> initEkycPlugin() async {
final config = Config(
accessToken: AccessToken.newInstance("<ACCESS_TOKEN>"),
baseUrl: "<BASE_URL>",
languageCode: "vi",
logger: logger,
exposeImage: false, // true writes face 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. |
uiSetting | EkycUISetting? | No | — | UI theming. |
fontSources | List<FontSource>? | No | — | Fonts to register before use. |
Capture Faces
dart
Future<void> takeFaces() async {
CakeEkycPlugin.instance.eventStream.listen((event) {
debugPrint("[EKYC] 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
});
}| Field | Type | Description |
|---|---|---|
faces | List<Face>? | Captured faces, each with image and gesture. |
sanityResults | List<EkycResponse<FaceSanityData>>? | Sanity response per image. Note the plural, unlike Android and iOS. |
livenessResult | EkycResponse<FaceLivenessData>? | Liveness result. |
Take face.image.id from each entry and pass those as the faces array to Register Faces or Verify Face Authen.
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.faceSanityFailed | 60002 | Sanity check failed. |
EkycFailure.faceLivenessFailed | 60003 | Liveness check failed. |
EkycFailure.unexpectedErrorCode | 50000 | Runtime exception. |
Theming the Selfie Screen
Pass an EkycUISetting into Config. For a FaceAuthen flow only the selfie and loading screens apply; the NID screens never appear.
dart
SelfieScreenSetting selfieScreenSetting = SelfieScreenSetting(
backgroundColor: "#000000",
title: title,
backIcon: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
);
SelfieFeedbackLookupTable selfieFeedbackLookupTable;
final uiSetting = EkycUISetting(
darkThemeSetting: darkThemeSetting,
selfieScreenSetting: selfieScreenSetting,
selfieFeedbackLookupTable: selfieFeedbackLookupTable,
loadingScreenSetting: loadingScreenSetting,
);dart
LoadingScreenSetting loadingScreenSetting = LoadingScreenSetting(
backgroundColor: "#FFFFFF",
title: title,
description: description,
bgImage: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
);The selfie screen inherits from darkThemeSetting; the loading screen inherits from lightThemeSetting.
Register fonts
yaml
fonts:
- family: BitcountGridDouble
fonts:
- asset: fonts/BitcountGridDouble-Bold.ttf
- asset: fonts/BitcountGridDouble-Regular.ttfdart
final fontResources = <FontSource>[
FontSource.asset(path: "packages/your_package_name/fonts/BitcountGridDouble-Bold.ttf"),
FontSource.asset(path: "packages/your_package_name/fonts/BitcountGridDouble-Regular.ttf"),
];A fontName on a TextElement only resolves if the same name was registered in fontSources.
Upload Image
dart
Future<void> testUpload() async {
final either = await CakeEkycPlugin.instance.upload(file: filePath, label: "portrait", metaData: metaData);
either.fold((failure) {
debugPrint("[EKYC] failure: code = ${failure.code}");
}, (result) async {
// Send the result to your backend; never log it — it holds biometric data.
});
}Individual Checks
dart
final faceSanity = await CakeEkycPlugin.instance.checkFaceSanity(imageId: "<IMAGE_ID>");
final faceLiveness = await CakeEkycPlugin.instance.checkFaceLiveness(imageIds: ["<IMAGE_ID>"]);
final compared = await CakeEkycPlugin.instance.compareFaces(imageId: "<IMAGE_ID_1>", imageId2: "<IMAGE_ID_2>");Next Steps
- Mobile SDK Overview — concepts shared across platforms
- Register Faces — enrol the captured image IDs
- Verify Face Authen — authenticate with a fresh capture