react-native-kalapa-ekyc
v1.2.9
Published
React Native SDK for Kalapa eKYC integration
Readme
Kalapa eKYC React Native SDK Documentation
Complete guide for integrating Kalapa eKYC functionality into your React Native applications.
Changelog
1.2.9
- React-Native: Add
customer_languageinto config. - Android: Fix obfuscation error
1.2.8
- Android: Update stable version for NFC step.
1.2.7
- Android: Update config to scan QR code or not.
- React-Native: Introduce config require_qr in AppConfig
1.2.6
- Android: Minor update, UI / UX optimize. Stable version
1.2.5
- Android: Fix NFC step error UNKNOWN rarely happens on some device like Samsung Note 10
1.2.4
- Android: Optimize UI / UX in NFC step
- React-Native: show to skip / show confirm screen.
1.2.3
- Android: Optimize UI / UX in NFC step
1.2.2
- iOS: Maintain UI config
- Android: Maintain / Optimize NFC step
1.2.1
- successColor / failureColor: Now can be configured via sdkConfig
1.2.0
- Documentation: Complete overhaul of KalapaResult class documentation
- Documentation: Added comprehensive property documentation for all root-level fields
- Documentation: Added AddressEntities, MrzData, and QrCode object documentation
- Documentation: Enhanced usage examples with all available properties
- Documentation: Fixed package name references throughout documentation
- Documentation: Added examples for accessing MRZ data, QR code data, and address entities
1.1.3
- Android: Removed GIF dependencies to satisfy Google Play requirement (16KB pages size)
- Stable version
1.1.2
- Android: Removed unnecessary jitpack.io repository
- Android: Updated animation to avoid GIF usage
1.1.1
- Android: Removed unnecessary jcenter repository
1.1.0
- Android: Support target SDK version 35 & edge-to-edge display
- Android: Support base64 library
- UI & UX: General optimization improvements
1.0.7
- General: Applied new flow for both Android & iOS platforms
- iOS: UI & UX optimization
- Android: UI & UX optimization
Requirements
React Native
"react": "17.0.2"
"react-native": "0.66.3"Android
Minimum SDK Requirements:
minSdkVersion = 24targetSdkVersion = 33android.useAndroidX = trueKotlin = 1.8.0+
Compile Options:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}iOS
- iOS Development Target >= 13.4
Getting Started
Install the SDK
Using Yarn
yarn add react-native-kalapa-ekycUsing npm
npm install react-native-kalapa-ekycManual Installation
Add to your app/package.json:
"dependencies": {
"react-native-kalapa-ekyc": "^1.2.9"
}iOS Configuration
Declare Camera and NFC Permissions
Update your Info.plist with the following:
<key>NFCReaderUsageDescription</key>
<string>This eKYC app needs NFC reader to scan chip</string>
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A0000002471001</string>
<string>A0000002472001</string>
<string>00000000000000</string>
</array>
<key>NSCameraUsageDescription</key>
<string>This eKYC app needs to use camera to scan document</string>Enable NFC Capability
Add the Near Field Communication Tag Reading capability to your project target in Xcode.
View Xcode capability documentation
Implementation Guide
1. Initialize a Session
Each eKYC profile requires a unique session ID (JWT access token). The SDK uses this session ID to perform all eKYC steps.
Important Notes:
- Failure to provide a valid session ID results in an unauthorized error
- Sessions are valid for 10 minutes by default (adjustable)
- Each session ID should be used for a single eKYC flow
Check the API documentation for creating a new session.
2. Define SDK Configuration
Basic Configuration Structure
let configInfo = {
domain: <BASE_URL>,
main_color: <MAIN_COLOR>,
main_text_color: <MAIN_TEXT_COLOR>,
btn_text_color: <BTN_TEXT_COLOR>,
background_color: <BG_COLOR>,
success_color: <SUCCESS_COLOR>,
failure_color: <FAILURE_COLOR>,
language: <LANGUAGE>,
liveness_version: <LIVENESS_VERSION>,
face_data: <FACE_DATA>,
mrz: <INPUT_MRZ>,
qr_code: <INPUT_QR_CODE>,
allow_mrz_rescan_on_nfc_mismatch: <ALLOW_MRZ_RESCAN_ON_NFC_MISMATCH>,
with_confirm_screen: <WITH_CONFIRM_SCREEN>,
require_qr: <REQUIRE_QR>,
customer_language: <CUSTOMER_LANGUAGE>
}Configuration Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| BASE_URL | String | Base URL for SDK API requests. Example endpoints: <BASE_URL>/api/kyc/scan-front, <BASE_URL>/api/kyc/scan-back |
| BG_COLOR | String | Hex color code for SDK background |
| MAIN_COLOR | String | Hex color code for buttons and functional texts |
| MAIN_TEXT_COLOR | String | Hex color code for main text elements |
| BTN_TEXT_COLOR | String | Hex color code for text inside filled buttons |
| SUCCESS_COLOR | String | Hex color code for text and view that indicated for success state |
| FAILURE_COLOR | String | Hex color code for text and view that indicated for failure state |
| LIVENESS_VERSION | Integer | Liveness detection version:• 3 - Requires 3 random actions (turn left/right/up/down, tilt left/right)• 2 - Move face towards camera• 1 - No action required |
| LANGUAGE | String | UI language: "vi" (Vietnamese) or "en" (English) |
| FACE_DATA | String | Base64 face data. If valid, skips liveness step and uses this for comparison with NFC portrait or document portrait |
| INPUT_MRZ | String | Pre-filled MRZ data. If valid, skips MRZ scan step. Invalid input throws INVALID_MRZ error |
| INPUT_QR_CODE | String | Pre-filled QR code. If valid, skips QR scan step. Invalid input throws INVALID_QR error |
| ALLOW_MRZ_RESCAN_ON_NFC_MISMATCH | Boolean | If true, allows user to rescan MRZ when chip data doesn't match input MRZ |
| WITH_CONFIRM_SCREEN | Boolean | If true, allows user to enter confirm step |
| REQUIRE_QR | Boolean | If true, SDK will scan for QR Code and may reduce the MRZ step when enter the NFC step. |
| CUSTOMER_LANGUAGE | String | Default "", If you want to custom your own language, contact Kalapa in order to use this feature. |
3. Define the SDK Flow
Available eKYC Steps
- Scan the document
- Scan the face
- Scan the NFC chip
Flow Types
| Flow Type | Scan Document | Scan Face | Scan NFC Chip |
|-----------|---------------|-----------|---------------|
| ekyc | ✓ | ✓ | ✗ |
| nfc_ekyc | ✓ | ✓ | ✓ |
| nfc_only | ✗ | ✓ | ✓ |
Flow Selection Guidelines
The SDK flow typically matches the flow set during session creation. However, there are special use cases:
Example Use Case for nfc_only:
If users completed the basic ekyc flow but failed to scan the NFC chip, you can:
- Reuse the same session ID
- Set flow to
nfc_only - Allow NFC chip scanning without re-scanning document and face
Best Practice: Use separate sessions for different flows to simplify data management.
4. Start the SDK
import KalapaEkyc, { KalapaResult } from 'react-native-kalapa-ekyc';
let sessionId = yourSessionInitFunc();
let sdkFlow = "<YOUR_SDK_FLOW>"; // ekyc / nfc_ekyc / nfc_only
let configInfo = {...};
KalapaEkyc.start(sessionId, sdkFlow, configInfo)
.then((rawResult) => {
try {
// You can use either the constructor or static method
const result = KalapaResult.fromRawResult(rawResult);
// Or: const result = new KalapaResult(rawResult);
handleSuccessfulResult(result);
} catch (error) {
console.error("Result parsing error:", error);
}
})
.catch((error) => {
switch (error.code) {
case "EXPIRED":
console.warn("Session expired:", error.message);
break;
case "CANCELED":
console.warn("User canceled:", error.message);
break;
case "PERMISSION_DENIED":
console.error("Permission denied:", error.message);
break;
case "DEVICE_NOT_ACCEPTABLE":
console.error("Device not acceptable:", error.message);
break;
case "MRZ_INVALID":
console.error("Invalid MRZ:", error.message);
break;
case "NFC_NOT_MATCH":
console.error("NFC mismatch:", error.message);
break;
case "UNSUPPORTED":
console.error("Unsupported device:", error.message);
break;
case "CONFIG_ERROR":
console.error("Configuration error:", error.message);
break;
case "OTHER":
default:
console.error("Unknown error:", error.message);
break;
}
});Exception Handling
Error Codes
| Error Code | Description |
|------------|-------------|
| EXPIRED | Session expired (10 minutes timeout) |
| CANCELED | User canceled the eKYC process |
| PERMISSION_DENIED | Camera or NFC permission denied |
| DEVICE_NOT_ACCEPTABLE | Emulator, rooted, or jailbroken device detected |
| MRZ_INVALID | Input MRZ is invalid |
| NFC_NOT_MATCH | MRZ doesn't match NFC chip data |
| UNSUPPORTED | Device doesn't support required features (usually NFC) |
| CONFIG_ERROR | Configuration error |
| OTHER | Unexpected error |
Result Objects
KalapaResult Class
The SDK provides a KalapaResult class for type-safe data access:
import { KalapaResult } from 'react-native-kalapa-ekyc';
// Create instance using static method (recommended)
const result = KalapaResult.fromRawResult(rawResult);
// Or use constructor directly
const result = new KalapaResult(rawResult);Core Properties
| Property | Type | Description |
|----------|------|-------------|
| decision | DecisionType | Decision result: "APPROVED", "MANUAL", "REJECTED", or "UNKNOWN" |
| selfie_data | SelfieData | Face matching results |
| nfc_data | NfcData | NFC chip data |
| session | string | Session JWT token |
| rawResult | any | Original unprocessed response |
Root-Level Personal Information
| Property | Type | Description |
|----------|------|-------------|
| name | string | Full name from the verification result |
| id_number | string | ID card number |
| birthday | string | Birth date |
| gender | string | Gender information |
| country | string | Country information |
| national | string | Nationality |
| ethnicity | string | Ethnicity information |
| religion | string | Religious information |
| features | string | Personal identification marks or features |
| poi | string | Place of issue |
Date Information
| Property | Type | Description |
|----------|------|-------------|
| doe | string | Date of expiry |
| doi | string | Date of issuance |
Address Information
| Property | Type | Description |
|----------|------|-------------|
| home | string | Home address (full text) |
| home_entities | AddressEntities | Parsed home address entities (district, ward, province, unknown) |
| resident | string | Residential address (full text) |
| resident_entities | AddressEntities | Parsed residential address entities (district, ward, province, unknown) |
Document Data
| Property | Type | Description |
|----------|------|-------------|
| mrz_data | MrzData | null | Machine Readable Zone data with parsed fields |
| qr_code | QrCode | null | QR code data from document |
| type | string | Document type |
SelfieData Object
Properties
| Property | Type | Description |
|----------|------|-------------|
| is_matched | boolean | Face matching result |
| matching_score | number | Matching confidence score (0-100) |
Usage Example
if (result.selfie_data.is_matched) {
console.log(`Face matched with ${result.selfie_data.matching_score}% confidence`);
}NfcData Object
Personal Information
| Property | Type | Description |
|----------|------|-------------|
| name | string | Full name from NFC chip |
| id_number | string | ID card number |
| old_id_number | string | Previous ID number (if any) |
| date_of_birth | string | Birth date in DD/MM/YYYY format |
| date_of_expiry | string | ID expiry date in DD/MM/YYYY format |
| date_of_issuance | string | ID issuance date in DD/MM/YYYY format |
| gender | string | Gender information |
| nationality | string | Nationality |
| nation | string | Nation/ethnicity information |
Address Information
| Property | Type | Description |
|----------|------|-------------|
| address | string | Current residential address |
| hometown | string | Hometown/place of origin |
Family Information
| Property | Type | Description |
|----------|------|-------------|
| father_name | string | Father's full name |
| mother_name | string | Mother's full name |
| spouse_name | string | Spouse's full name |
Additional Information
| Property | Type | Description |
|----------|------|-------------|
| religion | string | Religious information |
| personal_identification | string | Personal identification marks or features |
Technical Data
| Property | Type | Description |
|----------|------|-------------|
| face_image | string | Base64 encoded face image from NFC chip |
| mrz | string | Machine Readable Zone data (raw string) |
AddressEntities Object
Represents parsed address components:
| Property | Type | Description |
|----------|------|-------------|
| district | string | District name |
| ward | string | Ward name |
| province | string | Province name |
| unknown | string | Unparsed address components |
MrzData Object
Contains MRZ (Machine Readable Zone) information:
| Property | Type | Description |
|----------|------|-------------|
| data | MrzDataFields | undefined | Parsed MRZ fields |
| error | MrzDataError | undefined | Error information if parsing failed |
MrzDataFields
| Property | Type | Description |
|----------|------|-------------|
| birthday | string | undefined | Birth date from MRZ |
| doe | string | undefined | Date of expiry from MRZ |
| gender | string | undefined | Gender from MRZ |
| id_number | string | undefined | ID number from MRZ |
| name | string | undefined | Name from MRZ |
| raw_mrz | string | undefined | Raw MRZ string |
MrzDataError
| Property | Type | Description |
|----------|------|-------------|
| code | number | Error code |
| message | string | Error message |
QrCode Object
Contains QR code information:
| Property | Type | Description |
|----------|------|-------------|
| data | QrCodeData | undefined | Decoded QR code data |
| error | { code: number, message: string } | undefined | Error information if decoding failed |
QrCodeData
| Property | Type | Description |
|----------|------|-------------|
| decoded_text | string | undefined | Decoded QR code text |
| stage | number | undefined | Processing stage |
Convenience Methods
Decision Methods
| Method | Returns | Description |
|--------|---------|-------------|
| isApproved() | boolean | Returns true if decision is "APPROVED" |
| isManualReview() | boolean | Returns true if decision is "MANUAL" |
| isRejected() | boolean | Returns true if decision is "REJECTED" |
Face Matching Methods
| Method | Returns | Description |
|--------|---------|-------------|
| isFaceMatched() | boolean | Returns true if face matched successfully |
| getFaceMatchingScore() | number | Returns face matching confidence score |
Formatted Getters
| Method | Returns | Description |
|--------|---------|-------------|
| getDisplayName() | string | Returns formatted name or "N/A" if empty |
| getIdNumber() | string | Returns formatted ID number or "N/A" if empty |
| getDateOfBirth() | string | Returns formatted birth date or "N/A" if empty |
| getFaceImage() | string | Returns base64 face image from NFC chip |
Utility Methods
| Method | Returns | Description |
|--------|---------|-------------|
| toJSON() | object | Returns clean object for storage/transmission |
| fromRawResult(rawResult) | KalapaResult | Static method to create KalapaResult from raw response |
Complete Usage Example
import KalapaEkyc, { KalapaResult } from 'react-native-kalapa-ekyc';
const handleEkyc = async () => {
try {
const rawResult = await KalapaEkyc.start(sessionId, "nfc_only", configInfo);
const result = KalapaResult.fromRawResult(rawResult);
// Check decision
if (result.isApproved()) {
console.log("eKYC Approved");
} else if (result.isManualReview()) {
console.log("Manual review required");
}
// Check face matching
if (result.isFaceMatched()) {
console.log(`Face matched: ${result.getFaceMatchingScore()}%`);
}
// Access root-level data
console.log(`Name: ${result.name}`);
console.log(`ID Number: ${result.id_number}`);
console.log(`Birthday: ${result.birthday}`);
// Access NFC data
const userData = {
name: result.nfc_data.name,
idNumber: result.nfc_data.id_number,
birthDate: result.nfc_data.date_of_birth,
faceImage: result.nfc_data.face_image
};
// Access address entities
if (result.home_entities) {
console.log(`Home: ${result.home_entities.province}, ${result.home_entities.district}`);
}
// Access MRZ data if available
if (result.mrz_data?.data) {
console.log(`MRZ Name: ${result.mrz_data.data.name}`);
console.log(`Raw MRZ: ${result.mrz_data.data.raw_mrz}`);
}
// Access QR code data if available
if (result.qr_code?.data) {
console.log(`QR Code: ${result.qr_code.data.decoded_text}`);
}
// Export to JSON for storage/transmission
const jsonData = result.toJSON();
await saveUserData(jsonData);
} catch (error) {
handleEkycError(error);
}
};Summary
The Kalapa eKYC React Native SDK provides comprehensive identity verification with document scanning, face matching, and NFC chip reading capabilities. Key features include:
- Three flexible flow types for different verification needs
- Customizable UI with color and language options
- Multiple liveness detection versions
- Type-safe result objects with convenience methods
- Robust error handling with detailed error codes
- Support for pre-filled data to skip certain steps
For API documentation and session creation, refer to the Kalapa API documentation
