react-native-kalapa-ekyc 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +534 -142
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/build.gradle +10 -8
- package/android/src/main/java/com/reactnativekalapaekyc/KalapaEkycModule.java +72 -60
- package/ios/KalapaEkyc.m +20 -9
- package/ios/KalapaEkyc.xcodeproj/project.xcworkspace/xcuserdata/iosdev.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/KalapaEkyc.xcodeproj/project.xcworkspace/xcuserdata/leo.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/package.json +11 -12
- package/react-native-kalapa-ekyc.podspec +1 -0
- package/src/KalapaResult.ts +326 -0
- package/src/index.tsx +4 -1
- package/lib/typescript/babel.config.d.ts +0 -1
- package/lib/typescript/lib/commonjs/index.d.ts +0 -3
- package/lib/typescript/lib/module/index.d.ts +0 -2
- package/lib/typescript/scripts/bootstrap.d.ts +0 -1
- /package/lib/typescript/{src/index.d.ts → index.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,193 +1,585 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Kalapa eKYC React Native SDK Documentation
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Complete guide for integrating Kalapa eKYC functionality into your React Native applications.
|
|
4
|
+
---
|
|
5
|
+
## Changelog
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
### 1.2.0
|
|
8
|
+
- **Documentation**: Complete overhaul of KalapaResult class documentation
|
|
9
|
+
- **Documentation**: Added comprehensive property documentation for all root-level fields
|
|
10
|
+
- **Documentation**: Added AddressEntities, MrzData, and QrCode object documentation
|
|
11
|
+
- **Documentation**: Enhanced usage examples with all available properties
|
|
12
|
+
- **Documentation**: Fixed package name references throughout documentation
|
|
13
|
+
- **Documentation**: Added examples for accessing MRZ data, QR code data, and address entities
|
|
6
14
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
### 1.1.3
|
|
16
|
+
- **Android**: Removed GIF dependencies to satisfy Google Play requirement (16KB pages size)
|
|
17
|
+
- **Stable version**
|
|
18
|
+
|
|
19
|
+
### 1.1.2
|
|
20
|
+
- **Android**: Removed unnecessary jitpack.io repository
|
|
21
|
+
- **Android**: Updated animation to avoid GIF usage
|
|
22
|
+
|
|
23
|
+
### 1.1.1
|
|
24
|
+
- **Android**: Removed unnecessary jcenter repository
|
|
25
|
+
|
|
26
|
+
### 1.1.0
|
|
27
|
+
- **Android**: Support target SDK version 35 & edge-to-edge display
|
|
28
|
+
- **Android**: Support base64 library
|
|
29
|
+
- **UI & UX**: General optimization improvements
|
|
30
|
+
|
|
31
|
+
### 1.0.7
|
|
32
|
+
- **General**: Applied new flow for both Android & iOS platforms
|
|
33
|
+
- **iOS**: UI & UX optimization
|
|
34
|
+
- **Android**: UI & UX optimization
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Requirements
|
|
39
|
+
|
|
40
|
+
### React Native
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
"react": "17.0.2"
|
|
44
|
+
"react-native": "0.66.3"
|
|
10
45
|
```
|
|
11
46
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
47
|
+
### Android
|
|
48
|
+
|
|
49
|
+
**Minimum SDK Requirements:**
|
|
50
|
+
- `minSdkVersion = 24`
|
|
51
|
+
- `targetSdkVersion = 33`
|
|
52
|
+
- `android.useAndroidX = true`
|
|
53
|
+
- `Kotlin = 1.8.0+`
|
|
54
|
+
|
|
55
|
+
**Compile Options:**
|
|
56
|
+
```xml
|
|
57
|
+
compileOptions {
|
|
58
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
59
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
60
|
+
}
|
|
15
61
|
```
|
|
16
62
|
|
|
17
|
-
|
|
63
|
+
### iOS
|
|
64
|
+
|
|
65
|
+
- iOS Development Target >= 13.4
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Getting Started
|
|
70
|
+
|
|
71
|
+
### Install the SDK
|
|
72
|
+
|
|
73
|
+
#### Using Yarn
|
|
18
74
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
pod 'react-native-kalapa-ekyc', :path => '../node_modules/react-native-kalapa-ekyc'
|
|
75
|
+
```bash
|
|
76
|
+
yarn add react-native-kalapa-ekyc
|
|
22
77
|
```
|
|
23
78
|
|
|
24
|
-
|
|
79
|
+
#### Using npm
|
|
80
|
+
|
|
25
81
|
```bash
|
|
26
|
-
|
|
82
|
+
npm install react-native-kalapa-ekyc
|
|
27
83
|
```
|
|
28
84
|
|
|
29
|
-
|
|
85
|
+
#### Manual Installation
|
|
30
86
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
clientId: 'YOUR_CLIENT_ID',
|
|
37
|
-
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
38
|
-
environment: 'sandbox' // or 'production'
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
// Start eKYC flow
|
|
42
|
-
try {
|
|
43
|
-
const result = await ekyc.startEkyc();
|
|
44
|
-
console.log('eKYC Result:', result);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
console.error('eKYC Error:', error);
|
|
87
|
+
Add to your `app/package.json`:
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
"dependencies": {
|
|
91
|
+
"react-native-kalapa-ekyc": "^1.2.0"
|
|
47
92
|
}
|
|
48
93
|
```
|
|
49
94
|
|
|
50
|
-
|
|
95
|
+
---
|
|
51
96
|
|
|
52
|
-
|
|
97
|
+
## iOS Configuration
|
|
53
98
|
|
|
54
|
-
|
|
55
|
-
import { WebViewScreen } from 'react-native-kalapa-ekyc';
|
|
56
|
-
|
|
57
|
-
// In your navigation/component
|
|
58
|
-
<WebViewScreen
|
|
59
|
-
clientId="YOUR_CLIENT_ID"
|
|
60
|
-
clientSecret="YOUR_CLIENT_SECRET"
|
|
61
|
-
onComplete={(result) => {
|
|
62
|
-
console.log('WebView eKYC completed:', result);
|
|
63
|
-
}}
|
|
64
|
-
onError={(error) => {
|
|
65
|
-
console.error('WebView eKYC error:', error);
|
|
66
|
-
}}
|
|
67
|
-
/>
|
|
68
|
-
```
|
|
99
|
+
### Declare Camera and NFC Permissions
|
|
69
100
|
|
|
70
|
-
|
|
101
|
+
Update your `Info.plist` with the following:
|
|
71
102
|
|
|
72
|
-
|
|
103
|
+
```xml
|
|
104
|
+
<key>NFCReaderUsageDescription</key>
|
|
105
|
+
<string>This eKYC app needs NFC reader to scan chip</string>
|
|
73
106
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
107
|
+
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
|
|
108
|
+
<array>
|
|
109
|
+
<string>A0000002471001</string>
|
|
110
|
+
<string>A0000002472001</string>
|
|
111
|
+
<string>00000000000000</string>
|
|
112
|
+
</array>
|
|
113
|
+
|
|
114
|
+
<key>NSCameraUsageDescription</key>
|
|
115
|
+
<string>This eKYC app needs to use camera to scan document</string>
|
|
83
116
|
```
|
|
84
117
|
|
|
85
|
-
|
|
118
|
+
### Enable NFC Capability
|
|
86
119
|
|
|
87
|
-
|
|
88
|
-
- `getSessionStatus(sessionId: string)`: Get status of an eKYC session
|
|
89
|
-
- `validateSession(sessionId: string)`: Validate an eKYC session
|
|
120
|
+
Add the **Near Field Communication Tag Reading** capability to your project target in Xcode.
|
|
90
121
|
|
|
91
|
-
|
|
122
|
+
[View Xcode capability documentation](https://help.apple.com/xcode/mac/current/#/dev88ff319e7)
|
|
92
123
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Implementation Guide
|
|
127
|
+
|
|
128
|
+
### 1. Initialize a Session
|
|
129
|
+
|
|
130
|
+
Each eKYC profile requires a unique session ID (JWT access token). The SDK uses this session ID to perform all eKYC steps.
|
|
131
|
+
|
|
132
|
+
**Important Notes:**
|
|
133
|
+
- Failure to provide a valid session ID results in an unauthorized error
|
|
134
|
+
- Sessions are valid for 10 minutes by default (adjustable)
|
|
135
|
+
- Each session ID should be used for a single eKYC flow
|
|
136
|
+
|
|
137
|
+
Check the [API documentation](https://www.notion.so/Init-session-820a772b8402499887e3cc983aaab148?pvs=21) for creating a new session.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### 2. Define SDK Configuration
|
|
142
|
+
|
|
143
|
+
#### Basic Configuration Structure
|
|
144
|
+
|
|
145
|
+
```jsx
|
|
146
|
+
let configInfo = {
|
|
147
|
+
domain: <BASE_URL>,
|
|
148
|
+
main_color: <MAIN_COLOR>,
|
|
149
|
+
main_text_color: <MAIN_TEXT_COLOR>,
|
|
150
|
+
btn_text_color: <BTN_TEXT_COLOR>,
|
|
151
|
+
background_color: <BG_COLOR>,
|
|
152
|
+
language: <LANGUAGE>,
|
|
153
|
+
liveness_version: <LIVENESS_VERSION>,
|
|
154
|
+
face_data: <FACE_DATA>,
|
|
155
|
+
mrz: <INPUT_MRZ>,
|
|
156
|
+
qr_code: <INPUT_QR_CODE>,
|
|
157
|
+
allow_mrz_rescan_on_nfc_mismatch: <ALLOW_MRZ_RESCAN_ON_NFC_MISMATCH>
|
|
102
158
|
}
|
|
103
159
|
```
|
|
104
160
|
|
|
105
|
-
|
|
161
|
+
#### Configuration Parameters
|
|
162
|
+
|
|
163
|
+
| Parameter | Type | Description |
|
|
164
|
+
|-----------|------|-------------|
|
|
165
|
+
| `BASE_URL` | String | Base URL for SDK API requests. Example endpoints: `<BASE_URL>/api/kyc/scan-front`, `<BASE_URL>/api/kyc/scan-back` |
|
|
166
|
+
| `BG_COLOR` | String | Hex color code for SDK background |
|
|
167
|
+
| `MAIN_COLOR` | String | Hex color code for buttons and functional texts |
|
|
168
|
+
| `MAIN_TEXT_COLOR` | String | Hex color code for main text elements |
|
|
169
|
+
| `BTN_TEXT_COLOR` | String | Hex color code for text inside filled buttons |
|
|
170
|
+
| `LIVENESS_VERSION` | Integer | Liveness detection version:<br/>• `3` - Requires 3 random actions (turn left/right/up/down, tilt left/right)<br/>• `2` - Move face towards camera<br/>• `1` - No action required |
|
|
171
|
+
| `LANGUAGE` | String | UI language: `"vi"` (Vietnamese) or `"en"` (English) |
|
|
172
|
+
| `FACE_DATA` | String | Base64 face data. If valid, skips liveness step and uses this for comparison with NFC portrait or document portrait |
|
|
173
|
+
| `INPUT_MRZ` | String | Pre-filled MRZ data. If valid, skips MRZ scan step. Invalid input throws `INVALID_MRZ` error |
|
|
174
|
+
| `INPUT_QR_CODE` | String | Pre-filled QR code. If valid, skips QR scan step. Invalid input throws `INVALID_QR` error |
|
|
175
|
+
| `ALLOW_MRZ_RESCAN_ON_NFC_MISMATCH` | Boolean | If `true`, allows user to rescan MRZ when chip data doesn't match input MRZ |
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
### 3. Define the SDK Flow
|
|
180
|
+
|
|
181
|
+
#### Available eKYC Steps
|
|
182
|
+
|
|
183
|
+
1. Scan the document
|
|
184
|
+
2. Scan the face
|
|
185
|
+
3. Scan the NFC chip
|
|
186
|
+
|
|
187
|
+
#### Flow Types
|
|
188
|
+
|
|
189
|
+
| Flow Type | Scan Document | Scan Face | Scan NFC Chip |
|
|
190
|
+
|-----------|---------------|-----------|---------------|
|
|
191
|
+
| `ekyc` | ✓ | ✓ | ✗ |
|
|
192
|
+
| `nfc_ekyc` | ✓ | ✓ | ✓ |
|
|
193
|
+
| `nfc_only` | ✗ | ✓ | ✓ |
|
|
194
|
+
|
|
195
|
+
#### Flow Selection Guidelines
|
|
196
|
+
|
|
197
|
+
The SDK flow typically matches the flow set during session creation. However, there are special use cases:
|
|
198
|
+
|
|
199
|
+
**Example Use Case for `nfc_only`:**
|
|
200
|
+
If users completed the basic `ekyc` flow but failed to scan the NFC chip, you can:
|
|
201
|
+
- Reuse the same session ID
|
|
202
|
+
- Set flow to `nfc_only`
|
|
203
|
+
- Allow NFC chip scanning without re-scanning document and face
|
|
204
|
+
|
|
205
|
+
**Best Practice:** Use separate sessions for different flows to simplify data management.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### 4. Start the SDK
|
|
210
|
+
|
|
211
|
+
```jsx
|
|
212
|
+
import KalapaEkyc, { KalapaResult } from 'react-native-kalapa-ekyc';
|
|
213
|
+
|
|
214
|
+
let sessionId = yourSessionInitFunc();
|
|
215
|
+
let sdkFlow = "<YOUR_SDK_FLOW>"; // ekyc / nfc_ekyc / nfc_only
|
|
216
|
+
let configInfo = {...};
|
|
217
|
+
|
|
218
|
+
KalapaEkyc.start(sessionId, sdkFlow, configInfo)
|
|
219
|
+
.then((rawResult) => {
|
|
220
|
+
try {
|
|
221
|
+
// You can use either the constructor or static method
|
|
222
|
+
const result = KalapaResult.fromRawResult(rawResult);
|
|
223
|
+
// Or: const result = new KalapaResult(rawResult);
|
|
224
|
+
handleSuccessfulResult(result);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error("Result parsing error:", error);
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
.catch((error) => {
|
|
230
|
+
switch (error.code) {
|
|
231
|
+
case "EXPIRED":
|
|
232
|
+
console.warn("Session expired:", error.message);
|
|
233
|
+
break;
|
|
234
|
+
case "CANCELED":
|
|
235
|
+
console.warn("User canceled:", error.message);
|
|
236
|
+
break;
|
|
237
|
+
case "PERMISSION_DENIED":
|
|
238
|
+
console.error("Permission denied:", error.message);
|
|
239
|
+
break;
|
|
240
|
+
case "DEVICE_NOT_ACCEPTABLE":
|
|
241
|
+
console.error("Device not acceptable:", error.message);
|
|
242
|
+
break;
|
|
243
|
+
case "MRZ_INVALID":
|
|
244
|
+
console.error("Invalid MRZ:", error.message);
|
|
245
|
+
break;
|
|
246
|
+
case "NFC_NOT_MATCH":
|
|
247
|
+
console.error("NFC mismatch:", error.message);
|
|
248
|
+
break;
|
|
249
|
+
case "UNSUPPORTED":
|
|
250
|
+
console.error("Unsupported device:", error.message);
|
|
251
|
+
break;
|
|
252
|
+
case "CONFIG_ERROR":
|
|
253
|
+
console.error("Configuration error:", error.message);
|
|
254
|
+
break;
|
|
255
|
+
case "OTHER":
|
|
256
|
+
default:
|
|
257
|
+
console.error("Unknown error:", error.message);
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Exception Handling
|
|
266
|
+
|
|
267
|
+
### Error Codes
|
|
268
|
+
|
|
269
|
+
| Error Code | Description |
|
|
270
|
+
|------------|-------------|
|
|
271
|
+
| `EXPIRED` | Session expired (10 minutes timeout) |
|
|
272
|
+
| `CANCELED` | User canceled the eKYC process |
|
|
273
|
+
| `PERMISSION_DENIED` | Camera or NFC permission denied |
|
|
274
|
+
| `DEVICE_NOT_ACCEPTABLE` | Emulator, rooted, or jailbroken device detected |
|
|
275
|
+
| `MRZ_INVALID` | Input MRZ is invalid |
|
|
276
|
+
| `NFC_NOT_MATCH` | MRZ doesn't match NFC chip data |
|
|
277
|
+
| `UNSUPPORTED` | Device doesn't support required features (usually NFC) |
|
|
278
|
+
| `CONFIG_ERROR` | Configuration error |
|
|
279
|
+
| `OTHER` | Unexpected error |
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Result Objects
|
|
284
|
+
|
|
285
|
+
### KalapaResult Class
|
|
286
|
+
|
|
287
|
+
The SDK provides a `KalapaResult` class for type-safe data access:
|
|
106
288
|
|
|
107
289
|
```typescript
|
|
108
|
-
|
|
109
|
-
sessionId: string;
|
|
110
|
-
status: 'completed' | 'pending' | 'failed';
|
|
111
|
-
data?: {
|
|
112
|
-
idCard?: IdCardData;
|
|
113
|
-
face?: FaceData;
|
|
114
|
-
verification?: VerificationResult;
|
|
115
|
-
};
|
|
116
|
-
}
|
|
290
|
+
import { KalapaResult } from 'react-native-kalapa-ekyc';
|
|
117
291
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// ... other ID card fields
|
|
124
|
-
}
|
|
292
|
+
// Create instance using static method (recommended)
|
|
293
|
+
const result = KalapaResult.fromRawResult(rawResult);
|
|
294
|
+
|
|
295
|
+
// Or use constructor directly
|
|
296
|
+
const result = new KalapaResult(rawResult);
|
|
125
297
|
```
|
|
126
298
|
|
|
127
|
-
|
|
299
|
+
#### Core Properties
|
|
300
|
+
|
|
301
|
+
| Property | Type | Description |
|
|
302
|
+
|----------|------|-------------|
|
|
303
|
+
| `decision` | DecisionType | Decision result: `"APPROVED"`, `"MANUAL"`, `"REJECTED"`, or `"UNKNOWN"` |
|
|
304
|
+
| `selfie_data` | SelfieData | Face matching results |
|
|
305
|
+
| `nfc_data` | NfcData | NFC chip data |
|
|
306
|
+
| `session` | string | Session JWT token |
|
|
307
|
+
| `rawResult` | any | Original unprocessed response |
|
|
308
|
+
|
|
309
|
+
#### Root-Level Personal Information
|
|
128
310
|
|
|
129
|
-
|
|
311
|
+
| Property | Type | Description |
|
|
312
|
+
|----------|------|-------------|
|
|
313
|
+
| `name` | string | Full name from the verification result |
|
|
314
|
+
| `id_number` | string | ID card number |
|
|
315
|
+
| `birthday` | string | Birth date |
|
|
316
|
+
| `gender` | string | Gender information |
|
|
317
|
+
| `country` | string | Country information |
|
|
318
|
+
| `national` | string | Nationality |
|
|
319
|
+
| `ethnicity` | string | Ethnicity information |
|
|
320
|
+
| `religion` | string | Religious information |
|
|
321
|
+
| `features` | string | Personal identification marks or features |
|
|
322
|
+
| `poi` | string | Place of issue |
|
|
323
|
+
|
|
324
|
+
#### Date Information
|
|
325
|
+
|
|
326
|
+
| Property | Type | Description |
|
|
327
|
+
|----------|------|-------------|
|
|
328
|
+
| `doe` | string | Date of expiry |
|
|
329
|
+
| `doi` | string | Date of issuance |
|
|
330
|
+
|
|
331
|
+
#### Address Information
|
|
332
|
+
|
|
333
|
+
| Property | Type | Description |
|
|
334
|
+
|----------|------|-------------|
|
|
335
|
+
| `home` | string | Home address (full text) |
|
|
336
|
+
| `home_entities` | AddressEntities | Parsed home address entities (district, ward, province, unknown) |
|
|
337
|
+
| `resident` | string | Residential address (full text) |
|
|
338
|
+
| `resident_entities` | AddressEntities | Parsed residential address entities (district, ward, province, unknown) |
|
|
339
|
+
|
|
340
|
+
#### Document Data
|
|
341
|
+
|
|
342
|
+
| Property | Type | Description |
|
|
343
|
+
|----------|------|-------------|
|
|
344
|
+
| `mrz_data` | MrzData \| null | Machine Readable Zone data with parsed fields |
|
|
345
|
+
| `qr_code` | QrCode \| null | QR code data from document |
|
|
346
|
+
| `type` | string | Document type |
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
### SelfieData Object
|
|
351
|
+
|
|
352
|
+
#### Properties
|
|
353
|
+
|
|
354
|
+
| Property | Type | Description |
|
|
355
|
+
|----------|------|-------------|
|
|
356
|
+
| `is_matched` | boolean | Face matching result |
|
|
357
|
+
| `matching_score` | number | Matching confidence score (0-100) |
|
|
358
|
+
|
|
359
|
+
#### Usage Example
|
|
130
360
|
|
|
131
361
|
```typescript
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
} catch (error) {
|
|
135
|
-
if (error instanceof KalapaEkycError) {
|
|
136
|
-
// Handle SDK-specific errors
|
|
137
|
-
console.error(error.code, error.message);
|
|
138
|
-
} else {
|
|
139
|
-
// Handle other errors
|
|
140
|
-
console.error(error);
|
|
141
|
-
}
|
|
362
|
+
if (result.selfie_data.is_matched) {
|
|
363
|
+
console.log(`Face matched with ${result.selfie_data.matching_score}% confidence`);
|
|
142
364
|
}
|
|
143
365
|
```
|
|
144
366
|
|
|
145
|
-
|
|
367
|
+
---
|
|
146
368
|
|
|
147
|
-
|
|
148
|
-
|--------|------|-------------|---------|
|
|
149
|
-
| clientId | string | Your Kalapa client ID | Required |
|
|
150
|
-
| clientSecret | string | Your Kalapa client secret | Required |
|
|
151
|
-
| environment | string | 'sandbox' or 'production' | 'sandbox' |
|
|
152
|
-
| timeout | number | Request timeout in ms | 30000 |
|
|
153
|
-
| language | string | 'en' or 'vi' | 'en' |
|
|
369
|
+
### NfcData Object
|
|
154
370
|
|
|
155
|
-
|
|
371
|
+
#### Personal Information
|
|
156
372
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
373
|
+
| Property | Type | Description |
|
|
374
|
+
|----------|------|-------------|
|
|
375
|
+
| `name` | string | Full name from NFC chip |
|
|
376
|
+
| `id_number` | string | ID card number |
|
|
377
|
+
| `old_id_number` | string | Previous ID number (if any) |
|
|
378
|
+
| `date_of_birth` | string | Birth date in DD/MM/YYYY format |
|
|
379
|
+
| `date_of_expiry` | string | ID expiry date in DD/MM/YYYY format |
|
|
380
|
+
| `date_of_issuance` | string | ID issuance date in DD/MM/YYYY format |
|
|
381
|
+
| `gender` | string | Gender information |
|
|
382
|
+
| `nationality` | string | Nationality |
|
|
383
|
+
| `nation` | string | Nation/ethnicity information |
|
|
166
384
|
|
|
167
|
-
|
|
385
|
+
#### Address Information
|
|
168
386
|
|
|
169
|
-
|
|
387
|
+
| Property | Type | Description |
|
|
388
|
+
|----------|------|-------------|
|
|
389
|
+
| `address` | string | Current residential address |
|
|
390
|
+
| `hometown` | string | Hometown/place of origin |
|
|
170
391
|
|
|
171
|
-
|
|
392
|
+
#### Family Information
|
|
172
393
|
|
|
173
|
-
|
|
394
|
+
| Property | Type | Description |
|
|
395
|
+
|----------|------|-------------|
|
|
396
|
+
| `father_name` | string | Father's full name |
|
|
397
|
+
| `mother_name` | string | Mother's full name |
|
|
398
|
+
| `spouse_name` | string | Spouse's full name |
|
|
174
399
|
|
|
175
|
-
|
|
400
|
+
#### Additional Information
|
|
176
401
|
|
|
177
|
-
|
|
402
|
+
| Property | Type | Description |
|
|
403
|
+
|----------|------|-------------|
|
|
404
|
+
| `religion` | string | Religious information |
|
|
405
|
+
| `personal_identification` | string | Personal identification marks or features |
|
|
178
406
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
407
|
+
#### Technical Data
|
|
408
|
+
|
|
409
|
+
| Property | Type | Description |
|
|
410
|
+
|----------|------|-------------|
|
|
411
|
+
| `face_image` | string | Base64 encoded face image from NFC chip |
|
|
412
|
+
| `mrz` | string | Machine Readable Zone data (raw string) |
|
|
413
|
+
|
|
414
|
+
---
|
|
415
|
+
|
|
416
|
+
### AddressEntities Object
|
|
417
|
+
|
|
418
|
+
Represents parsed address components:
|
|
419
|
+
|
|
420
|
+
| Property | Type | Description |
|
|
421
|
+
|----------|------|-------------|
|
|
422
|
+
| `district` | string | District name |
|
|
423
|
+
| `ward` | string | Ward name |
|
|
424
|
+
| `province` | string | Province name |
|
|
425
|
+
| `unknown` | string | Unparsed address components |
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
### MrzData Object
|
|
430
|
+
|
|
431
|
+
Contains MRZ (Machine Readable Zone) information:
|
|
432
|
+
|
|
433
|
+
| Property | Type | Description |
|
|
434
|
+
|----------|------|-------------|
|
|
435
|
+
| `data` | MrzDataFields \| undefined | Parsed MRZ fields |
|
|
436
|
+
| `error` | MrzDataError \| undefined | Error information if parsing failed |
|
|
437
|
+
|
|
438
|
+
#### MrzDataFields
|
|
439
|
+
|
|
440
|
+
| Property | Type | Description |
|
|
441
|
+
|----------|------|-------------|
|
|
442
|
+
| `birthday` | string \| undefined | Birth date from MRZ |
|
|
443
|
+
| `doe` | string \| undefined | Date of expiry from MRZ |
|
|
444
|
+
| `gender` | string \| undefined | Gender from MRZ |
|
|
445
|
+
| `id_number` | string \| undefined | ID number from MRZ |
|
|
446
|
+
| `name` | string \| undefined | Name from MRZ |
|
|
447
|
+
| `raw_mrz` | string \| undefined | Raw MRZ string |
|
|
448
|
+
|
|
449
|
+
#### MrzDataError
|
|
450
|
+
|
|
451
|
+
| Property | Type | Description |
|
|
452
|
+
|----------|------|-------------|
|
|
453
|
+
| `code` | number | Error code |
|
|
454
|
+
| `message` | string | Error message |
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
### QrCode Object
|
|
459
|
+
|
|
460
|
+
Contains QR code information:
|
|
461
|
+
|
|
462
|
+
| Property | Type | Description |
|
|
463
|
+
|----------|------|-------------|
|
|
464
|
+
| `data` | QrCodeData \| undefined | Decoded QR code data |
|
|
465
|
+
| `error` | { code: number, message: string } \| undefined | Error information if decoding failed |
|
|
466
|
+
|
|
467
|
+
#### QrCodeData
|
|
468
|
+
|
|
469
|
+
| Property | Type | Description |
|
|
470
|
+
|----------|------|-------------|
|
|
471
|
+
| `decoded_text` | string \| undefined | Decoded QR code text |
|
|
472
|
+
| `stage` | number \| undefined | Processing stage |
|
|
473
|
+
|
|
474
|
+
---
|
|
475
|
+
|
|
476
|
+
## Convenience Methods
|
|
477
|
+
|
|
478
|
+
### Decision Methods
|
|
479
|
+
|
|
480
|
+
| Method | Returns | Description |
|
|
481
|
+
|--------|---------|-------------|
|
|
482
|
+
| `isApproved()` | boolean | Returns `true` if decision is `"APPROVED"` |
|
|
483
|
+
| `isManualReview()` | boolean | Returns `true` if decision is `"MANUAL"` |
|
|
484
|
+
| `isRejected()` | boolean | Returns `true` if decision is `"REJECTED"` |
|
|
485
|
+
|
|
486
|
+
### Face Matching Methods
|
|
487
|
+
|
|
488
|
+
| Method | Returns | Description |
|
|
489
|
+
|--------|---------|-------------|
|
|
490
|
+
| `isFaceMatched()` | boolean | Returns `true` if face matched successfully |
|
|
491
|
+
| `getFaceMatchingScore()` | number | Returns face matching confidence score |
|
|
492
|
+
|
|
493
|
+
### Formatted Getters
|
|
494
|
+
|
|
495
|
+
| Method | Returns | Description |
|
|
496
|
+
|--------|---------|-------------|
|
|
497
|
+
| `getDisplayName()` | string | Returns formatted name or `"N/A"` if empty |
|
|
498
|
+
| `getIdNumber()` | string | Returns formatted ID number or `"N/A"` if empty |
|
|
499
|
+
| `getDateOfBirth()` | string | Returns formatted birth date or `"N/A"` if empty |
|
|
500
|
+
| `getFaceImage()` | string | Returns base64 face image from NFC chip |
|
|
501
|
+
|
|
502
|
+
### Utility Methods
|
|
503
|
+
|
|
504
|
+
| Method | Returns | Description |
|
|
505
|
+
|--------|---------|-------------|
|
|
506
|
+
| `toJSON()` | object | Returns clean object for storage/transmission |
|
|
507
|
+
| `fromRawResult(rawResult)` | KalapaResult | Static method to create KalapaResult from raw response |
|
|
508
|
+
|
|
509
|
+
---
|
|
510
|
+
|
|
511
|
+
## Complete Usage Example
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
import KalapaEkyc, { KalapaResult } from 'react-native-kalapa-ekyc';
|
|
515
|
+
|
|
516
|
+
const handleEkyc = async () => {
|
|
517
|
+
try {
|
|
518
|
+
const rawResult = await KalapaEkyc.start(sessionId, "nfc_only", configInfo);
|
|
519
|
+
const result = KalapaResult.fromRawResult(rawResult);
|
|
520
|
+
|
|
521
|
+
// Check decision
|
|
522
|
+
if (result.isApproved()) {
|
|
523
|
+
console.log("eKYC Approved");
|
|
524
|
+
} else if (result.isManualReview()) {
|
|
525
|
+
console.log("Manual review required");
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// Check face matching
|
|
529
|
+
if (result.isFaceMatched()) {
|
|
530
|
+
console.log(`Face matched: ${result.getFaceMatchingScore()}%`);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Access root-level data
|
|
534
|
+
console.log(`Name: ${result.name}`);
|
|
535
|
+
console.log(`ID Number: ${result.id_number}`);
|
|
536
|
+
console.log(`Birthday: ${result.birthday}`);
|
|
537
|
+
|
|
538
|
+
// Access NFC data
|
|
539
|
+
const userData = {
|
|
540
|
+
name: result.nfc_data.name,
|
|
541
|
+
idNumber: result.nfc_data.id_number,
|
|
542
|
+
birthDate: result.nfc_data.date_of_birth,
|
|
543
|
+
faceImage: result.nfc_data.face_image
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
// Access address entities
|
|
547
|
+
if (result.home_entities) {
|
|
548
|
+
console.log(`Home: ${result.home_entities.province}, ${result.home_entities.district}`);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
// Access MRZ data if available
|
|
552
|
+
if (result.mrz_data?.data) {
|
|
553
|
+
console.log(`MRZ Name: ${result.mrz_data.data.name}`);
|
|
554
|
+
console.log(`Raw MRZ: ${result.mrz_data.data.raw_mrz}`);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
// Access QR code data if available
|
|
558
|
+
if (result.qr_code?.data) {
|
|
559
|
+
console.log(`QR Code: ${result.qr_code.data.decoded_text}`);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// Export to JSON for storage/transmission
|
|
563
|
+
const jsonData = result.toJSON();
|
|
564
|
+
await saveUserData(jsonData);
|
|
565
|
+
|
|
566
|
+
} catch (error) {
|
|
567
|
+
handleEkycError(error);
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
---
|
|
573
|
+
|
|
574
|
+
## Summary
|
|
575
|
+
|
|
576
|
+
The Kalapa eKYC React Native SDK provides comprehensive identity verification with document scanning, face matching, and NFC chip reading capabilities. Key features include:
|
|
577
|
+
|
|
578
|
+
- Three flexible flow types for different verification needs
|
|
579
|
+
- Customizable UI with color and language options
|
|
580
|
+
- Multiple liveness detection versions
|
|
581
|
+
- Type-safe result objects with convenience methods
|
|
582
|
+
- Robust error handling with detailed error codes
|
|
583
|
+
- Support for pre-filled data to skip certain steps
|
|
584
|
+
|
|
585
|
+
For API documentation and session creation, refer to the [Kalapa API documentation](https://kalapa-no.notion.site/eKYC-API-SDK-document-2a2a4ccfa1184a789cb4513fade351e4?pvs=74)
|