Skip to content

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 ​

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 and Configure ​

initialize returns true on success.

dart
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);
}
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. By default the plugin does not.
uiSettingEkycUISetting?No—UI theming. See below.
fontSourcesList<FontSource>?No—Fonts to register before use.

Take NID Card ​

takeNID returns an Either<EkycFailure, NIDCardResult>; unwrap it with fold.

dart
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 ​

dart
EkycImage frontSide;

final idCardResult = await CakeEkycPlugin.instance.takeNID(TakeNIDConfig(
    cardSides: [CardSide.back],
    otherSideImages: {CardSide.front: frontSide})
);

Errors ​

FieldTypeDescription
EkycFailure.userCancelErrorCode40001User pressed back.
EkycFailure.timeOutErrorCode40000Timeout.
EkycFailure.cameraErrorCode40003Opening the camera failed. Android only.
EkycFailure.permissionErrorCode40002Permissions were not granted.
EkycFailure.nidSanityFailed60000Sanity check failed.
EkycFailure.nidTamperingFailed60001Tampering check failed.
EkycFailure.unexpectedErrorCode50000Runtime exception.

Take Faces ​

dart
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.

dart
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.

FieldTypeDescription
National ID capturedarkInherits darkThemeSetting.
National ID confirmlightInherits lightThemeSetting.
QR code scanningdarkInherits darkThemeSetting.
SelfiedarkInherits darkThemeSetting.
LoadinglightInherits lightThemeSetting.

Per-screen settings ​

dart
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"),
);
dart
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"
);
dart
NIDScanQRScreenSetting scanQRScreenSetting = NIDScanQRScreenSetting(
  title: title,
  description: description,
  backIcon: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
  backgroundColor: "#FAFAFA"
);
dart
SelfieScreenSetting selfieScreenSetting = SelfieScreenSetting(
  backgroundColor: "#000000",
  title: title,
  backIcon: ImageSource.asset(path: "path_to_your_back_icon_image_file"),
);
dart
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.

yaml
fonts:
  - family: BitcountGridDouble
    fonts:
      - asset: fonts/BitcountGridDouble-Bold.ttf
      - asset: fonts/BitcountGridDouble-Light.ttf
      - asset: fonts/BitcountGridDouble-Regular.ttf
      - asset: fonts/BitcountGridDouble-Medium.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-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 ​

dart
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 ​

dart
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");
MethodAPI
checkNIDSanityVerify ID Card Sanity
checkNIDTamperingDetect ID Card Tampering
readNIDInfoRead ID Card Info
checkFaceSanityVerify Face Sanity
checkFaceLivenessVerify Face Liveness
compareFacesCompare Faces

Next Steps ​

Developers