Skip to main content

flutter_ondevice_kyc 1.1.0 copy "flutter_ondevice_kyc: ^1.1.0" to clipboard
flutter_ondevice_kyc: ^1.1.0 copied to clipboard

PlatformAndroid

On-device KYC scanning for MRZ and card numbers. The scan path makes no network call.

flutter_ondevice_kyc #

On-device KYC for an identity-card MRZ and a payment-card number. The scan path does not open a socket and does not write the frame.

A frame is published only when ICAO 9303 or Luhn accepts it. A miss is a rejected frame, not an exception. The name line has no check digit. The green lock waits on the document number, dates, and composite digit.

The code is MIT. The detector is YOLOX-Nano and the recognizer is the official en_PP-OCRv4_mobile_rec. Both weights are Apache-2.0. This version has no CVV, NFC, or face match.

Turkish process notes: doc/on-device-kyc.tr.md.

Example #

These frames are the example app on an Android emulator. The locked fields are the ICAO 9303 specimen, not a real document. The scan tab draws the card guide; the emulator camera has no scene behind it.

Paste Lock Scan
Validation tab Checksum lock Scan guide

Example recording

What it reads #

Document Shape Gate
Identity card back, including the Turkish card TD1, 3×30 ICAO check digits. An 11-digit run in the optional data must also pass the TCKN test
Passport TD3, 2×44 ICAO check digits
Older booklet TD2, 2×36 ICAO check digits
Payment card 13–19 digits Luhn. The CVV is not read

Names come out in MRZ Latin. Turkish dotted letters are not in those lines.

The detector was fine-tuned on synthetic cards. A real card is still read when the MRZ lines sit in the frame. This repository does not contain photographs of real identity documents.

Pipeline #

flowchart TD
  camera[Camera frame]
  focus[Focus the MRZ band, then lock]
  throttle[At most 5 fps]
  orient[Rotate upright and crop the guide]
  detect[YOLOX-Nano ONNX]
  warp[Homography]
  lines[Split MRZ lines]
  ocr[PP-OCRv4 per line]
  gate[ICAO 9303, TCKN, or Luhn]
  emit[KycCapture]
  camera --> focus --> throttle --> orient --> detect --> warp --> lines --> ocr --> gate
  gate -->|accepts| emit
  gate -->|rejects| throttle

Runtime is flutter_onnxruntime 1.9. The default provider is CPU. XNNPACK and CoreML are opt-in through KycExecutionProvider. NNAPI is not a default: it is slow on these small graphs and it is deprecated on Android 15.

Integrate #

The host app owns the model files. Copy example/assets/models/ into the host assets and list the three files in the host pubspec.yaml. Digests are in assets/models/README.md.

dependencies:
  flutter_ondevice_kyc: ^1.1.0

flutter:
  assets:
    - assets/models/card_detector.onnx
    - assets/models/text_rec.onnx
    - assets/models/en_dict.txt
final scanner = await KycScanner.onnx(
  detectorAsset: 'assets/models/card_detector.onnx',
  recognizerAsset: 'assets/models/text_rec.onnx',
  dictionaryAsset: 'assets/models/en_dict.txt',
);

KycScanView(
  scanner: scanner,
  onLocked: (capture) {},
);

KycScanView opens the back camera, draws the card guide and the three MRZ marks, and locks focus on that band. onLocked runs when a checksum matches.

Android: the plugin manifest adds CAMERA, and consumer-proguard.pro keeps ai.onnxruntime.** so a minified release build does not rename the ONNX Runtime classes. iOS: add NSCameraUsageDescription to the host Info.plist, and set the deployment target to 16.0. The plugin cannot write that string for you.

Run #

Flutter 3.24 or newer. The example is a host app: its models live in example/assets/models/.

flutter pub get
flutter test
cd example
flutter pub get
flutter test
flutter run

The scan tab embeds KycScanView. Tap the image to focus again. The validation tab locks pasted text. That lock did not come from a document.

Measure #

Lock rate, false-lock rate, and p95 are defined in eval/README.md. Frames and the manifest stay outside git. The fixture test checks the arithmetic. A model measurement points KYC_EVAL_DIR at a private folder.

API #

final scanner = await KycScanner.onnx(
  detectorAsset: 'assets/models/card_detector.onnx',
  recognizerAsset: 'assets/models/text_rec.onnx',
  dictionaryAsset: 'assets/models/en_dict.txt',
);
final decision = await scanner.scanStill(image);
if (decision is ScanLocked) {
  final capture = decision.capture;
}
await scanner.dispose();

KycScanner.fixture() locks the ICAO specimen when the weight files are absent. ScanRejected is not an exception. checkManual is for pasted text. redactPan is for logs. The full number lives on KycCapture.cardNumber, and the host should not store it.

Models #

Weights live in example/assets/models/. Digests are in assets/models/README.md.

File Source Size
card_detector.onnx YOLOX-Nano, 3 classes, 416, FP32 8.6 MB
text_rec.onnx en_PP-OCRv4_mobile_rec, opset 11, FP32 7.3 MB
en_dict.txt PaddleOCR English dictionary, including < 190 B

Training scripts are in training/. The Colab notebook is training/colab_yolox.ipynb. It draws a held-out synthetic set and fine-tunes YOLOX-Nano. The checked-in detector is that fine-tune. Checkpoints and generated images stay out of git. Detector INT8 is only worth doing with a calibration set that keeps detection quality. The recognizer stayed FP32.

Privacy #

lib/ does not import dart:io or an HTTP client. A frame stays in memory. Logs do not contain a PAN, an MRZ line, or a TCKN. The example Android manifest has no internet permission. This is not a legal opinion. It states that the scan path does not open a network connection and does not write an image.

Versions and contributions #

Versioning is in VERSIONING.md. Contributions are in CONTRIBUTING.md. A pull request must name an open issue that a maintainer has labeled accepted. Other pull requests are closed.

1
likes
140
points
200
downloads

Documentation

API reference

Publisher

verified publisherabdullahtas.dev

Weekly Downloads

On-device KYC scanning for MRZ and card numbers. The scan path makes no network call.

Repository (GitHub)
View/report issues
Contributing

Topics

#ocr #camera #identity

License

MIT (license)

Dependencies

camera, flutter, flutter_onnxruntime

More

Packages that depend on flutter_ondevice_kyc

Packages that implement flutter_ondevice_kyc