@finos_sdk/sdk-ekyc 1.4.6 → 1.4.7
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 +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/java/finos/sdk/ekyc/EKYCModule.kt +131 -86
- package/dist/EKYCModule.d.ts +6 -6
- package/dist/index.d.ts +2 -2
- package/dist/package.json +1 -1
- package/dist/src/modules/FinosEKYCModule.d.ts +6 -6
- package/dist/src/modules/FinosESignModule.d.ts +7 -7
- package/dist/src/types/ekycFaceType.d.ts +9 -0
- package/dist/src/types/ekycLivenessType.d.ts +9 -0
- package/ios/EKYCModule.swift +10 -2
- package/package.json +1 -1
- package/src/modules/FinosEKYCModule.ts +6 -6
- package/src/modules/FinosESignModule.ts +6 -6
- package/src/types/ekycFaceType.ts +10 -0
- package/src/types/ekycLivenessType.ts +10 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
React Native SDK for eKYC (electronic Know Your Customer) and eSign. Features include Vietnamese CCCD NFC reading, OCR, Liveness detection, Face matching, C06 residence verification, SMS OTP verification, and Electronic Signature (eSign) capabilities.
|
|
7
7
|
|
|
8
|
-
**Version**: 1.4.
|
|
8
|
+
**Version**: 1.4.7
|
|
9
9
|
|
|
10
10
|
## Features
|
|
11
11
|
|
package/android/build.gradle
CHANGED
|
@@ -65,7 +65,7 @@ dependencies {
|
|
|
65
65
|
implementation 'com.facebook.react:react-android'
|
|
66
66
|
|
|
67
67
|
// Finos eKYC SDK dependencies from GitHub Packages Maven repository
|
|
68
|
-
def sdkVersion = "1.4.
|
|
68
|
+
def sdkVersion = "1.4.7"
|
|
69
69
|
implementation("finos.sdk.ekyc:ekyc:$sdkVersion")
|
|
70
70
|
implementation("finos.sdk.ekyc:ekycui:$sdkVersion")
|
|
71
71
|
implementation("finos.sdk.ekyc:nfc:$sdkVersion")
|
|
@@ -97,6 +97,46 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
97
97
|
return Pair(eventMap, promiseMap)
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/** Recursively convert org.json.JSONObject → WritableMap (preserves key names as-is). */
|
|
101
|
+
private fun jsonObjectToWritableMap(jsonObject: JSONObject): WritableMap {
|
|
102
|
+
val map = Arguments.createMap()
|
|
103
|
+
val keys = jsonObject.keys()
|
|
104
|
+
while (keys.hasNext()) {
|
|
105
|
+
val key = keys.next()
|
|
106
|
+
when (val value = jsonObject.get(key)) {
|
|
107
|
+
is JSONObject -> map.putMap(key, jsonObjectToWritableMap(value))
|
|
108
|
+
is JSONArray -> map.putArray(key, jsonArrayToWritableArray(value))
|
|
109
|
+
is Boolean -> map.putBoolean(key, value)
|
|
110
|
+
is Int -> map.putInt(key, value)
|
|
111
|
+
is Long -> map.putDouble(key, value.toDouble())
|
|
112
|
+
is Double -> map.putDouble(key, value)
|
|
113
|
+
is String -> map.putString(key, value)
|
|
114
|
+
JSONObject.NULL -> map.putNull(key)
|
|
115
|
+
else -> map.putString(key, value.toString())
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return map
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Recursively convert org.json.JSONArray → WritableArray. */
|
|
122
|
+
private fun jsonArrayToWritableArray(jsonArray: JSONArray): WritableArray {
|
|
123
|
+
val array = Arguments.createArray()
|
|
124
|
+
for (i in 0 until jsonArray.length()) {
|
|
125
|
+
when (val value = jsonArray.get(i)) {
|
|
126
|
+
is JSONObject -> array.pushMap(jsonObjectToWritableMap(value))
|
|
127
|
+
is JSONArray -> array.pushArray(jsonArrayToWritableArray(value))
|
|
128
|
+
is Boolean -> array.pushBoolean(value)
|
|
129
|
+
is Int -> array.pushInt(value)
|
|
130
|
+
is Long -> array.pushDouble(value.toDouble())
|
|
131
|
+
is Double -> array.pushDouble(value)
|
|
132
|
+
is String -> array.pushString(value)
|
|
133
|
+
JSONObject.NULL -> array.pushNull()
|
|
134
|
+
else -> array.pushString(value.toString())
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return array
|
|
138
|
+
}
|
|
139
|
+
|
|
100
140
|
/** Convert ESignOpenSessionResult to WritableMap for RN. */
|
|
101
141
|
private fun eSignOpenSessionResultToWritableMap(result: ESignModels.ESignOpenSessionResult): WritableMap =
|
|
102
142
|
Arguments.createMap().apply {
|
|
@@ -493,24 +533,25 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
493
533
|
eKYCFinOSLiveness.startEkyc(
|
|
494
534
|
ekycConfigSDK = ekycConfig,
|
|
495
535
|
callbackSuccess = { event, data ->
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
536
|
+
Log.d(TAG, "🔥 NATIVE CALLBACK (Liveness): event=${event.name}")
|
|
537
|
+
val response = (data as? SDKEkycResult)?.checkLivenessResponse
|
|
538
|
+
val jsonStr = data?.customData?.let { Gson().toJson(it) } ?: Gson().toJson(response ?: data)
|
|
539
|
+
|
|
540
|
+
// Helper to create fresh data map to avoid 'Map already consumed' error
|
|
541
|
+
fun createWritableData() = try { jsonObjectToWritableMap(JSONObject(jsonStr)) } catch (e: Exception) { Arguments.createMap() }
|
|
542
|
+
|
|
543
|
+
// Send the event directly to React Native
|
|
544
|
+
sendEvent("onLivenessSuccess", Arguments.createMap().apply {
|
|
545
|
+
putString("event", event.name)
|
|
546
|
+
putMap("data", createWritableData())
|
|
547
|
+
})
|
|
548
|
+
|
|
549
|
+
// Always attempt to resolve the promise.
|
|
550
|
+
// RN safely ignores subsequent resolves if the native SDK fires multiple events.
|
|
551
|
+
promise.resolve(Arguments.createMap().apply {
|
|
552
|
+
putString("event", event.name)
|
|
553
|
+
putMap("data", createWritableData())
|
|
554
|
+
})
|
|
514
555
|
},
|
|
515
556
|
callbackError = { event, errorResult ->
|
|
516
557
|
Log.e(TAG, "❌ startLiveness() failed - Event: $event, Code: ${errorResult.code}, Message: ${errorResult.message}")
|
|
@@ -577,40 +618,21 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
577
618
|
eKYCFinOSFaceService.startEkyc(
|
|
578
619
|
ekycConfigSDK = ekycConfig,
|
|
579
620
|
callbackSuccess = { event, data ->
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
map.putString("event", event.name.toString())
|
|
596
|
-
val resultMap = Arguments.createMap().apply {
|
|
597
|
-
putDouble("conf", faceResponse?.result?.conf?.toString()?.toDoubleOrNull() ?: 0.0)
|
|
598
|
-
putString("match", faceResponse?.result?.match?.toString())
|
|
599
|
-
putInt("matchScore", faceResponse?.result?.matchScore?.toString()?.toIntOrNull() ?: 0)
|
|
600
|
-
putString("toBeReviewed", faceResponse?.result?.toBeReviewed?.toString())
|
|
601
|
-
}
|
|
602
|
-
val faceMap = Arguments.createMap().apply {
|
|
603
|
-
putString("requestId", faceResponse?.requestId?.toString())
|
|
604
|
-
putMap("result", resultMap)
|
|
605
|
-
putString("status", faceResponse?.status?.toString())
|
|
606
|
-
putInt("statusCode", faceResponse?.statusCode?.toString()?.toIntOrNull() ?: 0)
|
|
607
|
-
putString("error", faceResponse?.error?.toString())
|
|
608
|
-
putString("type", faceResponse?.type?.toString())
|
|
609
|
-
}
|
|
610
|
-
map.putMap("data", faceMap)
|
|
611
|
-
}
|
|
612
|
-
sendEvent("onFaceCompareSuccess", eventMap)
|
|
613
|
-
promise.resolve(promiseMap)
|
|
621
|
+
Log.d(TAG, "🔥 NATIVE CALLBACK (Face Compare): event=${event.name}")
|
|
622
|
+
val response = (data as? SDKEkycResult)?.checkFaceResponse
|
|
623
|
+
val jsonStr = data?.customData?.let { Gson().toJson(it) } ?: Gson().toJson(response ?: data)
|
|
624
|
+
fun createWritableData() = try { jsonObjectToWritableMap(JSONObject(jsonStr)) } catch (e: Exception) { Arguments.createMap() }
|
|
625
|
+
|
|
626
|
+
sendEvent("onFaceCompareSuccess", Arguments.createMap().apply {
|
|
627
|
+
putString("event", event.name)
|
|
628
|
+
putMap("data", createWritableData())
|
|
629
|
+
})
|
|
630
|
+
|
|
631
|
+
// Always attempt to resolve the promise.
|
|
632
|
+
promise.resolve(Arguments.createMap().apply {
|
|
633
|
+
putString("event", event.name)
|
|
634
|
+
putMap("data", createWritableData())
|
|
635
|
+
})
|
|
614
636
|
},
|
|
615
637
|
callbackError = { event, errorResult ->
|
|
616
638
|
Log.e(TAG, "❌ startFaceCompare() failed - Event: $event, Code: ${errorResult.code}, Message: ${errorResult.message}")
|
|
@@ -835,41 +857,55 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
835
857
|
activity = currentActivity,
|
|
836
858
|
ekycConfigSDK = ekycConfigSDK,
|
|
837
859
|
callbackSuccess = { event, data ->
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
val logDataStr = data?.customData?.let { Gson().toJson(it) } ?: Gson().toJson(data)
|
|
841
|
-
Log.d(TAG, "LOG_SUCCESS [EkycUI]: $logDataStr")
|
|
842
|
-
sendEvent("onEkycUISuccess", Arguments.createMap().apply {
|
|
843
|
-
putString("status", "log")
|
|
844
|
-
putString("event", event.name.toString())
|
|
845
|
-
putString("data", logDataStr)
|
|
846
|
-
})
|
|
847
|
-
return@startEkyc
|
|
848
|
-
}
|
|
849
|
-
Log.d(TAG, "✅ startEkycUI() callback - event=${event.name}")
|
|
860
|
+
Log.d(TAG, "🔥 NATIVE CALLBACK (EkycUI): event=${event.name}")
|
|
861
|
+
|
|
850
862
|
val result = data as? SDKEkycResult
|
|
851
|
-
val
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
863
|
+
val response = result?.ekycStateModel
|
|
864
|
+
val jsonStr = data?.customData?.let { Gson().toJson(it) } ?: Gson().toJson(response ?: data)
|
|
865
|
+
|
|
866
|
+
// Helper to create fresh data map to avoid 'Map already consumed' error
|
|
867
|
+
fun createWritableData() = try { jsonObjectToWritableMap(JSONObject(jsonStr)) } catch (e: Exception) { Arguments.createMap() }
|
|
868
|
+
|
|
869
|
+
val statusStr = when (event) {
|
|
870
|
+
EKYCEvent.LOG_SUCCESS -> "log"
|
|
871
|
+
EKYCEvent.SDK_START_SUCCESS -> "started"
|
|
872
|
+
else -> "success"
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// Send EVERY event directly to React Native Event Listener (Pass-through)
|
|
876
|
+
sendEvent("onEkycUISuccess", Arguments.createMap().apply {
|
|
877
|
+
putString("status", statusStr)
|
|
878
|
+
putString("event", event.name)
|
|
879
|
+
|
|
880
|
+
if (event == EKYCEvent.SDK_START_SUCCESS && response == null) {
|
|
881
|
+
// Bỏ qua data nếu là SDK_START_SUCCESS (chỉ có event/status) để giống code cũ
|
|
882
|
+
} else {
|
|
883
|
+
putMap("data", createWritableData())
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// Retain the convenient root properties cho backward compatibility
|
|
860
887
|
val ekycFiles = result?.ekycStateModel?.eKYCFileModel
|
|
861
888
|
val ekycTransactionId = result?.ekycStateModel?.transactionId ?: ""
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
889
|
+
if (ekycTransactionId.isNotEmpty()) putString("transactionId", ekycTransactionId)
|
|
890
|
+
ekycFiles?.imageFace?.absolutePath?.let { putString("imageFacePath", it) }
|
|
891
|
+
ekycFiles?.imageOcrFront?.absolutePath?.let { putString("imageOcrFrontPath", it) }
|
|
892
|
+
ekycFiles?.imageOcrBack?.absolutePath?.let { putString("imageOcrBackPath", it) }
|
|
893
|
+
})
|
|
894
|
+
|
|
895
|
+
// IMPORTANT: Chỉ resolve promise ở SDK_END_SUCCESS để `await FinosEKYC.startEkycUI()` không bị kết thúc sớm
|
|
896
|
+
if (event == EKYCEvent.SDK_END_SUCCESS) {
|
|
897
|
+
promise.resolve(Arguments.createMap().apply {
|
|
898
|
+
putString("status", "success")
|
|
899
|
+
putString("event", event.name)
|
|
900
|
+
putMap("data", createWritableData())
|
|
901
|
+
|
|
902
|
+
val ekycFiles = result?.ekycStateModel?.eKYCFileModel
|
|
903
|
+
val ekycTransactionId = result?.ekycStateModel?.transactionId ?: ""
|
|
904
|
+
if (ekycTransactionId.isNotEmpty()) putString("transactionId", ekycTransactionId)
|
|
905
|
+
ekycFiles?.imageFace?.absolutePath?.let { putString("imageFacePath", it) }
|
|
906
|
+
ekycFiles?.imageOcrFront?.absolutePath?.let { putString("imageOcrFrontPath", it) }
|
|
907
|
+
ekycFiles?.imageOcrBack?.absolutePath?.let { putString("imageOcrBackPath", it) }
|
|
908
|
+
})
|
|
873
909
|
}
|
|
874
910
|
},
|
|
875
911
|
callbackError = { event, errorResult ->
|
|
@@ -881,14 +917,14 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
881
917
|
putString("customMessage", errorResult.message)
|
|
882
918
|
putString("message", errorResult.message)
|
|
883
919
|
}
|
|
920
|
+
sendEvent("onEkycUIError", errorMap)
|
|
921
|
+
|
|
884
922
|
val promiseErrorMap = Arguments.createMap().apply {
|
|
885
923
|
putString("status", "error")
|
|
886
924
|
putString("event", event.name.toString())
|
|
887
925
|
putString("customCode", errorResult.code)
|
|
888
926
|
putString("customMessage", errorResult.message)
|
|
889
|
-
putString("message", errorResult.message)
|
|
890
927
|
}
|
|
891
|
-
sendEvent("onEkycUIError", errorMap)
|
|
892
928
|
promise.reject(event.name.toString(), errorResult.message, null, promiseErrorMap)
|
|
893
929
|
}
|
|
894
930
|
)
|
|
@@ -2174,4 +2210,13 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
2174
2210
|
}
|
|
2175
2211
|
}
|
|
2176
2212
|
|
|
2213
|
+
@ReactMethod
|
|
2214
|
+
fun addListener(eventName: String) {
|
|
2215
|
+
// Keep: Required for RN built-in Event Emitter Calls.
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
@ReactMethod
|
|
2219
|
+
fun removeListeners(count: Int) {
|
|
2220
|
+
// Keep: Required for RN built-in Event Emitter Calls.
|
|
2221
|
+
}
|
|
2177
2222
|
}
|
package/dist/EKYCModule.d.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { NfcConfig, NfcError } from './src/types/ekycNFCType';
|
|
|
3
3
|
import { SDKEkycResultWithEvent, SDKEkycResultStringWithEvent, StartEkycUIResult } from './src/types/ekycType';
|
|
4
4
|
import { C06Config } from './src/types/ekycC06Type';
|
|
5
5
|
import { OcrConfig } from './src/types/ekycOCRType';
|
|
6
|
-
import { LivenessConfig, SDKFaceDetectStatus } from './src/types/ekycLivenessType';
|
|
7
|
-
import { FaceServiceConfig } from './src/types/ekycFaceType';
|
|
6
|
+
import { LivenessConfig, SDKFaceDetectStatus, LivenessSuccessEvent } from './src/types/ekycLivenessType';
|
|
7
|
+
import { FaceServiceConfig, FaceCompareSuccessEvent } from './src/types/ekycFaceType';
|
|
8
8
|
import { SmsOtpConfig, SmsOtpResult, SmsOtpError } from './src/types/ekycSmsOtpType';
|
|
9
9
|
import { ESignInitResult, ESignOpenSessionResult, ESignCertificate, ESignSignRequest, ESignError, AuthorizeInfo, ESignPdfResult, ESignApiResponse } from './src/types/ekycESignType';
|
|
10
10
|
export declare const SDK_VERSION: string;
|
|
@@ -29,8 +29,8 @@ declare class SDKeKYC {
|
|
|
29
29
|
startOcr(config: OcrConfig): Promise<SDKEkycResultStringWithEvent>;
|
|
30
30
|
startNfcScan(config: NfcConfig): Promise<SDKEkycResultStringWithEvent>;
|
|
31
31
|
checkC06(config: C06Config): Promise<SDKEkycResultStringWithEvent>;
|
|
32
|
-
startLiveness(config: LivenessConfig): Promise<
|
|
33
|
-
startFaceCompare(config: FaceServiceConfig): Promise<
|
|
32
|
+
startLiveness(config: LivenessConfig): Promise<LivenessSuccessEvent>;
|
|
33
|
+
startFaceCompare(config: FaceServiceConfig): Promise<FaceCompareSuccessEvent>;
|
|
34
34
|
onResume(): void;
|
|
35
35
|
onPause(): void;
|
|
36
36
|
onNfcScanStart(callback: (data: SDKEkycResultWithEvent) => void): EmitterSubscription | null;
|
|
@@ -40,9 +40,9 @@ declare class SDKeKYC {
|
|
|
40
40
|
onC06Error(callback: (error: NfcError) => void): EmitterSubscription | null;
|
|
41
41
|
onOcrSuccess(callback: (data: SDKEkycResultStringWithEvent) => void): EmitterSubscription | null;
|
|
42
42
|
onOcrError(callback: (error: any) => void): EmitterSubscription | null;
|
|
43
|
-
onLivenessSuccess(callback: (data:
|
|
43
|
+
onLivenessSuccess(callback: (data: LivenessSuccessEvent) => void): EmitterSubscription | null;
|
|
44
44
|
onLivenessError(callback: (error: any) => void): EmitterSubscription | null;
|
|
45
|
-
onFaceCompareSuccess(callback: (data:
|
|
45
|
+
onFaceCompareSuccess(callback: (data: FaceCompareSuccessEvent) => void): EmitterSubscription | null;
|
|
46
46
|
onFaceCompareError(callback: (error: any) => void): EmitterSubscription | null;
|
|
47
47
|
onEkycUISuccess(callback: (data: any) => void): EmitterSubscription | null;
|
|
48
48
|
onEkycUIError(callback: (error: any) => void): EmitterSubscription | null;
|
package/dist/index.d.ts
CHANGED
|
@@ -9,9 +9,9 @@ export { SDKFlowType, SDK_FLOW_OPTIONS, flowToStrings } from './src/types/ekycFl
|
|
|
9
9
|
export type { NfcConfig, NFCData, NfcInfo } from './src/types/ekycNFCType';
|
|
10
10
|
export type { C06Config } from './src/types/ekycC06Type';
|
|
11
11
|
export type { OcrConfig } from './src/types/ekycOCRType';
|
|
12
|
-
export type { LivenessConfig } from './src/types/ekycLivenessType';
|
|
12
|
+
export type { LivenessConfig, LivenessSuccessEvent, CheckLivenessResponse, Metadata, LivenessCheckResult, Details, QualityChecks, QualityCheck, AgeRange, LiveFace } from './src/types/ekycLivenessType';
|
|
13
13
|
export { SDKFaceDetectStatus, SDK_LIVENESS_ACTIONS, customActionsToStrings } from './src/types/ekycLivenessType';
|
|
14
|
-
export type { FaceServiceConfig } from './src/types/ekycFaceType';
|
|
14
|
+
export type { FaceServiceConfig, FaceCompareSuccessEvent, CheckFaceResponse, FaceVerifyResult } from './src/types/ekycFaceType';
|
|
15
15
|
export { EKYCEvent, EKYCErrorEvent } from './src/types/EKYCEvent';
|
|
16
16
|
export type { SDKEkycResultWithEvent, SDKEkycResultStringWithEvent, StartEkycUIResult, EKYCError } from './src/types/ekycType';
|
|
17
17
|
export { getEkycError, AppIDType } from './src/types/ekycType';
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finos_sdk/sdk-ekyc",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.7",
|
|
4
4
|
"description": "React Native SDK for eKYC - Vietnamese CCCD NFC reading, OCR, Liveness detection, Face matching, and C06, eSign, SmsOTP residence verification",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -3,8 +3,8 @@ import { NfcConfig } from '../types/ekycNFCType';
|
|
|
3
3
|
import { SDKEkycResultWithEvent, SDKEkycResultStringWithEvent, EKYCError, AppIDType } from '../types/ekycType';
|
|
4
4
|
import { C06Config } from '../types/ekycC06Type';
|
|
5
5
|
import { OcrConfig } from '../types/ekycOCRType';
|
|
6
|
-
import { LivenessConfig, SDKFaceDetectStatus } from '../types/ekycLivenessType';
|
|
7
|
-
import { FaceServiceConfig } from '../types/ekycFaceType';
|
|
6
|
+
import { LivenessConfig, SDKFaceDetectStatus, LivenessSuccessEvent } from '../types/ekycLivenessType';
|
|
7
|
+
import { FaceServiceConfig, FaceCompareSuccessEvent } from '../types/ekycFaceType';
|
|
8
8
|
import { SmsOtpConfig, SmsOtpResult } from '../types/ekycSmsOtpType';
|
|
9
9
|
import { ESignInitResult, ESignOpenSessionResult, ESignCertificate, ESignSignRequest, ESignPdfResult, ESignApiResponse } from '../types/ekycESignType';
|
|
10
10
|
import { SDKFlowType } from '../types/ekycFlowType';
|
|
@@ -77,12 +77,12 @@ export declare class FinosEKYCModule {
|
|
|
77
77
|
* @param config.activeActionCount - Number of random actions (1-10), only used when customActions is null (default: 2)
|
|
78
78
|
* @param config.switchFrontCamera - Use front camera (default: false)
|
|
79
79
|
*/
|
|
80
|
-
startLiveness(config: LivenessConfig): Promise<
|
|
80
|
+
startLiveness(config: LivenessConfig): Promise<LivenessSuccessEvent>;
|
|
81
81
|
/**
|
|
82
82
|
* Start face comparison (Face Service)
|
|
83
83
|
* @param config Face service configuration
|
|
84
84
|
*/
|
|
85
|
-
startFaceCompare(config: FaceServiceConfig): Promise<
|
|
85
|
+
startFaceCompare(config: FaceServiceConfig): Promise<FaceCompareSuccessEvent>;
|
|
86
86
|
/**
|
|
87
87
|
* Extract NFC data for C06 verification
|
|
88
88
|
* @param nfcResultJson NFC result JSON string
|
|
@@ -134,7 +134,7 @@ export declare class FinosEKYCModule {
|
|
|
134
134
|
/**
|
|
135
135
|
* Listen for liveness success events
|
|
136
136
|
*/
|
|
137
|
-
onLivenessSuccess(callback: (data:
|
|
137
|
+
onLivenessSuccess(callback: (data: LivenessSuccessEvent) => void): import("react-native").EmitterSubscription | null;
|
|
138
138
|
/**
|
|
139
139
|
* Listen for liveness error events
|
|
140
140
|
*/
|
|
@@ -143,7 +143,7 @@ export declare class FinosEKYCModule {
|
|
|
143
143
|
/**
|
|
144
144
|
* Listen for face compare success events
|
|
145
145
|
*/
|
|
146
|
-
onFaceCompareSuccess(callback: (data:
|
|
146
|
+
onFaceCompareSuccess(callback: (data: FaceCompareSuccessEvent) => void): import("react-native").EmitterSubscription | null;
|
|
147
147
|
/** Payload là EKYCError: { event, code, message }. */
|
|
148
148
|
onFaceCompareError(callback: (error: EKYCError) => void): import("react-native").EmitterSubscription | null;
|
|
149
149
|
/**
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { SDK_VERSION, SDK_NAME } from '../../EKYCModule';
|
|
2
2
|
import { SmsOtpConfig, SmsOtpResult } from '../types/ekycSmsOtpType';
|
|
3
3
|
import { ESignInitResult, ESignOpenSessionResult, ESignCertificate, ESignSignRequest, AuthorizeInfo, ESignPdfResult, ESignApiResponse } from '../types/ekycESignType';
|
|
4
|
-
import { LivenessConfig } from '../types/ekycLivenessType';
|
|
5
|
-
import { FaceServiceConfig } from '../types/ekycFaceType';
|
|
6
|
-
import {
|
|
4
|
+
import { LivenessConfig, LivenessSuccessEvent } from '../types/ekycLivenessType';
|
|
5
|
+
import { FaceServiceConfig, FaceCompareSuccessEvent } from '../types/ekycFaceType';
|
|
6
|
+
import { EKYCError } from '../types/ekycType';
|
|
7
7
|
/**
|
|
8
8
|
* Finos eSign SDK Module
|
|
9
9
|
*
|
|
@@ -255,16 +255,16 @@ export declare class FinosESignModule {
|
|
|
255
255
|
* @param config.activeActionCount - Number of random actions (1-10), only used when customActions is null (default: 2)
|
|
256
256
|
* @param config.switchFrontCamera - Use front camera (default: false)
|
|
257
257
|
*/
|
|
258
|
-
startLiveness(config: LivenessConfig): Promise<
|
|
259
|
-
onLivenessSuccess(callback: (data:
|
|
258
|
+
startLiveness(config: LivenessConfig): Promise<LivenessSuccessEvent>;
|
|
259
|
+
onLivenessSuccess(callback: (data: LivenessSuccessEvent) => void): import("react-native").EmitterSubscription | null;
|
|
260
260
|
/** Payload là EKYCError: { event, code, message }. */
|
|
261
261
|
onLivenessError(callback: (error: EKYCError) => void): import("react-native").EmitterSubscription | null;
|
|
262
262
|
/**
|
|
263
263
|
* Face matching (Face Service)
|
|
264
264
|
* @param config Face service configuration
|
|
265
265
|
*/
|
|
266
|
-
startFaceCompare(config: FaceServiceConfig): Promise<
|
|
267
|
-
onFaceCompareSuccess(callback: (data:
|
|
266
|
+
startFaceCompare(config: FaceServiceConfig): Promise<FaceCompareSuccessEvent>;
|
|
267
|
+
onFaceCompareSuccess(callback: (data: FaceCompareSuccessEvent) => void): import("react-native").EmitterSubscription | null;
|
|
268
268
|
/** Payload là EKYCError: { event, code, message }. */
|
|
269
269
|
onFaceCompareError(callback: (error: EKYCError) => void): import("react-native").EmitterSubscription | null;
|
|
270
270
|
/**
|
|
@@ -12,6 +12,15 @@ export interface FaceVerifyResult {
|
|
|
12
12
|
matchScore?: number;
|
|
13
13
|
toBeReviewed?: string;
|
|
14
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Payload emitted by onFaceCompareSuccess listener.
|
|
17
|
+
* event = "FACE_SUCCESS" | "LOG_SUCCESS"
|
|
18
|
+
* data = CheckFaceResponse object (bridge serialises individual fields, not a JSON string)
|
|
19
|
+
*/
|
|
20
|
+
export interface FaceCompareSuccessEvent {
|
|
21
|
+
event: string;
|
|
22
|
+
data: CheckFaceResponse;
|
|
23
|
+
}
|
|
15
24
|
export interface FaceServiceConfig {
|
|
16
25
|
/**
|
|
17
26
|
* Backward/forward compatible:
|
|
@@ -97,3 +97,12 @@ export interface QualityCheck {
|
|
|
97
97
|
}
|
|
98
98
|
/** Liveness error – dùng chung EKYCError (event, code, message). */
|
|
99
99
|
export type LivenessError = import('./ekycType').EKYCError;
|
|
100
|
+
/**
|
|
101
|
+
* Payload emitted by onLivenessSuccess listener.
|
|
102
|
+
* event = "LIVENESS_SUCCESS" | "LOG_SUCCESS"
|
|
103
|
+
* data = CheckLivenessResponse object (bridge serialises fields directly, not a JSON string)
|
|
104
|
+
*/
|
|
105
|
+
export interface LivenessSuccessEvent {
|
|
106
|
+
event: string;
|
|
107
|
+
data: CheckLivenessResponse;
|
|
108
|
+
}
|
package/ios/EKYCModule.swift
CHANGED
|
@@ -184,8 +184,16 @@ class EKYCModule: RCTEventEmitter {
|
|
|
184
184
|
let ekycConfig = EKYCConfigSDK(appKey: AppKeyConfig(appKey: appKey), sdkType: .liveness, livenessConfig: livenessConfig)
|
|
185
185
|
SdkEkycLiveness.startEkyc(from: vc, ekycConfigSDK: ekycConfig,
|
|
186
186
|
callbackSuccess: { event, data in
|
|
187
|
-
let livenessResponse = (data as? SDKEkycResult)?.checkLivenessResponse
|
|
188
|
-
let
|
|
187
|
+
let livenessResponse = (data as? SDKEkycResult)?.checkLivenessResponse
|
|
188
|
+
let livenessDict: Any
|
|
189
|
+
if let resp = livenessResponse,
|
|
190
|
+
let encoded = try? JSONEncoder().encode(resp),
|
|
191
|
+
let dict = try? JSONSerialization.jsonObject(with: encoded) as? [String: Any] {
|
|
192
|
+
livenessDict = dict
|
|
193
|
+
} else {
|
|
194
|
+
livenessDict = [String: Any]()
|
|
195
|
+
}
|
|
196
|
+
let body: [String: Any] = ["event": event.description, "data": livenessDict]
|
|
189
197
|
self?.emit("onLivenessSuccess", body: body)
|
|
190
198
|
resolve(body)
|
|
191
199
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finos_sdk/sdk-ekyc",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.7",
|
|
4
4
|
"description": "React Native SDK for eKYC - Vietnamese CCCD NFC reading, OCR, Liveness detection, Face matching, and C06, eSign, SmsOTP residence verification",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -4,8 +4,8 @@ import { NfcConfig, NfcError } from '../types/ekycNFCType';
|
|
|
4
4
|
import { SDKEkycResultWithEvent, SDKEkycResultStringWithEvent, EKYCError, getEkycError, AppIDType } from '../types/ekycType';
|
|
5
5
|
import { C06Config } from '../types/ekycC06Type';
|
|
6
6
|
import { OcrConfig, OcrError } from '../types/ekycOCRType';
|
|
7
|
-
import { LivenessConfig, SDKFaceDetectStatus, LivenessError } from '../types/ekycLivenessType';
|
|
8
|
-
import { FaceServiceConfig, FaceCompareError } from '../types/ekycFaceType';
|
|
7
|
+
import { LivenessConfig, SDKFaceDetectStatus, LivenessError, LivenessSuccessEvent } from '../types/ekycLivenessType';
|
|
8
|
+
import { FaceServiceConfig, FaceCompareError, FaceCompareSuccessEvent } from '../types/ekycFaceType';
|
|
9
9
|
import { SmsOtpConfig, SmsOtpResult, SmsOtpError } from '../types/ekycSmsOtpType';
|
|
10
10
|
import { ESignInitResult, ESignOpenSessionResult, ESignCertificate, ESignSignRequest, ESignError, ESignAuthenticateResult, ESignPdfResult, ESignApiResponse } from '../types/ekycESignType';
|
|
11
11
|
import { SDKFlowType, flowToStrings } from '../types/ekycFlowType';
|
|
@@ -194,7 +194,7 @@ export class FinosEKYCModule {
|
|
|
194
194
|
* @param config.activeActionCount - Number of random actions (1-10), only used when customActions is null (default: 2)
|
|
195
195
|
* @param config.switchFrontCamera - Use front camera (default: false)
|
|
196
196
|
*/
|
|
197
|
-
public async startLiveness(config: LivenessConfig): Promise<
|
|
197
|
+
public async startLiveness(config: LivenessConfig): Promise<LivenessSuccessEvent> {
|
|
198
198
|
this.validateSDKReady();
|
|
199
199
|
|
|
200
200
|
try {
|
|
@@ -221,7 +221,7 @@ export class FinosEKYCModule {
|
|
|
221
221
|
* Start face comparison (Face Service)
|
|
222
222
|
* @param config Face service configuration
|
|
223
223
|
*/
|
|
224
|
-
public async startFaceCompare(config: FaceServiceConfig): Promise<
|
|
224
|
+
public async startFaceCompare(config: FaceServiceConfig): Promise<FaceCompareSuccessEvent> {
|
|
225
225
|
this.validateSDKReady();
|
|
226
226
|
|
|
227
227
|
const normalized: FaceServiceConfig = {
|
|
@@ -337,7 +337,7 @@ export class FinosEKYCModule {
|
|
|
337
337
|
/**
|
|
338
338
|
* Listen for liveness success events
|
|
339
339
|
*/
|
|
340
|
-
public onLivenessSuccess(callback: (data:
|
|
340
|
+
public onLivenessSuccess(callback: (data: LivenessSuccessEvent) => void) {
|
|
341
341
|
return this.sdk.onLivenessSuccess(callback);
|
|
342
342
|
}
|
|
343
343
|
|
|
@@ -352,7 +352,7 @@ export class FinosEKYCModule {
|
|
|
352
352
|
/**
|
|
353
353
|
* Listen for face compare success events
|
|
354
354
|
*/
|
|
355
|
-
public onFaceCompareSuccess(callback: (data:
|
|
355
|
+
public onFaceCompareSuccess(callback: (data: FaceCompareSuccessEvent) => void) {
|
|
356
356
|
return this.sdk.onFaceCompareSuccess(callback);
|
|
357
357
|
}
|
|
358
358
|
|
|
@@ -2,8 +2,8 @@ import { Platform } from 'react-native';
|
|
|
2
2
|
import sdkEKYC, { SDKeKYC, SDK_VERSION, SDK_NAME } from '../../EKYCModule';
|
|
3
3
|
import { SmsOtpConfig, SmsOtpResult, SmsOtpError } from '../types/ekycSmsOtpType';
|
|
4
4
|
import { ESignInitResult, ESignOpenSessionResult, ESignCertificate, ESignSignRequest, ESignError, ESignAuthenticateResult, AuthorizeInfo, ESignPdfResult, ESignApiResponse } from '../types/ekycESignType';
|
|
5
|
-
import { LivenessConfig, LivenessError } from '../types/ekycLivenessType';
|
|
6
|
-
import { FaceServiceConfig, FaceCompareError } from '../types/ekycFaceType';
|
|
5
|
+
import { LivenessConfig, LivenessError, LivenessSuccessEvent } from '../types/ekycLivenessType';
|
|
6
|
+
import { FaceServiceConfig, FaceCompareError, FaceCompareSuccessEvent } from '../types/ekycFaceType';
|
|
7
7
|
import { SDKEkycResultStringWithEvent, SDKEkycResultWithEvent, EKYCError, getEkycError } from '../types/ekycType';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -565,14 +565,14 @@ export class FinosESignModule {
|
|
|
565
565
|
* @param config.activeActionCount - Number of random actions (1-10), only used when customActions is null (default: 2)
|
|
566
566
|
* @param config.switchFrontCamera - Use front camera (default: false)
|
|
567
567
|
*/
|
|
568
|
-
public async startLiveness(config: LivenessConfig): Promise<
|
|
568
|
+
public async startLiveness(config: LivenessConfig): Promise<LivenessSuccessEvent> {
|
|
569
569
|
this.validateSDKReady();
|
|
570
570
|
// Pass through to SDK - error handling is done in EKYCModule.ts
|
|
571
571
|
return await this.sdk.startLiveness(config);
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
// Liveness Event Listeners
|
|
575
|
-
public onLivenessSuccess(callback: (data:
|
|
575
|
+
public onLivenessSuccess(callback: (data: LivenessSuccessEvent) => void) {
|
|
576
576
|
return this.sdk.onLivenessSuccess(callback);
|
|
577
577
|
}
|
|
578
578
|
|
|
@@ -587,7 +587,7 @@ export class FinosESignModule {
|
|
|
587
587
|
* Face matching (Face Service)
|
|
588
588
|
* @param config Face service configuration
|
|
589
589
|
*/
|
|
590
|
-
public async startFaceCompare(config: FaceServiceConfig): Promise<
|
|
590
|
+
public async startFaceCompare(config: FaceServiceConfig): Promise<FaceCompareSuccessEvent> {
|
|
591
591
|
this.validateSDKReady();
|
|
592
592
|
const normalized: FaceServiceConfig = {
|
|
593
593
|
...config,
|
|
@@ -598,7 +598,7 @@ export class FinosESignModule {
|
|
|
598
598
|
}
|
|
599
599
|
|
|
600
600
|
// Face Compare Event Listeners
|
|
601
|
-
public onFaceCompareSuccess(callback: (data:
|
|
601
|
+
public onFaceCompareSuccess(callback: (data: FaceCompareSuccessEvent) => void) {
|
|
602
602
|
return this.sdk.onFaceCompareSuccess(callback);
|
|
603
603
|
}
|
|
604
604
|
|
|
@@ -14,6 +14,16 @@ export interface FaceVerifyResult {
|
|
|
14
14
|
toBeReviewed?: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Payload emitted by onFaceCompareSuccess listener.
|
|
19
|
+
* event = "FACE_SUCCESS" | "LOG_SUCCESS"
|
|
20
|
+
* data = CheckFaceResponse object (bridge serialises individual fields, not a JSON string)
|
|
21
|
+
*/
|
|
22
|
+
export interface FaceCompareSuccessEvent {
|
|
23
|
+
event: string;
|
|
24
|
+
data: CheckFaceResponse;
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
export interface FaceServiceConfig {
|
|
18
28
|
/**
|
|
19
29
|
* Backward/forward compatible:
|
|
@@ -131,3 +131,13 @@ export interface QualityCheck {
|
|
|
131
131
|
|
|
132
132
|
/** Liveness error – dùng chung EKYCError (event, code, message). */
|
|
133
133
|
export type LivenessError = import('./ekycType').EKYCError;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Payload emitted by onLivenessSuccess listener.
|
|
137
|
+
* event = "LIVENESS_SUCCESS" | "LOG_SUCCESS"
|
|
138
|
+
* data = CheckLivenessResponse object (bridge serialises fields directly, not a JSON string)
|
|
139
|
+
*/
|
|
140
|
+
export interface LivenessSuccessEvent {
|
|
141
|
+
event: string;
|
|
142
|
+
data: CheckLivenessResponse;
|
|
143
|
+
}
|