Skip to content

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 ​

WhatDescription
Flutter SDK>=3.0.0 <4.0.0
iOSiOS 13+, Xcode 16.2
AndroidGradle 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_plugin
bash
flutter pub get

Initialize ​

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);
}
ParamTypeRequiredDefaultDescription
baseUrlStringYes—Base URL for network requests.
accessTokenAccessToken?Yes—Authentication token provider.
languageCodeStringNovivi or en.
loggerLogger?No—Log sink.
exposeImagebool?NofalseSave images to local files.
uiSettingEkycUISetting?No—UI theming.
fontSourcesList<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
  });
}
FieldTypeDescription
facesList<Face>?Captured faces, each with image and gesture.
sanityResultsList<EkycResponse<FaceSanityData>>?Sanity response per image. Note the plural, unlike Android and iOS.
livenessResultEkycResponse<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 ​

FieldTypeDescription
EkycFailure.userCancelErrorCode40001User pressed back.
EkycFailure.timeOutErrorCode40000Timeout.
EkycFailure.cameraErrorCode40003Opening the camera failed. Android only.
EkycFailure.permissionErrorCode40002Permissions were not granted.
EkycFailure.faceSanityFailed60002Sanity check failed.
EkycFailure.faceLivenessFailed60003Liveness check failed.
EkycFailure.unexpectedErrorCode50000Runtime 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.ttf
dart
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.
  });
}

→ Upload Image

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 ​

Developers