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.
File without changes
@@ -6,9 +6,8 @@ buildscript {
6
6
  }
7
7
 
8
8
  dependencies {
9
- classpath "com.android.tools.build:gradle:8.7.2"
10
- // noinspection DifferentKotlinGradleVersion
11
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0}"
9
+ classpath("com.android.tools.build:gradle:4.2.2")
10
+ // classpath 'com.android.tools.build:gradle:3.5.3'
12
11
  }
13
12
  }
14
13
  }
@@ -20,11 +19,10 @@ def safeExtGet(prop, fallback) {
20
19
  }
21
20
 
22
21
  android {
23
- namespace "com.reactnativekalapaekyc"
24
- compileSdkVersion safeExtGet('KalapaEkyc_compileSdkVersion', 35)
22
+ compileSdkVersion safeExtGet('KalapaEkyc_compileSdkVersion', 33)
25
23
  defaultConfig {
26
- minSdkVersion safeExtGet('KalapaEkyc_minSdkVersion', 26)
27
- targetSdkVersion safeExtGet('KalapaEkyc_targetSdkVersion', 35)
24
+ minSdkVersion safeExtGet('KalapaEkyc_minSdkVersion', 24)
25
+ targetSdkVersion safeExtGet('KalapaEkyc_targetSdkVersion', 33)
28
26
  versionCode 1
29
27
  versionName "1.8"
30
28
 
@@ -38,6 +36,10 @@ android {
38
36
  lintOptions {
39
37
  disable 'GradleCompatible'
40
38
  }
39
+ compileOptions {
40
+ sourceCompatibility JavaVersion.VERSION_1_8
41
+ targetCompatibility JavaVersion.VERSION_1_8
42
+ }
41
43
  }
42
44
 
43
45
  repositories {
@@ -54,5 +56,5 @@ dependencies {
54
56
  //noinspection GradleDynamicVersion
55
57
  implementation "com.facebook.react:react-native:+" // From node_modules
56
58
  //kalapasdk
57
- implementation 'vn.kalapa.payme:ekyc:2.10.9.4'
59
+ implementation 'vn.kalapa:ekyc:2.10.9'
58
60
  }
@@ -44,73 +44,85 @@ public class KalapaEkycModule extends ReactContextBaseJavaModule {
44
44
  public void multiply(int a, int b, Promise promise) {
45
45
  promise.resolve(a * b);
46
46
  }
47
-
47
+
48
48
 
49
49
  @ReactMethod
50
50
  public void start(String session, String flow, ReadableMap data, Promise promise) {
51
51
 
52
- String domain = data.getString("domain");
53
- String mainColor = data.getString("main_color") != null ? data.getString("main_color") : "#1F69E6";
54
- String background = data.getString("background_color") != null ? data.getString("background_color") : "#FFFFFF";
55
- String mainTextColor = data.getString("main_text_color") != null ? data.getString("main_text_color") : "#000000";
56
- String btnTextColor = data.getString("btn_text_color") != null ? data.getString("btn_text_color") : "#FFFFFF";
57
- String language = data.getString("language") != null ? data.getString("language") : "en";
58
- int livenessVersion = data.getInt("liveness_version");
59
-
60
-
61
- String faceData = data.getString("face_data") != null ? data.getString("face_data") : "";
62
- String mrzData = data.getString("mrz") != null ? data.getString("mrz") : "";
63
- String sessionId = data.getString("session_id") != null ? data.getString("session_id") : "";
64
-
65
- Context context = getReactApplicationContext();
66
- if (getCurrentActivity() != null) {
52
+ String domain = data.getString("domain");
53
+ String mainColor = data.getString("main_color") != null ? data.getString("main_color") : "#1F69E6";
54
+ String background = data.getString("background_color") != null ? data.getString("background_color") : "#FFFFFF";
55
+ String mainTextColor = data.getString("main_text_color") != null ? data.getString("main_text_color") : "#000000";
56
+ String btnTextColor = data.getString("btn_text_color") != null ? data.getString("btn_text_color") : "#FFFFFF";
57
+ String language = data.getString("language") != null ? data.getString("language") : "en";
58
+ int livenessVersion = data.getInt("liveness_version");
59
+
60
+ String faceData = data.getString("face_data") != null ? data.getString("face_data") : "";
61
+ String mrzData = data.getString("mrz") != null ? data.getString("mrz") : "";
62
+ String qrCode = data.getString("qr_code") != null ? data.getString("qr_code") : "";
63
+ String sessionId = data.getString("session_id") != null ? data.getString("session_id") : "";
64
+ boolean allowMrzRescanOnNfcMismatch = data.getBoolean("allow_mrz_rescan_on_nfc_mismatch");
65
+ Context context = getReactApplicationContext();
66
+ if (getCurrentActivity() != null) {
67
67
  KalapaSDKConfig klpConfig = new KalapaSDKConfig.KalapaSDKConfigBuilder(getCurrentActivity())
68
- .withBaseURL(domain)
69
- .withMainColor(mainColor)
70
- .withBackgroundColor(background)
71
- .withMainTextColor(mainTextColor)
72
- .withBtnTextColor(btnTextColor)
73
- .withLanguage(language)
74
- .withLivenessVersion(livenessVersion).build();
75
- System.out.println("KLP KalapaSDKConfig: " + klpConfig.getLivenessVersion());
76
- KalapaSDK.KalapaSDKBuilder builder = new KalapaSDK.KalapaSDKBuilder(getCurrentActivity(), klpConfig);
77
- if (faceData != null && !faceData.isEmpty()) builder.withFaceData(faceData);
78
- if (mrzData != null && !mrzData.isEmpty()) builder.withMrz(mrzData);
79
- if (sessionId != null && !sessionId.isEmpty()) builder.withLeftoverSession(sessionId);
80
-
81
- builder.build().start(session, flow, new KalapaHandler() {
82
- @Override
83
- public void onExpired() {
84
- promise.reject("EXPIRED", "Session expired");
68
+ .withBaseURL(domain)
69
+ .withMainColor(mainColor)
70
+ .withBackgroundColor(background)
71
+ .withMainTextColor(mainTextColor)
72
+ .withBtnTextColor(btnTextColor)
73
+ .withLanguage(language)
74
+ .withLivenessVersion(livenessVersion)
75
+ .withAllowMRZRescanOnNFCMismatch(allowMrzRescanOnNfcMismatch)
76
+ .build();
77
+
78
+ KalapaSDK.KalapaSDKBuilder builder = new KalapaSDK.KalapaSDKBuilder(getCurrentActivity(), klpConfig);
79
+ if (qrCode != null && !qrCode.isEmpty()) builder.withRawQRCode(qrCode);
80
+ if (faceData != null && !faceData.isEmpty()) builder.withFaceData(faceData);
81
+ if (mrzData != null && !mrzData.isEmpty()) builder.withMrz(mrzData);
82
+ if (sessionId != null && !sessionId.isEmpty()) builder.withLeftoverSession(sessionId);
83
+
84
+ builder.build().start(session, flow, new KalapaHandler() {
85
+ @Override
86
+ public void onExpired() {
87
+ promise.reject("EXPIRED", "Session expired");
85
88
  // promise.reject("401", "EXPIRED");
86
- }
87
-
88
- @Override
89
- public void onComplete(@NonNull KalapaResult kalapaResult) {
90
- super.onComplete(kalapaResult);
91
- String resultMap = kalapaResult.toJson();
92
- WritableMap res = new WritableNativeMap();
93
- res.putString("kalapa_result", resultMap);
89
+ }
90
+
91
+ @Override
92
+ public void onComplete(@NonNull KalapaResult kalapaResult) {
93
+ String resultMap = kalapaResult.toJson();
94
+ WritableMap res = new WritableNativeMap();
95
+ res.putString("kalapa_result", resultMap);
94
96
  // callback.invoke(res);
95
- promise.resolve(res);
96
- }
97
-
98
- @Override
99
- public void onError(@NonNull KalapaSDKResultCode kalapaSDKResultCode) {
100
- super.onError(kalapaSDKResultCode);
101
- switch (kalapaSDKResultCode) {
102
- case USER_LEAVE:
103
- promise.reject("CANCELED", kalapaSDKResultCode.getEn());
104
- case DEVICE_NOT_SUPPORTED:
105
- promise.reject("UNSUPPORTED", kalapaSDKResultCode.getEn());
106
- case CONFIGURATION_NOT_ACCEPTABLE:
107
- promise.reject("CONFIG_ERROR", kalapaSDKResultCode.getEn());
108
- default:
109
- promise.reject("OTHER", kalapaSDKResultCode.getEn());
110
- }
111
- }
112
- });
113
- } else Toast.makeText(getReactApplicationContext(), "Activity is null", Toast.LENGTH_LONG).show();
97
+ promise.resolve(res);
98
+ }
99
+
100
+ @Override
101
+ public void onError(@NonNull KalapaSDKResultCode kalapaSDKResultCode, @NonNull String message) {
102
+ switch (kalapaSDKResultCode) {
103
+ case USER_LEAVE:
104
+ promise.reject("CANCELED", message);
105
+ case DEVICE_NOT_SUPPORTED:
106
+ promise.reject("UNSUPPORTED", message);
107
+ case CONFIGURATION_NOT_ACCEPTABLE:
108
+ promise.reject("CONFIG_ERROR", message);
109
+ case INVALID_NFC:
110
+ promise.reject("MRZ_INVALID", message);
111
+ case WRONG_CCCDID:
112
+ promise.reject("NFC_NOT_MATCH", message);
113
+ case PERMISSION_DENIED:
114
+ promise.reject("PERMISSION_DENIED", message);
115
+ case VIRTUAL_CAMERA_DETECTED:
116
+ case ROOTED_DEVICE_DETECTED:
117
+ case EMULATOR_DETECTED:
118
+ promise.reject("DEVICE_NOT_ACCEPTABLE", message);
119
+ default:
120
+ promise.reject("OTHER", message);
121
+ }
122
+ }
123
+ });
124
+ } else
125
+ Toast.makeText(getReactApplicationContext(), "Activity is null", Toast.LENGTH_LONG).show();
114
126
  }
115
127
 
116
128
  public static native int nativeMultiply(int a, int b);
package/ios/KalapaEkyc.m CHANGED
@@ -26,7 +26,9 @@ RCT_EXPORT_METHOD(start:(NSString *)session
26
26
  NSString *faceData = data[@"face_data"];
27
27
  NSString *mrz = data[@"mrz"];
28
28
  NSString *sessionID = data[@"session_id"];
29
-
29
+ id val = data[@"allow_mrz_rescan_on_nfc_mismatch"];
30
+ BOOL allowMRZRescanOnNfcMismatch = [val isKindOfClass:NSNumber.class] ? [val boolValue] : NO;
31
+
30
32
  KLPAppearance *klpAppearance = [[[[[[KLPAppearance Builder]
31
33
  withLanguage:language]
32
34
  withMainColor:mainColor]
@@ -39,18 +41,26 @@ RCT_EXPORT_METHOD(start:(NSString *)session
39
41
  livenessVersion:livenessVersion
40
42
  appearance:klpAppearance
41
43
  mrz:mrz
42
- faceData:faceData];
44
+ faceData:faceData
45
+ allowMRZRescanOnNfcMismatch:allowMRZRescanOnNfcMismatch];
43
46
 
44
47
  if (sessionID != nil) {
45
48
  [klpConfig withSession:sessionID];
46
49
  }
47
50
 
48
- [klpConfig withExpiredHandler:^{
49
- reject(@"EXPIRED", @"Session expired", nil);
50
- }];
51
-
52
- [klpConfig withCancelSessionHandler:^{
53
- reject(@"CANCELED", @"Session was canceled by the user", nil);
51
+ [klpConfig withEventHandler:^(enum Event event) {
52
+ switch (event) {
53
+ case EventSessionTerminated:
54
+ reject(@"CANCELED", @"Người dùng hủy bỏ xác thực", nil);
55
+ break;
56
+ case EventSessionExpired:
57
+ reject(@"UNAUTHORIZED", @"Quá trình xác thực thất bại, vui lòng kiểm tra lại", nil);
58
+ break;
59
+ default:
60
+ reject(@"OTHER", @"Đã có lỗi xảy ra", nil);
61
+ break;
62
+ }
63
+
54
64
  }];
55
65
 
56
66
  [klpConfig withResultHandler:^(KalapaResult * _Nullable result) {
@@ -81,7 +91,8 @@ RCT_EXPORT_METHOD(start:(NSString *)session
81
91
  livenessVersion:(NSInteger)livenessVersion
82
92
  appearance:(KLPAppearance *)appearance
83
93
  mrz:(NSString *)mrz
84
- faceData:(NSString *)faceData {
94
+ faceData:(NSString *)faceData
95
+ allowMRZRescanOnNfcMismatch:(BOOL)allowMRZRescanOnNfcMismatch {
85
96
  KLPConfig *config = [[[[[[KLPConfig BuilderWithSession:session]
86
97
  withBaseUrl:domain]
87
98
  withLivenessVersion:livenessVersion]
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "react-native-kalapa-ekyc",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "React Native SDK for Kalapa eKYC integration",
5
- "main": "lib/commonjs/index.js",
5
+ "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
7
7
  "types": "lib/typescript/src/index.d.ts",
8
8
  "react-native": "src/index.tsx",
9
- "source": "src/index.tsx",
9
+ "source": "src/index",
10
10
  "files": [
11
11
  "src",
12
12
  "lib",
@@ -16,17 +16,15 @@
16
16
  "android",
17
17
  "ios",
18
18
  "cpp",
19
- "Frameworks",
20
19
  "react-native-kalapa-ekyc.podspec",
20
+ "!lib/typescript/example",
21
21
  "!android/build",
22
22
  "!ios/build"
23
23
  ],
24
24
  "scripts": {
25
25
  "test": "jest",
26
26
  "typescript": "tsc --noEmit",
27
- "lint": "eslint \"**/*.{js,ts,tsx}\"",
28
- "prepare": "npm run build",
29
- "build": "echo 'Build completed'"
27
+ "lint": "eslint \"**/*.{js,ts,tsx}\""
30
28
  },
31
29
  "keywords": [
32
30
  "react-native",
@@ -49,8 +47,8 @@
49
47
  "@react-native-community/eslint-config": "^2.0.0",
50
48
  "@release-it/conventional-changelog": "^2.0.0",
51
49
  "@types/jest": "^26.0.0",
52
- "@types/react": "17.0.2",
53
- "@types/react-native": "0.63.4",
50
+ "@types/react": "^16.9.19",
51
+ "@types/react-native": "0.62.13",
54
52
  "commitlint": "^11.0.0",
55
53
  "eslint": "^7.2.0",
56
54
  "eslint-config-prettier": "^7.0.0",
@@ -59,14 +57,15 @@
59
57
  "jest": "^26.0.1",
60
58
  "pod-install": "^0.1.0",
61
59
  "prettier": "^2.0.5",
60
+ "react": "16.13.1",
61
+ "react-native": "0.63.4",
62
62
  "react-native-builder-bob": "^0.18.0",
63
63
  "release-it": "^14.2.2",
64
64
  "typescript": "^4.1.3"
65
65
  },
66
66
  "peerDependencies": {
67
- "react": "^17.0.2",
68
- "react-native": "^0.66.4",
69
- "react-native-reanimated": ">1.9.0"
67
+ "react": "*",
68
+ "react-native": "*"
70
69
  },
71
70
  "jest": {
72
71
  "preset": "react-native",
@@ -14,6 +14,7 @@ Pod::Spec.new do |s|
14
14
  s.source = { :git => "https://gitlab.com/littlepjg/klp-ekyc-react-native.git", :tag => "#{s.version}" }
15
15
 
16
16
  s.source_files = "ios/**/*.{h,m,mm}"
17
+ #s.ios.vendored_frameworks = "Frameworks/KalapaSDK.xcframework"
17
18
 
18
19
  s.dependency "React-Core"
19
20
  s.dependency "KalapaEkycSDK"
@@ -0,0 +1,326 @@
1
+ /**
2
+ * KalapaResult - Simplified and standardized result parser for NFC-only mode
3
+ * Handles both Android and iOS response formats
4
+ */
5
+
6
+ export interface SelfieData {
7
+ is_matched: boolean;
8
+ matching_score: number;
9
+ }
10
+
11
+ export interface NfcData {
12
+ // Personal Information
13
+ name: string;
14
+ id_number: string;
15
+ old_id_number: string;
16
+ date_of_birth: string;
17
+ date_of_expiry: string;
18
+ date_of_issuance: string;
19
+ gender: string;
20
+ nationality: string;
21
+ nation: string;
22
+
23
+ // Address Information
24
+ address: string;
25
+ hometown: string;
26
+
27
+ // Family Information
28
+ father_name: string;
29
+ mother_name: string;
30
+ spouse_name: string;
31
+
32
+ // Additional Information
33
+ religion: string;
34
+ personal_identification: string;
35
+
36
+ // Technical Data
37
+ face_image: string; // Base64 image from NFC chip
38
+ mrz: string;
39
+ }
40
+
41
+ export interface AddressEntities {
42
+ district: string;
43
+ ward: string;
44
+ province: string;
45
+ unknown: string;
46
+ }
47
+
48
+ export interface MrzDataFields {
49
+ birthday?: string;
50
+ doe?: string;
51
+ gender?: string;
52
+ id_number?: string;
53
+ name?: string;
54
+ }
55
+
56
+ export interface MrzDataError {
57
+ code: number;
58
+ message: string;
59
+ }
60
+
61
+ export interface MrzData {
62
+ data?: {
63
+ fields?: MrzDataFields;
64
+ raw_mrz?: string;
65
+ };
66
+ error?: MrzDataError;
67
+ }
68
+
69
+ export interface QrCodeData {
70
+ decoded_text?: string;
71
+ stage?: number;
72
+ }
73
+
74
+ export interface QrCode {
75
+ data?: QrCodeData;
76
+ error?: {
77
+ code: number;
78
+ message: string;
79
+ };
80
+ }
81
+
82
+ export type DecisionType = 'APPROVED' | 'MANUAL' | 'REJECTED' | 'UNKNOWN';
83
+
84
+ export class KalapaResult {
85
+ // Root level common fields
86
+ public birthday!: string;
87
+ public country!: string;
88
+ public decision!: DecisionType;
89
+ public doe!: string; // Date of expiry
90
+ public doi!: string; // Date of issuance
91
+ public ethnicity!: string;
92
+ public features!: string;
93
+ public gender!: string;
94
+ public home!: string;
95
+ public home_entities!: AddressEntities;
96
+ public id_number!: string;
97
+ public mrz_data!: MrzData | null;
98
+ public name!: string;
99
+ public national!: string;
100
+ public nfc_data!: NfcData;
101
+ public poi!: string;
102
+ public qr_code!: QrCode | null;
103
+ public religion!: string;
104
+ public resident!: string;
105
+ public resident_entities!: AddressEntities;
106
+ public selfie_data!: SelfieData;
107
+ public session!: string;
108
+ public type!: string;
109
+ public rawResult: any;
110
+
111
+ constructor(rawResult: any) {
112
+ this.rawResult = rawResult;
113
+ this._parseResult();
114
+ }
115
+
116
+ private _parseResult(): void {
117
+ // Handle both wrapped (kalapa_result) and unwrapped responses
118
+ const kalapaData = this.rawResult?.kalapa_result || this.rawResult || {};
119
+
120
+ // Parse root level common fields
121
+ this.birthday = kalapaData.birthday || '';
122
+ this.country = kalapaData.country || '';
123
+ this.decision = (kalapaData.decision || 'UNKNOWN') as DecisionType;
124
+ this.doe = kalapaData.doe || '';
125
+ this.doi = kalapaData.doi || '';
126
+ this.ethnicity = kalapaData.ethnicity || '';
127
+ this.features = kalapaData.features || '';
128
+ this.gender = kalapaData.gender || '';
129
+ this.home = kalapaData.home || '';
130
+ this.home_entities = {
131
+ district: kalapaData.home_entities?.district || '',
132
+ ward: kalapaData.home_entities?.ward || '',
133
+ province: kalapaData.home_entities?.province || '',
134
+ unknown: kalapaData.home_entities?.unknown || ''
135
+ };
136
+ // Handle both idNumber (Android) and id_number (iOS)
137
+ this.id_number = kalapaData.id_number || kalapaData.idNumber || '';
138
+ this.name = kalapaData.name || '';
139
+ this.national = kalapaData.national || '';
140
+ this.poi = kalapaData.poi || '';
141
+ this.religion = kalapaData.religion || '';
142
+ this.resident = kalapaData.resident || '';
143
+ this.resident_entities = {
144
+ district: kalapaData.resident_entities?.district || '',
145
+ ward: kalapaData.resident_entities?.ward || '',
146
+ province: kalapaData.resident_entities?.province || '',
147
+ unknown: kalapaData.resident_entities?.unknown || ''
148
+ };
149
+ this.session = kalapaData.session || '';
150
+ this.type = kalapaData.type || '';
151
+
152
+ // Parse MRZ data (available on both platforms)
153
+ const mrzRaw = kalapaData.mrz_data;
154
+ if (mrzRaw && typeof mrzRaw === 'object' && mrzRaw !== null) {
155
+ this.mrz_data = {
156
+ data: mrzRaw.data ? {
157
+ fields: mrzRaw.data.fields || {},
158
+ raw_mrz: mrzRaw.data.raw_mrz || ''
159
+ } : undefined,
160
+ error: mrzRaw.error ? {
161
+ code: mrzRaw.error.code || 0,
162
+ message: mrzRaw.error.message || ''
163
+ } : undefined
164
+ };
165
+ } else {
166
+ this.mrz_data = null;
167
+ }
168
+
169
+ // Parse QR code data (available on both platforms)
170
+ const qrRaw = kalapaData.qr_code;
171
+ if (qrRaw && typeof qrRaw === 'object' && qrRaw !== null) {
172
+ this.qr_code = {
173
+ data: qrRaw.data ? {
174
+ decoded_text: qrRaw.data.decoded_text || '',
175
+ stage: qrRaw.data.stage || undefined
176
+ } : undefined,
177
+ error: qrRaw.error ? {
178
+ code: qrRaw.error.code || 0,
179
+ message: qrRaw.error.message || ''
180
+ } : undefined
181
+ };
182
+ } else {
183
+ this.qr_code = null;
184
+ }
185
+
186
+ // Parse selfie data (identical structure on both platforms)
187
+ const selfieRaw = kalapaData.selfie_data || {};
188
+ this.selfie_data = {
189
+ is_matched: selfieRaw.is_matched || false,
190
+ matching_score: selfieRaw.matching_score || 0
191
+ };
192
+
193
+ // Parse NFC data (core fields available on both platforms)
194
+ const nfcRaw = kalapaData.nfc_data || {};
195
+ this.nfc_data = {
196
+ // Personal Information
197
+ name: nfcRaw.name || '',
198
+ id_number: nfcRaw.id_number || '',
199
+ old_id_number: nfcRaw.old_id_number || '',
200
+ date_of_birth: nfcRaw.date_of_birth || '',
201
+ date_of_expiry: nfcRaw.date_of_expiry || '',
202
+ date_of_issuance: nfcRaw.date_of_issuance || '',
203
+ gender: nfcRaw.gender || '',
204
+ nationality: nfcRaw.nationality || '',
205
+ nation: nfcRaw.nation || '',
206
+
207
+ // Address Information
208
+ address: nfcRaw.address || '',
209
+ hometown: nfcRaw.hometown || '',
210
+
211
+ // Family Information
212
+ father_name: nfcRaw.father_name || '',
213
+ mother_name: nfcRaw.mother_name || '',
214
+ spouse_name: nfcRaw.spouse_name || '',
215
+
216
+ // Additional Information
217
+ religion: nfcRaw.religion || '',
218
+ personal_identification: nfcRaw.personal_identification || '',
219
+
220
+ // Technical Data
221
+ face_image: nfcRaw.face_image || '', // Base64 image from NFC chip
222
+ mrz: nfcRaw.mrz || '',
223
+ };
224
+ }
225
+
226
+ // Convenience methods
227
+ public isApproved(): boolean {
228
+ return this.decision === 'APPROVED';
229
+ }
230
+
231
+ public isManualReview(): boolean {
232
+ return this.decision === 'MANUAL';
233
+ }
234
+
235
+ public isRejected(): boolean {
236
+ return this.decision === 'REJECTED';
237
+ }
238
+
239
+ public isFaceMatched(): boolean {
240
+ return this.selfie_data.is_matched === true;
241
+ }
242
+
243
+ public getFaceMatchingScore(): number {
244
+ return this.selfie_data.matching_score;
245
+ }
246
+
247
+ // Get formatted display name
248
+ public getDisplayName(): string {
249
+ return this.nfc_data.name || 'N/A';
250
+ }
251
+
252
+ // Get formatted ID number
253
+ public getIdNumber(): string {
254
+ return this.nfc_data.id_number || 'N/A';
255
+ }
256
+
257
+ // Get formatted date of birth
258
+ public getDateOfBirth(): string {
259
+ return this.nfc_data.date_of_birth || 'N/A';
260
+ }
261
+
262
+ // Get face image (Base64)
263
+ public getFaceImage(): string {
264
+ return this.nfc_data.face_image;
265
+ }
266
+
267
+ // Export essential data as plain object
268
+ public toJSON(): {
269
+ birthday: string;
270
+ country: string;
271
+ decision: DecisionType;
272
+ doe: string;
273
+ doi: string;
274
+ ethnicity: string;
275
+ features: string;
276
+ gender: string;
277
+ home: string;
278
+ home_entities: AddressEntities;
279
+ id_number: string;
280
+ mrz_data: MrzData | null;
281
+ name: string;
282
+ national: string;
283
+ nfc_data: NfcData;
284
+ poi: string;
285
+ qr_code: QrCode | null;
286
+ religion: string;
287
+ resident: string;
288
+ resident_entities: AddressEntities;
289
+ selfie_data: SelfieData;
290
+ session: string;
291
+ type: string;
292
+ } {
293
+ return {
294
+ birthday: this.birthday,
295
+ country: this.country,
296
+ decision: this.decision,
297
+ doe: this.doe,
298
+ doi: this.doi,
299
+ ethnicity: this.ethnicity,
300
+ features: this.features,
301
+ gender: this.gender,
302
+ home: this.home,
303
+ home_entities: this.home_entities,
304
+ id_number: this.id_number,
305
+ mrz_data: this.mrz_data,
306
+ name: this.name,
307
+ national: this.national,
308
+ nfc_data: this.nfc_data,
309
+ poi: this.poi,
310
+ qr_code: this.qr_code,
311
+ religion: this.religion,
312
+ resident: this.resident,
313
+ resident_entities: this.resident_entities,
314
+ selfie_data: this.selfie_data,
315
+ session: this.session,
316
+ type: this.type
317
+ };
318
+ }
319
+
320
+ // Static factory method to create from raw result
321
+ public static fromRawResult(rawResult: any): KalapaResult {
322
+ return new KalapaResult(rawResult);
323
+ }
324
+ }
325
+
326
+ export default KalapaResult;