prism_ekyc 0.2.0
prism_ekyc: ^0.2.0 copied to clipboard
Prism eKYC – NFC + Camera + Face Verification Flutter package for Japanese ID documents.
prism_ekyc #
A Flutter plugin for eKYC (electronic Know Your Customer) of Japanese IC cards. Reads Residence Cards (在留カード) via NFC, captures the card backside via camera, and verifies the user's face.
Platform support: Android · iOS
Features #
| Feature | Android | iOS |
|---|---|---|
| NFC read (Residence Card) | ✅ libjeid | ✅ libjeid.xcframework |
| Card front image (PNG) | ✅ | ✅ |
| Face photo | ✅ JPEG | ✅ JPEG2000 |
| Chip address / permissions | ✅ | ✅ |
| Card backside camera capture | ✅ | ✅ |
| Face verification (Vision / ML Kit) | ✅ | ✅ |
| OCR (card front text fields) | ✅ ML Kit | ✅ Vision |
Installation #
Add to your pubspec.yaml:
dependencies:
prism_ekyc: 0.2.0
Android Setup #
1. Maven repository #
Add the libjeid repository to your root android/build.gradle (or build.gradle.kts):
// android/build.gradle.kts
allprojects {
repositories {
google()
mavenCentral()
maven { url = uri("https://cdn.osstech.co.jp/android") }
}
}
2. App-level dependencies #
In android/app/build.gradle.kts:
dependencies {
// libjeid — NFC reading of Japanese IC cards
implementation("jp.co.osstech:libjeid-free:20251031@aar")
// BouncyCastle — required by libjeid for BAC/DES crypto
implementation("org.bouncycastle:bcprov-lts8on:2.73.9")
// ML Kit Japanese text recognition (for OCR of card front)
implementation("com.google.mlkit:text-recognition-japanese:16.0.1")
}
3. Permissions #
In android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
Set launchMode="singleTop" on your MainActivity:
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
...>
4. ProGuard rules #
In android/app/proguard-rules.pro:
-keep class org.bouncycastle.** { *; }
-dontwarn org.bouncycastle.**
-keep class jp.co.osstech.libjeid.** { *; }
-dontwarn jp.co.osstech.libjeid.**
iOS Setup #
1. NFC capability #
In Xcode, enable the Near Field Communication Tag Reading capability for your app target.
2. Info.plist #
<!-- ios/Runner/Info.plist -->
<key>NFCReaderUsageDescription</key>
<string>NFC is used to read your IC card for identity verification.</string>
<key>NSCameraUsageDescription</key>
<string>Camera is used to capture your ID card for identity verification.</string>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
3. Entitlements #
Add to Runner.entitlements:
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>
</array>
4. libjeid.xcframework #
libjeid.xcframework is bundled inside the plugin at ios/Frameworks/libjeid.xcframework.
No additional CocoaPod or manual linking is required — the plugin's podspec handles it.
Usage #
import 'package:prism_ekyc/prism_ekyc.dart';
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => PrismEkyc.screen(
PrismEkycConfig(
// debugBypassNfc: true, // skip real NFC scan during development
onComplete: (EkycResult result) {
print('Name: ${result.formData.fullName}');
print('Card #: ${result.formData.cardNumber}');
print('NFC address: ${result.nfcData?.chipAddress}');
print('Face verified: ${result.faceVerified}');
},
),
),
),
);
EkycResult #
| Field | Type | Description |
|---|---|---|
formData |
UserFormData |
User-entered form data |
nfcData |
NfcScanResult? |
Chip-read data (address, images, etc.) |
backsideImage |
Uint8List? |
Card backside JPEG bytes |
faceVerified |
bool |
Whether face matched the ID photo |
faceMatchConfidence |
double? |
0.0–1.0 confidence (null if not run) |
NFC Method Channel Reference #
The plugin exposes com.rubilabs.prism_ekyc/nfc for direct use if needed:
const _nfc = MethodChannel('com.rubilabs.prism_ekyc/nfc');
// Check if NFC is available and enabled
final bool available = await _nfc.invokeMethod('isNfcAvailable');
// Read a Residence Card (blocks until card is physically tapped)
final Map result = await _nfc.invokeMethod('readResidenceCard', {
'cardNumber': 'AA12345678BC', // 12-character number printed on the card front
});
// Returned keys:
// cardFrontImage — "data:image/png;base64,..."
// photo — "data:image/jpeg;base64,..." (Android) or jp2 (iOS)
// address — String
// addressCode — String
// addressDate — String
// comprehensivePermission — String
// individualPermission — String
// updateStatus — String
// rcCardType — "1" (regular) or "2" (special permanent)
// isValid — bool (chip signature validation)
// Cancel an in-progress read (e.g. when the screen is popped)
await _nfc.invokeMethod('stopRead');
eKYC Screen Flow #
Welcome → NationalitySelector → IdInstruction → NfcScan →
BacksideCapture → FaceVerification → RegistrationForm → Completion
- NationalitySelector — determines
isJapanese(Japanese vs non-Japanese resident) - IdInstruction — for Japanese users, selects Driver's License vs My Number Card
- NfcScan — reads the chip; non-Japanese users always scan a Residence Card
- BacksideCapture — camera captures the physical card back → triggers OCR
- FaceVerification — live camera + blink/smile challenge
- RegistrationForm — user fills in remaining details
- Completion — calls
onCompletewith the fullEkycResult
Plugin Architecture #
Android #
| Class | Role |
|---|---|
PrismEkycPlugin |
Flutter plugin entry point; ActivityAware; registers NFC + face channels |
AndroidNfcReader |
NFC via NfcAdapter.enableReaderMode + libjeid-free |
AndroidFaceComparison |
Face similarity via ML Kit Face Detection |
iOS #
| Class | Role |
|---|---|
PrismEkycPlugin |
Flutter plugin entry point; registers NFC + face channels |
NfcReader |
NFC via NFCTagReaderSession + libjeid.xcframework |
FaceComparison |
Face similarity via Apple Vision VNGenerateImageFeaturePrintRequest |
Troubleshooting #
Android: NoClassDefFoundError: org.bouncycastle.*
Add -keep class org.bouncycastle.** { *; } to proguard-rules.pro.
Android: app crashes immediately after "Reading data" in NFC dialog
R8 is stripping libjeid or BouncyCastle classes in release builds.
Add both -keep rules listed above.
iOS: NFC session never starts
- Ensure the NFC capability is enabled in Xcode
- Ensure
NFCReaderUsageDescriptionis inInfo.plist - NFC only works on physical devices (not simulator)
iOS: card not detected / Invalid tag
Hold the card flat against the back/top of the iPhone and do not move either until the session closes.
License #
Proprietary — RubiLabs © 2026