@finos_sdk/sdk-ekyc 1.4.4 → 1.4.6
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/android/build.gradle +1 -1
- package/android/src/main/java/finos/sdk/ekyc/EKYCModule.kt +117 -22
- package/dist/EKYCModule.d.ts +12 -0
- package/dist/EKYCModule.js +36 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -3
- package/dist/package.json +1 -1
- package/dist/src/modules/FinosEKYCModule.d.ts +14 -0
- package/dist/src/modules/FinosEKYCModule.js +12 -0
- package/dist/src/modules/FinosESignModule.d.ts +2 -0
- package/dist/src/types/EKYCEvent.d.ts +60 -0
- package/dist/src/types/EKYCEvent.js +65 -0
- package/dist/src/types/ekycESignType.d.ts +2 -0
- package/dist/src/types/ekycLivenessType.d.ts +13 -0
- package/ios/EKYCModule.swift +25 -5
- package/package.json +1 -1
- package/src/modules/FinosEKYCModule.ts +20 -0
- package/src/modules/FinosESignModule.ts +2 -0
- package/src/types/EKYCEvent.ts +76 -0
- package/src/types/ekycESignType.ts +2 -0
- package/src/types/ekycLivenessType.ts +16 -1
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.6.1"
|
|
69
69
|
implementation("finos.sdk.ekyc:ekyc:$sdkVersion")
|
|
70
70
|
implementation("finos.sdk.ekyc:ekycui:$sdkVersion")
|
|
71
71
|
implementation("finos.sdk.ekyc:nfc:$sdkVersion")
|
|
@@ -2,6 +2,7 @@ package finos.sdk.ekyc
|
|
|
2
2
|
|
|
3
3
|
import android.R
|
|
4
4
|
import android.net.Uri
|
|
5
|
+
import com.google.gson.Gson
|
|
5
6
|
import android.os.Handler
|
|
6
7
|
import android.os.Looper
|
|
7
8
|
import android.util.Base64
|
|
@@ -26,6 +27,7 @@ import finos.sdk.core.model.sdk.config.AppKeyConfig
|
|
|
26
27
|
import finos.sdk.core.model.sdk.config.C06Config
|
|
27
28
|
import finos.sdk.core.model.sdk.config.EKYCConfigSDK
|
|
28
29
|
import finos.sdk.core.model.sdk.config.FaceServiceConfig
|
|
30
|
+
import finos.sdk.core.model.sdk.config.LivenessBackConfirmConfig
|
|
29
31
|
import finos.sdk.core.model.sdk.config.LivenessConfig
|
|
30
32
|
import finos.sdk.core.model.sdk.config.NfcConfig
|
|
31
33
|
import finos.sdk.core.model.sdk.config.OcrConfig
|
|
@@ -108,6 +110,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
108
110
|
Arguments.createMap().apply {
|
|
109
111
|
putInt("status", result.status)
|
|
110
112
|
putString("msg", result.msg)
|
|
113
|
+
result.errorCode?.let { putString("errorCode", it) }
|
|
111
114
|
result.data?.let { d ->
|
|
112
115
|
putMap("data", Arguments.createMap().apply {
|
|
113
116
|
d.sessionId?.let { putString("sessionId", it) }
|
|
@@ -130,6 +133,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
130
133
|
Arguments.createMap().apply {
|
|
131
134
|
putInt("status", result.status)
|
|
132
135
|
putString("msg", result.msg)
|
|
136
|
+
result.errorCode?.let { putString("errorCode", it) }
|
|
133
137
|
result.data?.let { d ->
|
|
134
138
|
putMap("data", Arguments.createMap().apply {
|
|
135
139
|
putString("transactionId", d.transactionId)
|
|
@@ -232,7 +236,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
232
236
|
val eventMap =
|
|
233
237
|
Arguments.createMap().apply {
|
|
234
238
|
putString("event", event.name.toString())
|
|
235
|
-
putString("data",
|
|
239
|
+
putString("data", Gson().toJson(data))
|
|
236
240
|
}
|
|
237
241
|
sendEvent("onNfcScanStart", eventMap)
|
|
238
242
|
}
|
|
@@ -257,7 +261,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
257
261
|
val eventMap =
|
|
258
262
|
Arguments.createMap().apply {
|
|
259
263
|
putString("event", event.name.toString())
|
|
260
|
-
putString("data",
|
|
264
|
+
putString("data", Gson().toJson(data))
|
|
261
265
|
}
|
|
262
266
|
sendEvent("onNfcEvent", eventMap)
|
|
263
267
|
}
|
|
@@ -311,18 +315,19 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
311
315
|
ekycConfigSDK = ekycConfig,
|
|
312
316
|
callbackSuccess = { event, data ->
|
|
313
317
|
Log.d(TAG, "✅ checkC06() success")
|
|
318
|
+
val c06Json = Gson().toJson((data as? SDKEkycResult)?.checkC06Response)
|
|
314
319
|
|
|
315
320
|
// Create separate maps for event and promise
|
|
316
321
|
val eventMap =
|
|
317
322
|
Arguments.createMap().apply {
|
|
318
323
|
putString("event", event.name.toString())
|
|
319
|
-
putString("data",
|
|
324
|
+
putString("data", c06Json)
|
|
320
325
|
}
|
|
321
326
|
|
|
322
327
|
val promiseMap =
|
|
323
328
|
Arguments.createMap().apply {
|
|
324
329
|
putString("event", event.name.toString())
|
|
325
|
-
putString("data",
|
|
330
|
+
putString("data", c06Json)
|
|
326
331
|
}
|
|
327
332
|
sendEvent("onC06Success", eventMap)
|
|
328
333
|
promise.resolve(promiseMap)
|
|
@@ -386,7 +391,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
386
391
|
Log.d(TAG, "✅ startOcr() success")
|
|
387
392
|
val (eventMap, promiseMap) = createSeparateMaps { map ->
|
|
388
393
|
map.putString("event", event.name.toString())
|
|
389
|
-
map.putString("data", (data as SDKEkycResult).ocrResponse
|
|
394
|
+
map.putString("data", Gson().toJson((data as SDKEkycResult).ocrResponse))
|
|
390
395
|
}
|
|
391
396
|
sendEvent("onOcrSuccess", eventMap)
|
|
392
397
|
promise.resolve(promiseMap)
|
|
@@ -425,6 +430,8 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
425
430
|
activeActionCount: Int?,
|
|
426
431
|
forceCaptureTimeout: Double?,
|
|
427
432
|
isActiveLivenessColor: Boolean?,
|
|
433
|
+
isShowBackConfirmation: Boolean?,
|
|
434
|
+
backConfirmConfigJson: String?,
|
|
428
435
|
promise: Promise
|
|
429
436
|
) {
|
|
430
437
|
Log.d(TAG, "▶️ startLiveness() called")
|
|
@@ -458,6 +465,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
458
465
|
null
|
|
459
466
|
}
|
|
460
467
|
|
|
468
|
+
val backConfirmConfig = parseBackConfirmConfig(backConfirmConfigJson)
|
|
461
469
|
val livenessConfig =
|
|
462
470
|
LivenessConfig(
|
|
463
471
|
isActiveLiveness = isActiveLiveness ?: false,
|
|
@@ -472,7 +480,9 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
472
480
|
activeActionCount = activeActionCount ?: 2,
|
|
473
481
|
forceCaptureTimeout = (forceCaptureTimeout ?: 0.0).toLong(),
|
|
474
482
|
selfieImage = imageFile,
|
|
475
|
-
transactionId = transactionId
|
|
483
|
+
transactionId = transactionId,
|
|
484
|
+
isShowBackConfirmation = isShowBackConfirmation ?: false,
|
|
485
|
+
backConfirmConfig = backConfirmConfig,
|
|
476
486
|
)
|
|
477
487
|
val ekycConfig =
|
|
478
488
|
EKYCConfigSDK(
|
|
@@ -483,10 +493,21 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
483
493
|
eKYCFinOSLiveness.startEkyc(
|
|
484
494
|
ekycConfigSDK = ekycConfig,
|
|
485
495
|
callbackSuccess = { event, data ->
|
|
496
|
+
// LOG_SUCCESS = internal submit result event (v1.4.6.1), don't resolve promise
|
|
497
|
+
if (event == EKYCEvent.LOG_SUCCESS) {
|
|
498
|
+
val logDataStr = data?.customData?.let { Gson().toJson(it) } ?: (data as? SDKEkycResult)?.checkLivenessResponse?.let { Gson().toJson(it) } ?: Gson().toJson(data)
|
|
499
|
+
Log.d(TAG, "LOG_SUCCESS [Liveness]: $logDataStr")
|
|
500
|
+
val logMap = Arguments.createMap().apply {
|
|
501
|
+
putString("event", event.name.toString())
|
|
502
|
+
putString("data", logDataStr)
|
|
503
|
+
}
|
|
504
|
+
sendEvent("onLivenessSuccess", logMap)
|
|
505
|
+
return@startEkyc
|
|
506
|
+
}
|
|
486
507
|
Log.d(TAG, "✅ startLiveness() success")
|
|
487
508
|
val (eventMap, promiseMap) = createSeparateMaps { map ->
|
|
488
509
|
map.putString("event", event.name.toString())
|
|
489
|
-
map.putString("data", (data as SDKEkycResult).checkLivenessResponse
|
|
510
|
+
map.putString("data", Gson().toJson((data as SDKEkycResult).checkLivenessResponse))
|
|
490
511
|
}
|
|
491
512
|
sendEvent("onLivenessSuccess", eventMap)
|
|
492
513
|
promise.resolve(promiseMap)
|
|
@@ -556,10 +577,37 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
556
577
|
eKYCFinOSFaceService.startEkyc(
|
|
557
578
|
ekycConfigSDK = ekycConfig,
|
|
558
579
|
callbackSuccess = { event, data ->
|
|
580
|
+
// LOG_SUCCESS = internal submit result event (v1.4.6.1), don't resolve promise
|
|
581
|
+
if (event == EKYCEvent.LOG_SUCCESS) {
|
|
582
|
+
val faceResponse = (data as? SDKEkycResult)?.checkFaceResponse
|
|
583
|
+
val logDataStr = data?.customData?.let { Gson().toJson(it) } ?: faceResponse?.let { Gson().toJson(it) } ?: "null"
|
|
584
|
+
Log.d(TAG, "LOG_SUCCESS [FaceCompare]: $logDataStr")
|
|
585
|
+
val logMap = Arguments.createMap().apply {
|
|
586
|
+
putString("event", event.name.toString())
|
|
587
|
+
putString("data", logDataStr)
|
|
588
|
+
}
|
|
589
|
+
sendEvent("onFaceCompareSuccess", logMap)
|
|
590
|
+
return@startEkyc
|
|
591
|
+
}
|
|
559
592
|
Log.d(TAG, "✅ startFaceCompare() success")
|
|
593
|
+
val faceResponse = (data as? SDKEkycResult)?.checkFaceResponse
|
|
560
594
|
val (eventMap, promiseMap) = createSeparateMaps { map ->
|
|
561
595
|
map.putString("event", event.name.toString())
|
|
562
|
-
|
|
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)
|
|
563
611
|
}
|
|
564
612
|
sendEvent("onFaceCompareSuccess", eventMap)
|
|
565
613
|
promise.resolve(promiseMap)
|
|
@@ -758,6 +806,9 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
758
806
|
else -> AppIDType.NONE
|
|
759
807
|
}
|
|
760
808
|
|
|
809
|
+
val isShowBackConfirmation = extractBooleanValue(optionConfigJson, "isShowBackConfirmation") ?: false
|
|
810
|
+
val backConfirmConfig = parseBackConfirmConfig(extractObjectJson(optionConfigJson, "backConfirmConfig"))
|
|
811
|
+
|
|
761
812
|
val livenessConfig = if (finalFlow.contains(SDKType.LIVENESS)) {
|
|
762
813
|
LivenessConfig(
|
|
763
814
|
isActiveLiveness = isActiveLiveness,
|
|
@@ -765,6 +816,8 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
765
816
|
isShowCameraFont = switchFrontCamera,
|
|
766
817
|
customActions = customActionsList?.takeIf { it.isNotEmpty() },
|
|
767
818
|
activeActionCount = activeActionCount,
|
|
819
|
+
isShowBackConfirmation = isShowBackConfirmation,
|
|
820
|
+
backConfirmConfig = backConfirmConfig,
|
|
768
821
|
)
|
|
769
822
|
} else null
|
|
770
823
|
|
|
@@ -782,6 +835,17 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
782
835
|
activity = currentActivity,
|
|
783
836
|
ekycConfigSDK = ekycConfigSDK,
|
|
784
837
|
callbackSuccess = { event, data ->
|
|
838
|
+
// LOG_SUCCESS = internal submit result event (v1.4.5), emit event only, don't resolve promise
|
|
839
|
+
if (event == EKYCEvent.LOG_SUCCESS) {
|
|
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
|
+
}
|
|
785
849
|
Log.d(TAG, "✅ startEkycUI() callback - event=${event.name}")
|
|
786
850
|
val result = data as? SDKEkycResult
|
|
787
851
|
val hasRealData = result?.ekycStateModel != null
|
|
@@ -798,7 +862,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
798
862
|
val (eventMap, promiseMap) = createSeparateMaps { map ->
|
|
799
863
|
map.putString("status", "success")
|
|
800
864
|
map.putString("event", event.name.toString())
|
|
801
|
-
map.putString("data",
|
|
865
|
+
map.putString("data", Gson().toJson(data))
|
|
802
866
|
map.putString("transactionId", ekycTransactionId)
|
|
803
867
|
ekycFiles?.imageFace?.absolutePath?.let { map.putString("imageFacePath", it) }
|
|
804
868
|
ekycFiles?.imageOcrFront?.absolutePath?.let { map.putString("imageOcrFrontPath", it) }
|
|
@@ -859,32 +923,42 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
859
923
|
private fun parseOptionConfig(optionConfigJson: String): OptionConfig {
|
|
860
924
|
return try {
|
|
861
925
|
if (optionConfigJson.isBlank() || optionConfigJson == "{}") {
|
|
862
|
-
|
|
863
|
-
OptionConfig(
|
|
864
|
-
baseUrl = null,
|
|
865
|
-
countMaxRetry = 3,
|
|
866
|
-
language = null
|
|
867
|
-
)
|
|
926
|
+
OptionConfig()
|
|
868
927
|
} else {
|
|
869
|
-
// Simple JSON parsing (in real implementation, use proper JSON library)
|
|
870
928
|
val baseUrl = extractStringValue(optionConfigJson, "baseUrl")
|
|
871
929
|
val countMaxRetry = extractIntValue(optionConfigJson, "countMaxRetry") ?: 3
|
|
872
930
|
val language = extractStringValue(optionConfigJson, "language")
|
|
931
|
+
val networkTimeoutMs = extractLongValue(optionConfigJson, "networkTimeoutMs") ?: 30_000L
|
|
873
932
|
|
|
874
933
|
OptionConfig(
|
|
875
934
|
baseUrl = baseUrl,
|
|
876
935
|
countMaxRetry = countMaxRetry,
|
|
877
|
-
language = language
|
|
936
|
+
language = language,
|
|
937
|
+
networkTimeoutMs = networkTimeoutMs,
|
|
878
938
|
)
|
|
879
939
|
}
|
|
880
940
|
} catch (e: Exception) {
|
|
881
941
|
Log.e(TAG, "Error parsing optionConfig: ${e.message}", e)
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
942
|
+
OptionConfig()
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
private fun parseBackConfirmConfig(json: String?): LivenessBackConfirmConfig? {
|
|
947
|
+
if (json.isNullOrBlank() || json == "{}") return null
|
|
948
|
+
return try {
|
|
949
|
+
LivenessBackConfirmConfig(
|
|
950
|
+
titleVi = extractStringValue(json, "titleVi"),
|
|
951
|
+
titleEn = extractStringValue(json, "titleEn"),
|
|
952
|
+
bodyVi = extractStringValue(json, "bodyVi"),
|
|
953
|
+
bodyEn = extractStringValue(json, "bodyEn"),
|
|
954
|
+
confirmButtonVi = extractStringValue(json, "confirmButtonVi"),
|
|
955
|
+
confirmButtonEn = extractStringValue(json, "confirmButtonEn"),
|
|
956
|
+
cancelButtonVi = extractStringValue(json, "cancelButtonVi"),
|
|
957
|
+
cancelButtonEn = extractStringValue(json, "cancelButtonEn"),
|
|
887
958
|
)
|
|
959
|
+
} catch (e: Exception) {
|
|
960
|
+
Log.e(TAG, "Error parsing backConfirmConfig: ${e.message}", e)
|
|
961
|
+
null
|
|
888
962
|
}
|
|
889
963
|
}
|
|
890
964
|
|
|
@@ -898,6 +972,16 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
898
972
|
}
|
|
899
973
|
}
|
|
900
974
|
|
|
975
|
+
private fun extractLongValue(json: String, key: String): Long? {
|
|
976
|
+
return try {
|
|
977
|
+
val pattern = "\"$key\"\\s*:\\s*(-?\\d+)".toRegex()
|
|
978
|
+
val match = pattern.find(json)
|
|
979
|
+
match?.groupValues?.get(1)?.toLong()
|
|
980
|
+
} catch (e: Exception) {
|
|
981
|
+
null
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
901
985
|
private fun extractBooleanValue(json: String, key: String): Boolean? {
|
|
902
986
|
return try {
|
|
903
987
|
val pattern = "\"$key\"\\s*:\\s*(true|false)".toRegex()
|
|
@@ -1052,6 +1136,17 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
|
|
|
1052
1136
|
}
|
|
1053
1137
|
}
|
|
1054
1138
|
|
|
1139
|
+
/** Extract a nested JSON object `{ ... }` for a given key. Returns the raw JSON string or null. */
|
|
1140
|
+
private fun extractObjectJson(json: String, key: String): String? {
|
|
1141
|
+
return try {
|
|
1142
|
+
val obj = JSONObject(json)
|
|
1143
|
+
val nested = obj.optJSONObject(key) ?: return null
|
|
1144
|
+
nested.toString()
|
|
1145
|
+
} catch (e: Exception) {
|
|
1146
|
+
null
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1055
1150
|
// ==================== SMS OTP Methods ====================
|
|
1056
1151
|
|
|
1057
1152
|
@ReactMethod
|
package/dist/EKYCModule.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ declare class SDKeKYC {
|
|
|
44
44
|
onLivenessError(callback: (error: any) => void): EmitterSubscription | null;
|
|
45
45
|
onFaceCompareSuccess(callback: (data: SDKEkycResultWithEvent) => void): EmitterSubscription | null;
|
|
46
46
|
onFaceCompareError(callback: (error: any) => void): EmitterSubscription | null;
|
|
47
|
+
onEkycUISuccess(callback: (data: any) => void): EmitterSubscription | null;
|
|
48
|
+
onEkycUIError(callback: (error: any) => void): EmitterSubscription | null;
|
|
47
49
|
removeAllListeners(): void;
|
|
48
50
|
sendOtp(config: SmsOtpConfig): Promise<SmsOtpResult>;
|
|
49
51
|
verifyOtp(config: SmsOtpConfig, otpCode: string): Promise<SmsOtpResult>;
|
|
@@ -146,6 +148,16 @@ declare class SDKeKYC {
|
|
|
146
148
|
baseUrl?: string;
|
|
147
149
|
countMaxRetry?: number;
|
|
148
150
|
language?: string;
|
|
151
|
+
networkTimeoutMs?: number;
|
|
152
|
+
switchFrontCamera?: boolean;
|
|
153
|
+
isActiveLiveness?: boolean;
|
|
154
|
+
autoCapture?: boolean;
|
|
155
|
+
forceCaptureTimeout?: number;
|
|
156
|
+
customActions?: string[];
|
|
157
|
+
activeActionCount?: number;
|
|
158
|
+
appIDType?: string;
|
|
159
|
+
isShowBackConfirmation?: boolean;
|
|
160
|
+
backConfirmConfig?: import('./src/types/ekycLivenessType').LivenessBackConfirmConfig;
|
|
149
161
|
}, styleConfig?: {
|
|
150
162
|
textSize?: number;
|
|
151
163
|
textFont?: string;
|
package/dist/EKYCModule.js
CHANGED
|
@@ -213,7 +213,10 @@ class SDKeKYC {
|
|
|
213
213
|
try {
|
|
214
214
|
// Convert SDKFaceDetectStatus enum array to string array
|
|
215
215
|
const customActionsStrings = (_b = (_a = config.customActions) === null || _a === void 0 ? void 0 : _a.map(action => String(action))) !== null && _b !== void 0 ? _b : undefined;
|
|
216
|
-
|
|
216
|
+
const backConfirmConfigJson = config.backConfirmConfig
|
|
217
|
+
? JSON.stringify(config.backConfirmConfig)
|
|
218
|
+
: undefined;
|
|
219
|
+
return await nativeModule.startLiveness(config.appKey, config.selfieImage, (_c = config.transactionId) !== null && _c !== void 0 ? _c : '', config.isActiveLiveness, config.isShowCameraFont, customActionsStrings, config.activeActionCount, config.forceCaptureTimeout, config.isActiveLivenessColor, config.isShowBackConfirmation, backConfirmConfigJson);
|
|
217
220
|
}
|
|
218
221
|
catch (error) {
|
|
219
222
|
console.error('Liveness Error:', error);
|
|
@@ -420,6 +423,38 @@ class SDKeKYC {
|
|
|
420
423
|
return null;
|
|
421
424
|
}
|
|
422
425
|
}
|
|
426
|
+
onEkycUISuccess(callback) {
|
|
427
|
+
try {
|
|
428
|
+
const emitter = this.ensureEventEmitter();
|
|
429
|
+
if (!emitter) {
|
|
430
|
+
console.error('❌ Event emitter not available for onEkycUISuccess');
|
|
431
|
+
return null;
|
|
432
|
+
}
|
|
433
|
+
const listener = emitter.addListener('onEkycUISuccess', callback);
|
|
434
|
+
this.listeners.push(listener);
|
|
435
|
+
return listener;
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
console.error('Failed to add onEkycUISuccess listener:', error);
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
onEkycUIError(callback) {
|
|
443
|
+
try {
|
|
444
|
+
const emitter = this.ensureEventEmitter();
|
|
445
|
+
if (!emitter) {
|
|
446
|
+
console.error('❌ Event emitter not available for onEkycUIError');
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
const listener = emitter.addListener('onEkycUIError', callback);
|
|
450
|
+
this.listeners.push(listener);
|
|
451
|
+
return listener;
|
|
452
|
+
}
|
|
453
|
+
catch (error) {
|
|
454
|
+
console.error('Failed to add onEkycUIError listener:', error);
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
423
458
|
removeAllListeners() {
|
|
424
459
|
this.listeners.forEach(listener => listener.remove());
|
|
425
460
|
this.listeners = [];
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type { OcrConfig } from './src/types/ekycOCRType';
|
|
|
12
12
|
export type { LivenessConfig } from './src/types/ekycLivenessType';
|
|
13
13
|
export { SDKFaceDetectStatus, SDK_LIVENESS_ACTIONS, customActionsToStrings } from './src/types/ekycLivenessType';
|
|
14
14
|
export type { FaceServiceConfig } from './src/types/ekycFaceType';
|
|
15
|
+
export { EKYCEvent, EKYCErrorEvent } from './src/types/EKYCEvent';
|
|
15
16
|
export type { SDKEkycResultWithEvent, SDKEkycResultStringWithEvent, StartEkycUIResult, EKYCError } from './src/types/ekycType';
|
|
16
17
|
export { getEkycError, AppIDType } from './src/types/ekycType';
|
|
17
18
|
export type { NfcError } from './src/types/ekycNFCType';
|
package/dist/index.js
CHANGED
|
@@ -33,9 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
37
|
-
exports.
|
|
38
|
-
exports.SDK_NAME = exports.SDK_VERSION = exports.USER_CANCEL = exports.ESIGN_INVALID_PIN_CODE = exports.ESIGN_INVALID_RECOVERY_CODE = exports.ESIGN_INVALID_LICENSE_CODE = exports.ESIGN_INVALID_CONTEXT = exports.ESIGN_MISSING_REQUEST_ID = exports.ESIGN_MISSING_SERIAL = exports.ESIGN_MISSING_IDENTITY = exports.ESIGN_MISSING_ACCESS_TOKEN = exports.ESIGN_NO_SESSION_ID = exports.ESIGN_MISSING_CONFIRMATION_DOC = exports.ESIGN_MISSING_REQUEST_JSON = exports.ESIGN_MISSING_CCCD = exports.ESIGN_MISSING_TOKEN = exports.ESIGN_ERROR_UNKNOWN = exports.ESIGN_AUTH_REQUEST_EXISTS = exports.ESIGN_INVALID_CERT_FOR_AUTH = exports.ESIGN_INVALID_SIGN_COUNT_OR_TIME = exports.ESIGN_AUTH_EXISTS = exports.ESIGN_SESSION_INVALID_LIST_CERT = void 0;
|
|
36
|
+
exports.OCR_USE_NEW_ID_DOCUMENT_2 = exports.OCR_USE_NEW_ID_DOCUMENT_1 = exports.OCR_FAKE_MRZ = exports.OCR_INVALID_GENDER_CODE = exports.OCR_INVALID_ID_CARD = exports.OCR_GLARE_ID_CARD = exports.OCR_BLURRY_ID_CARD = exports.OCR_CUT_CORNER_ID_CARD = exports.OCR_CANNOT_RECOGNIZE_PORTRAIT = exports.OCR_ID_CARD_FROM_OTHER_DEVICE = exports.OCR_NOT_ORIGINAL_ID_CARD = exports.OCR_MISSING_ID_CARD_PART = exports.OCR_CANNOT_GET_ISSUE_PLACE = exports.OCR_CANNOT_GET_GENDER = exports.OCR_CANNOT_GET_HOMETOWN = exports.OCR_CANNOT_GET_RESIDENCE = exports.OCR_CANNOT_GET_ISSUE_DATE = exports.OCR_CANNOT_GET_EXPIRY_DATE = exports.OCR_CANNOT_GET_BIRTH_YEAR = exports.OCR_CANNOT_GET_NAME = exports.OCR_CANNOT_GET_ID_NUMBER = exports.OCR_WRONG_ID_CARD_SIDE = exports.OCR_UNRECOGNIZED_ID_CARD = exports.SDK_MISS_KEY = exports.ERROR_UNKNOWN = exports.SDK_START_ERROR = exports.SDK_START_FLOW_ERROR = exports.getMessage = exports.getErrorResultFromDetails = exports.createCustom = exports.fromCode = exports.getLocalizedMessage = exports.parseNfcResponse = exports.AuthorizationStatus = exports.AppIDType = exports.getEkycError = exports.EKYCErrorEvent = exports.EKYCEvent = exports.customActionsToStrings = exports.SDK_LIVENESS_ACTIONS = exports.SDKFaceDetectStatus = exports.flowToStrings = exports.SDK_FLOW_OPTIONS = exports.SDKFlowType = exports.FinosESignModule = exports.FinosESign = exports.FinosEKYCModule = exports.FinosEKYC = exports.SDKeKYC = exports.sdkEKYC = void 0;
|
|
37
|
+
exports.ESIGN_INVALID_USER_ACCOUNT = exports.ESIGN_APP_LIMITED = exports.ESIGN_DEVICE_NOT_INIT = exports.ESIGN_INVALID_LICENSE_CONTENT = exports.ESIGN_INVALID_LICENSE = exports.ESIGN_DEVICE_ALREADY_INIT = exports.ESIGN_SESSION_INVALID = exports.FETCH_HISTORY_ERROR = exports.QRCODE_ERROR = exports.SMS_OTP_RATE_LIMIT = exports.SMS_OTP_NOT_FOUND = exports.SMS_OTP_MAX_ATTEMPTS = exports.SMS_OTP_INVALID_PHONE = exports.SMS_OTP_ERROR = exports.NFC_CHIP_AUTH_FAILED = exports.NFC_USER_CANCEL = exports.NFC_UNKNOWN_ERROR = exports.NFC_IO_ERROR = exports.NFC_INVALID_MRZ_KEY = exports.NFC_CONNECTION_LOST = exports.NFC_MUTUAL_AUTH_FAILED = exports.C06_ERROR = exports.SCAN_NFC_ENABLE = exports.SCAN_NFC_CHECK = exports.SCAN_NFC_ERROR = exports.HEAD_IS_TURNED_IN_SELFIE = exports.NUDITY_DETECTED_IN_SELFIE = exports.READING_GLASSES_DETECTED_IN_SELFIE = exports.EYEWEAR_DETECTED_IN_SELFIE = exports.FACE_OCCLUDED_IN_SELFIE = exports.FACE_IS_BLURRED = exports.MASK_PRESENT_IN_SELFIE = exports.EYES_CLOSED_IN_SELFIE = exports.MULTIPLE_FACES_IN_SELFIE = exports.LIVENESS_FAIL = exports.LIVENESS_ERROR = exports.FACE_ERROR = exports.FACE_HAT_ERROR = exports.OCR_ERROR = exports.OCR_FONT_BACK_NOT_MATCH = exports.OCR_PHOTOCOPY_ID_CARD = exports.OCR_FAKE_PORTRAIT_DETECTED = exports.OCR_FAKE_CHARACTERS_DETECTED_2 = exports.OCR_FAKE_CHARACTERS_DETECTED_1 = exports.OCR_UNKNOWN_ID_NUMBER_LENGTH = exports.OCR_MODIFIED_BIRTH_DATE_DETECTED_CMND = exports.OCR_MODIFIED_SYMBOL_DETECTED_CMND = exports.OCR_FAKE_BIRTH_DATE_DETECTED_CMND = exports.OCR_FAKE_PORTRAIT_DETECTED_CMND = exports.OCR_FAKE_CHARACTERS_DETECTED_CMND = void 0;
|
|
38
|
+
exports.SDK_NAME = exports.SDK_VERSION = exports.USER_CANCEL = exports.ESIGN_INVALID_PIN_CODE = exports.ESIGN_INVALID_RECOVERY_CODE = exports.ESIGN_INVALID_LICENSE_CODE = exports.ESIGN_INVALID_CONTEXT = exports.ESIGN_MISSING_REQUEST_ID = exports.ESIGN_MISSING_SERIAL = exports.ESIGN_MISSING_IDENTITY = exports.ESIGN_MISSING_ACCESS_TOKEN = exports.ESIGN_NO_SESSION_ID = exports.ESIGN_MISSING_CONFIRMATION_DOC = exports.ESIGN_MISSING_REQUEST_JSON = exports.ESIGN_MISSING_CCCD = exports.ESIGN_MISSING_TOKEN = exports.ESIGN_ERROR_UNKNOWN = exports.ESIGN_AUTH_REQUEST_EXISTS = exports.ESIGN_INVALID_CERT_FOR_AUTH = exports.ESIGN_INVALID_SIGN_COUNT_OR_TIME = exports.ESIGN_AUTH_EXISTS = exports.ESIGN_SESSION_INVALID_LIST_CERT = exports.ESIGN_INVALID_RECOVERY_OR_PIN = exports.ESIGN_SESSION_INVALID_REGISTER = void 0;
|
|
39
39
|
const EKYCModule_1 = __importStar(require("./EKYCModule"));
|
|
40
40
|
exports.sdkEKYC = EKYCModule_1.default;
|
|
41
41
|
Object.defineProperty(exports, "SDKeKYC", { enumerable: true, get: function () { return EKYCModule_1.SDKeKYC; } });
|
|
@@ -59,6 +59,10 @@ var ekycLivenessType_1 = require("./src/types/ekycLivenessType");
|
|
|
59
59
|
Object.defineProperty(exports, "SDKFaceDetectStatus", { enumerable: true, get: function () { return ekycLivenessType_1.SDKFaceDetectStatus; } });
|
|
60
60
|
Object.defineProperty(exports, "SDK_LIVENESS_ACTIONS", { enumerable: true, get: function () { return ekycLivenessType_1.SDK_LIVENESS_ACTIONS; } });
|
|
61
61
|
Object.defineProperty(exports, "customActionsToStrings", { enumerable: true, get: function () { return ekycLivenessType_1.customActionsToStrings; } });
|
|
62
|
+
// Export event enums (port of Android EKYCEvent.kt & EKYCErrorEvent.kt)
|
|
63
|
+
var EKYCEvent_1 = require("./src/types/EKYCEvent");
|
|
64
|
+
Object.defineProperty(exports, "EKYCEvent", { enumerable: true, get: function () { return EKYCEvent_1.EKYCEvent; } });
|
|
65
|
+
Object.defineProperty(exports, "EKYCErrorEvent", { enumerable: true, get: function () { return EKYCEvent_1.EKYCErrorEvent; } });
|
|
62
66
|
var ekycType_1 = require("./src/types/ekycType");
|
|
63
67
|
Object.defineProperty(exports, "getEkycError", { enumerable: true, get: function () { return ekycType_1.getEkycError; } });
|
|
64
68
|
Object.defineProperty(exports, "AppIDType", { enumerable: true, get: function () { return ekycType_1.AppIDType; } });
|
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.6",
|
|
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",
|
|
@@ -146,6 +146,14 @@ export declare class FinosEKYCModule {
|
|
|
146
146
|
onFaceCompareSuccess(callback: (data: SDKEkycResultWithEvent) => 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
|
+
/**
|
|
150
|
+
* Listen for eKYC UI success events (including LOG_SUCCESS from Liveness/FaceService submit)
|
|
151
|
+
*/
|
|
152
|
+
onEkycUISuccess(callback: (data: any) => void): import("react-native").EmitterSubscription | null;
|
|
153
|
+
/**
|
|
154
|
+
* Listen for eKYC UI error events
|
|
155
|
+
*/
|
|
156
|
+
onEkycUIError(callback: (error: any) => void): import("react-native").EmitterSubscription | null;
|
|
149
157
|
/**
|
|
150
158
|
* Remove all event listeners
|
|
151
159
|
*/
|
|
@@ -300,6 +308,8 @@ export declare class FinosEKYCModule {
|
|
|
300
308
|
baseUrl?: string;
|
|
301
309
|
countMaxRetry?: number;
|
|
302
310
|
language?: string;
|
|
311
|
+
/** Network timeout in milliseconds (default: 30000). callTimeout = networkTimeoutMs * 2 */
|
|
312
|
+
networkTimeoutMs?: number;
|
|
303
313
|
switchFrontCamera?: boolean;
|
|
304
314
|
/** LivenessConfig – SDKeKYCActivity (157-169) */
|
|
305
315
|
isActiveLiveness?: boolean;
|
|
@@ -310,6 +320,10 @@ export declare class FinosEKYCModule {
|
|
|
310
320
|
activeActionCount?: number;
|
|
311
321
|
/** AppIDType: NONE | HD_BANK | VIKKI (default: AppIDType.NONE) */
|
|
312
322
|
appIDType?: AppIDType;
|
|
323
|
+
/** Show confirmation bottom sheet when user presses back in liveness screen (v1.4.6+) */
|
|
324
|
+
isShowBackConfirmation?: boolean;
|
|
325
|
+
/** Text config for the back confirmation bottom sheet (v1.4.6+) */
|
|
326
|
+
backConfirmConfig?: import('../types/ekycLivenessType').LivenessBackConfirmConfig;
|
|
313
327
|
}, styleConfig?: {
|
|
314
328
|
textSize?: number;
|
|
315
329
|
textFont?: string;
|
|
@@ -345,6 +345,18 @@ class FinosEKYCModule {
|
|
|
345
345
|
onFaceCompareError(callback) {
|
|
346
346
|
return this.sdk.onFaceCompareError(callback);
|
|
347
347
|
}
|
|
348
|
+
/**
|
|
349
|
+
* Listen for eKYC UI success events (including LOG_SUCCESS from Liveness/FaceService submit)
|
|
350
|
+
*/
|
|
351
|
+
onEkycUISuccess(callback) {
|
|
352
|
+
return this.sdk.onEkycUISuccess(callback);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Listen for eKYC UI error events
|
|
356
|
+
*/
|
|
357
|
+
onEkycUIError(callback) {
|
|
358
|
+
return this.sdk.onEkycUIError(callback);
|
|
359
|
+
}
|
|
348
360
|
/**
|
|
349
361
|
* Remove all event listeners
|
|
350
362
|
*/
|
|
@@ -286,6 +286,8 @@ export declare class FinosESignModule {
|
|
|
286
286
|
baseUrl?: string;
|
|
287
287
|
countMaxRetry?: number;
|
|
288
288
|
language?: string;
|
|
289
|
+
/** Network timeout in milliseconds (default: 30000). callTimeout = networkTimeoutMs * 2 */
|
|
290
|
+
networkTimeoutMs?: number;
|
|
289
291
|
switchFrontCamera?: boolean;
|
|
290
292
|
}, styleConfig?: {
|
|
291
293
|
textSize?: number;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native port of EkycNativeAndroid EKYCEvent.kt
|
|
3
|
+
* Enum các sự kiện SDK trả về qua callback, đồng bộ 1:1 với Android enum.
|
|
4
|
+
*
|
|
5
|
+
* @see EkycNativeAndroid/Module/SDKCore/src/main/java/finos/sdk/core/define/EKYCEvent.kt
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* EKYCEvent – tên event trả về từ native callback success.
|
|
9
|
+
* Giá trị string map chính xác với Android enum name.
|
|
10
|
+
*/
|
|
11
|
+
export declare enum EKYCEvent {
|
|
12
|
+
/** SDK khởi tạo thành công, activity/flow vừa mở. */
|
|
13
|
+
SDK_START_SUCCESS = "SDK_START_SUCCESS",
|
|
14
|
+
/** SDK flow hoàn thành, có data kết quả. */
|
|
15
|
+
SDK_END_SUCCESS = "SDK_END_SUCCESS",
|
|
16
|
+
/** Bắt đầu quét NFC (đang chờ thẻ). */
|
|
17
|
+
SCAN_NFC_START = "SCAN_NFC_START",
|
|
18
|
+
/** Quét NFC thành công, có dữ liệu thẻ. */
|
|
19
|
+
SCAN_NFC_SUCCESS = "SCAN_NFC_SUCCESS",
|
|
20
|
+
/** Xác minh C06 thành công. */
|
|
21
|
+
C06_SUCCESS = "C06_SUCCESS",
|
|
22
|
+
/** Liveness detection thành công. */
|
|
23
|
+
LIVENESS_SUCCESS = "LIVENESS_SUCCESS",
|
|
24
|
+
/** Face detection đang xử lý (progress). */
|
|
25
|
+
FACE_PROGRESS = "FACE_PROGRESS",
|
|
26
|
+
/** Face compare thành công. */
|
|
27
|
+
FACE_SUCCESS = "FACE_SUCCESS",
|
|
28
|
+
/** OCR xử lý thành công. */
|
|
29
|
+
OCR_SUCCESS = "OCR_SUCCESS",
|
|
30
|
+
/** QR Code quét thành công. */
|
|
31
|
+
QRCODE_SUCCESS = "QRCODE_SUCCESS",
|
|
32
|
+
/** Lấy lịch sử giao dịch thành công. */
|
|
33
|
+
FETCH_LATEST_TRANSACTION_SUCCESS = "FETCH_LATEST_TRANSACTION_SUCCESS",
|
|
34
|
+
/** Gửi SMS OTP thành công. */
|
|
35
|
+
SMS_OTP_SEND_SUCCESS = "SMS_OTP_SEND_SUCCESS",
|
|
36
|
+
/** Xác minh SMS OTP thành công. */
|
|
37
|
+
SMS_OTP_VERIFY_SUCCESS = "SMS_OTP_VERIFY_SUCCESS",
|
|
38
|
+
/** Gửi lại SMS OTP thành công. */
|
|
39
|
+
SMS_OTP_RESEND_SUCCESS = "SMS_OTP_RESEND_SUCCESS",
|
|
40
|
+
/** Kết quả NFC/Liveness/FaceService đã submit lên server thành công (v1.4.5). */
|
|
41
|
+
LOG_SUCCESS = "LOG_SUCCESS"
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* EKYCErrorEvent – tên event trả về từ native callback error.
|
|
45
|
+
* Đồng bộ với Android enum EKYCErrorEvent.
|
|
46
|
+
*
|
|
47
|
+
* @see EkycNativeAndroid/Module/SDKCore/src/main/java/finos/sdk/core/define/EKYCErrorEvent.kt
|
|
48
|
+
*/
|
|
49
|
+
export declare enum EKYCErrorEvent {
|
|
50
|
+
SDK_START_ERROR = "SDK_START_ERROR",
|
|
51
|
+
OCR_ERROR = "OCR_ERROR",
|
|
52
|
+
LIVENESS_ERROR = "LIVENESS_ERROR",
|
|
53
|
+
FACE_ERROR = "FACE_ERROR",
|
|
54
|
+
NFC_ERROR = "NFC_ERROR",
|
|
55
|
+
C06_ERROR = "C06_ERROR",
|
|
56
|
+
SDK_DETAIL = "SDK_DETAIL",
|
|
57
|
+
SMS_OTP_ERROR = "SMS_OTP_ERROR",
|
|
58
|
+
ESIGN_ERROR = "ESIGN_ERROR",
|
|
59
|
+
USER_CANCEL = "USER_CANCEL"
|
|
60
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* React Native port of EkycNativeAndroid EKYCEvent.kt
|
|
4
|
+
* Enum các sự kiện SDK trả về qua callback, đồng bộ 1:1 với Android enum.
|
|
5
|
+
*
|
|
6
|
+
* @see EkycNativeAndroid/Module/SDKCore/src/main/java/finos/sdk/core/define/EKYCEvent.kt
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.EKYCErrorEvent = exports.EKYCEvent = void 0;
|
|
10
|
+
/**
|
|
11
|
+
* EKYCEvent – tên event trả về từ native callback success.
|
|
12
|
+
* Giá trị string map chính xác với Android enum name.
|
|
13
|
+
*/
|
|
14
|
+
var EKYCEvent;
|
|
15
|
+
(function (EKYCEvent) {
|
|
16
|
+
/** SDK khởi tạo thành công, activity/flow vừa mở. */
|
|
17
|
+
EKYCEvent["SDK_START_SUCCESS"] = "SDK_START_SUCCESS";
|
|
18
|
+
/** SDK flow hoàn thành, có data kết quả. */
|
|
19
|
+
EKYCEvent["SDK_END_SUCCESS"] = "SDK_END_SUCCESS";
|
|
20
|
+
/** Bắt đầu quét NFC (đang chờ thẻ). */
|
|
21
|
+
EKYCEvent["SCAN_NFC_START"] = "SCAN_NFC_START";
|
|
22
|
+
/** Quét NFC thành công, có dữ liệu thẻ. */
|
|
23
|
+
EKYCEvent["SCAN_NFC_SUCCESS"] = "SCAN_NFC_SUCCESS";
|
|
24
|
+
/** Xác minh C06 thành công. */
|
|
25
|
+
EKYCEvent["C06_SUCCESS"] = "C06_SUCCESS";
|
|
26
|
+
/** Liveness detection thành công. */
|
|
27
|
+
EKYCEvent["LIVENESS_SUCCESS"] = "LIVENESS_SUCCESS";
|
|
28
|
+
/** Face detection đang xử lý (progress). */
|
|
29
|
+
EKYCEvent["FACE_PROGRESS"] = "FACE_PROGRESS";
|
|
30
|
+
/** Face compare thành công. */
|
|
31
|
+
EKYCEvent["FACE_SUCCESS"] = "FACE_SUCCESS";
|
|
32
|
+
/** OCR xử lý thành công. */
|
|
33
|
+
EKYCEvent["OCR_SUCCESS"] = "OCR_SUCCESS";
|
|
34
|
+
/** QR Code quét thành công. */
|
|
35
|
+
EKYCEvent["QRCODE_SUCCESS"] = "QRCODE_SUCCESS";
|
|
36
|
+
/** Lấy lịch sử giao dịch thành công. */
|
|
37
|
+
EKYCEvent["FETCH_LATEST_TRANSACTION_SUCCESS"] = "FETCH_LATEST_TRANSACTION_SUCCESS";
|
|
38
|
+
/** Gửi SMS OTP thành công. */
|
|
39
|
+
EKYCEvent["SMS_OTP_SEND_SUCCESS"] = "SMS_OTP_SEND_SUCCESS";
|
|
40
|
+
/** Xác minh SMS OTP thành công. */
|
|
41
|
+
EKYCEvent["SMS_OTP_VERIFY_SUCCESS"] = "SMS_OTP_VERIFY_SUCCESS";
|
|
42
|
+
/** Gửi lại SMS OTP thành công. */
|
|
43
|
+
EKYCEvent["SMS_OTP_RESEND_SUCCESS"] = "SMS_OTP_RESEND_SUCCESS";
|
|
44
|
+
/** Kết quả NFC/Liveness/FaceService đã submit lên server thành công (v1.4.5). */
|
|
45
|
+
EKYCEvent["LOG_SUCCESS"] = "LOG_SUCCESS";
|
|
46
|
+
})(EKYCEvent || (exports.EKYCEvent = EKYCEvent = {}));
|
|
47
|
+
/**
|
|
48
|
+
* EKYCErrorEvent – tên event trả về từ native callback error.
|
|
49
|
+
* Đồng bộ với Android enum EKYCErrorEvent.
|
|
50
|
+
*
|
|
51
|
+
* @see EkycNativeAndroid/Module/SDKCore/src/main/java/finos/sdk/core/define/EKYCErrorEvent.kt
|
|
52
|
+
*/
|
|
53
|
+
var EKYCErrorEvent;
|
|
54
|
+
(function (EKYCErrorEvent) {
|
|
55
|
+
EKYCErrorEvent["SDK_START_ERROR"] = "SDK_START_ERROR";
|
|
56
|
+
EKYCErrorEvent["OCR_ERROR"] = "OCR_ERROR";
|
|
57
|
+
EKYCErrorEvent["LIVENESS_ERROR"] = "LIVENESS_ERROR";
|
|
58
|
+
EKYCErrorEvent["FACE_ERROR"] = "FACE_ERROR";
|
|
59
|
+
EKYCErrorEvent["NFC_ERROR"] = "NFC_ERROR";
|
|
60
|
+
EKYCErrorEvent["C06_ERROR"] = "C06_ERROR";
|
|
61
|
+
EKYCErrorEvent["SDK_DETAIL"] = "SDK_DETAIL";
|
|
62
|
+
EKYCErrorEvent["SMS_OTP_ERROR"] = "SMS_OTP_ERROR";
|
|
63
|
+
EKYCErrorEvent["ESIGN_ERROR"] = "ESIGN_ERROR";
|
|
64
|
+
EKYCErrorEvent["USER_CANCEL"] = "USER_CANCEL";
|
|
65
|
+
})(EKYCErrorEvent || (exports.EKYCErrorEvent = EKYCErrorEvent = {}));
|
|
@@ -56,6 +56,7 @@ export interface ESignSignRequestConfirm {
|
|
|
56
56
|
export interface ESignApiResponse {
|
|
57
57
|
status: number;
|
|
58
58
|
msg: string;
|
|
59
|
+
errorCode?: string;
|
|
59
60
|
data?: {
|
|
60
61
|
sessionId?: string;
|
|
61
62
|
[key: string]: any;
|
|
@@ -69,6 +70,7 @@ export interface ESignApiResponse {
|
|
|
69
70
|
export interface ESignPdfResult {
|
|
70
71
|
status: number;
|
|
71
72
|
msg: string;
|
|
73
|
+
errorCode?: string;
|
|
72
74
|
data?: {
|
|
73
75
|
transactionId: string;
|
|
74
76
|
[key: string]: any;
|
|
@@ -20,6 +20,17 @@ export declare enum SDKFaceDetectStatus {
|
|
|
20
20
|
export declare const SDK_LIVENESS_ACTIONS: readonly SDKFaceDetectStatus[];
|
|
21
21
|
/** Chuyển customActions enum[] sang string[] khi gửi xuống native. */
|
|
22
22
|
export declare function customActionsToStrings(actions: SDKFaceDetectStatus[]): string[];
|
|
23
|
+
/** Text config for the back-press confirmation bottom sheet (v1.4.6+). All fields optional – fallback to built-in strings. */
|
|
24
|
+
export interface LivenessBackConfirmConfig {
|
|
25
|
+
titleVi?: string;
|
|
26
|
+
titleEn?: string;
|
|
27
|
+
bodyVi?: string;
|
|
28
|
+
bodyEn?: string;
|
|
29
|
+
confirmButtonVi?: string;
|
|
30
|
+
confirmButtonEn?: string;
|
|
31
|
+
cancelButtonVi?: string;
|
|
32
|
+
cancelButtonEn?: string;
|
|
33
|
+
}
|
|
23
34
|
export interface LivenessConfig {
|
|
24
35
|
appKey: string;
|
|
25
36
|
transactionId?: string;
|
|
@@ -30,6 +41,8 @@ export interface LivenessConfig {
|
|
|
30
41
|
customActions?: SDKFaceDetectStatus[];
|
|
31
42
|
activeActionCount?: number;
|
|
32
43
|
forceCaptureTimeout?: number;
|
|
44
|
+
isShowBackConfirmation?: boolean;
|
|
45
|
+
backConfirmConfig?: LivenessBackConfirmConfig;
|
|
33
46
|
}
|
|
34
47
|
export interface CheckLivenessResponse {
|
|
35
48
|
metadata?: Metadata;
|
package/ios/EKYCModule.swift
CHANGED
|
@@ -96,14 +96,14 @@ class EKYCModule: RCTEventEmitter {
|
|
|
96
96
|
callbackSuccess: { event, data in
|
|
97
97
|
switch event {
|
|
98
98
|
case .SCAN_NFC_START:
|
|
99
|
-
self?.emit("onNfcScanStart", body: ["event": event.description, "data":
|
|
99
|
+
self?.emit("onNfcScanStart", body: ["event": event.description, "data": (data as? SDKEkycResult)?.nfcResponse ?? "{}"])
|
|
100
100
|
case .SCAN_NFC_SUCCESS:
|
|
101
101
|
let nfcResponse = (data as? SDKEkycResult)?.nfcResponse ?? ""
|
|
102
102
|
let body: [String: Any] = ["event": event.description, "data": nfcResponse]
|
|
103
103
|
self?.emit("onNfcScanSuccess", body: body)
|
|
104
104
|
resolve(body)
|
|
105
105
|
default:
|
|
106
|
-
self?.emit("onNfcEvent", body: ["event": event.description, "data":
|
|
106
|
+
self?.emit("onNfcEvent", body: ["event": event.description, "data": (data as? SDKEkycResult)?.nfcResponse ?? "{}"])
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
callbackError: { event, errorResult in
|
|
@@ -123,7 +123,8 @@ class EKYCModule: RCTEventEmitter {
|
|
|
123
123
|
let ekycConfig = EKYCConfigSDK(appKey: AppKeyConfig(appKey: appKey), c06Config: c06Config)
|
|
124
124
|
SdkEkycC06.startEkyc(ekycConfigSDK: ekycConfig,
|
|
125
125
|
callbackSuccess: { [weak self] event, data in
|
|
126
|
-
let
|
|
126
|
+
let c06Response = (data as? SDKEkycResult)?.checkC06Response?.description ?? "{}"
|
|
127
|
+
let body: [String: Any] = ["event": event.description, "data": c06Response]
|
|
127
128
|
self?.emit("onC06Success", body: body)
|
|
128
129
|
resolve(body)
|
|
129
130
|
},
|
|
@@ -210,7 +211,17 @@ class EKYCModule: RCTEventEmitter {
|
|
|
210
211
|
DispatchQueue.main.async { [weak self] in
|
|
211
212
|
SdkEkycFaceService.startEkyc(ekycConfigSDK: ekycConfig,
|
|
212
213
|
callbackSuccess: { event, data in
|
|
213
|
-
let
|
|
214
|
+
let faceResponse = (data as? SDKEkycResult)?.checkFaceResponse
|
|
215
|
+
var faceDict: [String: Any] = [:]
|
|
216
|
+
if let v = faceResponse?.requestId { faceDict["requestId"] = v }
|
|
217
|
+
if let r = faceResponse?.result {
|
|
218
|
+
faceDict["result"] = ["conf": r.conf, "match": r.match, "matchScore": r.matchScore, "toBeReviewed": r.toBeReviewed]
|
|
219
|
+
}
|
|
220
|
+
if let v = faceResponse?.status { faceDict["status"] = v }
|
|
221
|
+
if let v = faceResponse?.statusCode { faceDict["statusCode"] = v }
|
|
222
|
+
if let v = faceResponse?.error { faceDict["error"] = v }
|
|
223
|
+
if let v = faceResponse?.type { faceDict["type"] = v }
|
|
224
|
+
let body: [String: Any] = ["event": event.description, "data": faceDict]
|
|
214
225
|
self?.emit("onFaceCompareSuccess", body: body)
|
|
215
226
|
resolve(body)
|
|
216
227
|
},
|
|
@@ -291,7 +302,16 @@ class EKYCModule: RCTEventEmitter {
|
|
|
291
302
|
return
|
|
292
303
|
}
|
|
293
304
|
let files = result?.ekycStateModel?.eKYCFileModel
|
|
294
|
-
var
|
|
305
|
+
var dataDict: [String: Any] = [:]
|
|
306
|
+
if let v = result?.nfcResponse { dataDict["nfcResponse"] = v }
|
|
307
|
+
if let v = result?.checkC06Response?.description { dataDict["checkC06Response"] = v }
|
|
308
|
+
if let v = result?.ocrResponse?.description { dataDict["ocrResponse"] = v }
|
|
309
|
+
if let v = result?.checkLivenessResponse?.description { dataDict["checkLivenessResponse"] = v }
|
|
310
|
+
if let v = result?.checkFaceResponse?.description { dataDict["checkFaceResponse"] = v }
|
|
311
|
+
if let v = result?.customData { dataDict["customData"] = v }
|
|
312
|
+
let dataJson = (try? JSONSerialization.data(withJSONObject: dataDict))
|
|
313
|
+
.flatMap { String(data: $0, encoding: .utf8) } ?? "{}"
|
|
314
|
+
var body: [String: Any] = ["status": "success", "event": event.description, "data": dataJson, "transactionId": result?.ekycStateModel?.transactionId ?? ""]
|
|
295
315
|
if let facePath = files?.imageFace { body["imageFacePath"] = facePath.path }
|
|
296
316
|
if let frontPath = files?.imageOcrFront { body["imageOcrFrontPath"] = frontPath.path }
|
|
297
317
|
if let backPath = files?.imageOcrBack { body["imageOcrBackPath"] = backPath.path }
|
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.6",
|
|
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",
|
|
@@ -361,6 +361,20 @@ export class FinosEKYCModule {
|
|
|
361
361
|
return this.sdk.onFaceCompareError(callback);
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
+
/**
|
|
365
|
+
* Listen for eKYC UI success events (including LOG_SUCCESS from Liveness/FaceService submit)
|
|
366
|
+
*/
|
|
367
|
+
public onEkycUISuccess(callback: (data: any) => void) {
|
|
368
|
+
return this.sdk.onEkycUISuccess(callback);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Listen for eKYC UI error events
|
|
373
|
+
*/
|
|
374
|
+
public onEkycUIError(callback: (error: any) => void) {
|
|
375
|
+
return this.sdk.onEkycUIError(callback);
|
|
376
|
+
}
|
|
377
|
+
|
|
364
378
|
/**
|
|
365
379
|
* Remove all event listeners
|
|
366
380
|
*/
|
|
@@ -750,6 +764,8 @@ export class FinosEKYCModule {
|
|
|
750
764
|
baseUrl?: string;
|
|
751
765
|
countMaxRetry?: number;
|
|
752
766
|
language?: string;
|
|
767
|
+
/** Network timeout in milliseconds (default: 30000). callTimeout = networkTimeoutMs * 2 */
|
|
768
|
+
networkTimeoutMs?: number;
|
|
753
769
|
switchFrontCamera?: boolean;
|
|
754
770
|
/** LivenessConfig – SDKeKYCActivity (157-169) */
|
|
755
771
|
isActiveLiveness?: boolean;
|
|
@@ -760,6 +776,10 @@ export class FinosEKYCModule {
|
|
|
760
776
|
activeActionCount?: number;
|
|
761
777
|
/** AppIDType: NONE | HD_BANK | VIKKI (default: AppIDType.NONE) */
|
|
762
778
|
appIDType?: AppIDType;
|
|
779
|
+
/** Show confirmation bottom sheet when user presses back in liveness screen (v1.4.6+) */
|
|
780
|
+
isShowBackConfirmation?: boolean;
|
|
781
|
+
/** Text config for the back confirmation bottom sheet (v1.4.6+) */
|
|
782
|
+
backConfirmConfig?: import('../types/ekycLivenessType').LivenessBackConfirmConfig;
|
|
763
783
|
},
|
|
764
784
|
styleConfig?: {
|
|
765
785
|
textSize?: number;
|
|
@@ -634,6 +634,8 @@ export class FinosESignModule {
|
|
|
634
634
|
baseUrl?: string;
|
|
635
635
|
countMaxRetry?: number;
|
|
636
636
|
language?: string;
|
|
637
|
+
/** Network timeout in milliseconds (default: 30000). callTimeout = networkTimeoutMs * 2 */
|
|
638
|
+
networkTimeoutMs?: number;
|
|
637
639
|
switchFrontCamera?: boolean;
|
|
638
640
|
},
|
|
639
641
|
styleConfig?: {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React Native port of EkycNativeAndroid EKYCEvent.kt
|
|
3
|
+
* Enum các sự kiện SDK trả về qua callback, đồng bộ 1:1 với Android enum.
|
|
4
|
+
*
|
|
5
|
+
* @see EkycNativeAndroid/Module/SDKCore/src/main/java/finos/sdk/core/define/EKYCEvent.kt
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* EKYCEvent – tên event trả về từ native callback success.
|
|
10
|
+
* Giá trị string map chính xác với Android enum name.
|
|
11
|
+
*/
|
|
12
|
+
export enum EKYCEvent {
|
|
13
|
+
/** SDK khởi tạo thành công, activity/flow vừa mở. */
|
|
14
|
+
SDK_START_SUCCESS = 'SDK_START_SUCCESS',
|
|
15
|
+
|
|
16
|
+
/** SDK flow hoàn thành, có data kết quả. */
|
|
17
|
+
SDK_END_SUCCESS = 'SDK_END_SUCCESS',
|
|
18
|
+
|
|
19
|
+
/** Bắt đầu quét NFC (đang chờ thẻ). */
|
|
20
|
+
SCAN_NFC_START = 'SCAN_NFC_START',
|
|
21
|
+
|
|
22
|
+
/** Quét NFC thành công, có dữ liệu thẻ. */
|
|
23
|
+
SCAN_NFC_SUCCESS = 'SCAN_NFC_SUCCESS',
|
|
24
|
+
|
|
25
|
+
/** Xác minh C06 thành công. */
|
|
26
|
+
C06_SUCCESS = 'C06_SUCCESS',
|
|
27
|
+
|
|
28
|
+
/** Liveness detection thành công. */
|
|
29
|
+
LIVENESS_SUCCESS = 'LIVENESS_SUCCESS',
|
|
30
|
+
|
|
31
|
+
/** Face detection đang xử lý (progress). */
|
|
32
|
+
FACE_PROGRESS = 'FACE_PROGRESS',
|
|
33
|
+
|
|
34
|
+
/** Face compare thành công. */
|
|
35
|
+
FACE_SUCCESS = 'FACE_SUCCESS',
|
|
36
|
+
|
|
37
|
+
/** OCR xử lý thành công. */
|
|
38
|
+
OCR_SUCCESS = 'OCR_SUCCESS',
|
|
39
|
+
|
|
40
|
+
/** QR Code quét thành công. */
|
|
41
|
+
QRCODE_SUCCESS = 'QRCODE_SUCCESS',
|
|
42
|
+
|
|
43
|
+
/** Lấy lịch sử giao dịch thành công. */
|
|
44
|
+
FETCH_LATEST_TRANSACTION_SUCCESS = 'FETCH_LATEST_TRANSACTION_SUCCESS',
|
|
45
|
+
|
|
46
|
+
/** Gửi SMS OTP thành công. */
|
|
47
|
+
SMS_OTP_SEND_SUCCESS = 'SMS_OTP_SEND_SUCCESS',
|
|
48
|
+
|
|
49
|
+
/** Xác minh SMS OTP thành công. */
|
|
50
|
+
SMS_OTP_VERIFY_SUCCESS = 'SMS_OTP_VERIFY_SUCCESS',
|
|
51
|
+
|
|
52
|
+
/** Gửi lại SMS OTP thành công. */
|
|
53
|
+
SMS_OTP_RESEND_SUCCESS = 'SMS_OTP_RESEND_SUCCESS',
|
|
54
|
+
|
|
55
|
+
/** Kết quả NFC/Liveness/FaceService đã submit lên server thành công (v1.4.5). */
|
|
56
|
+
LOG_SUCCESS = 'LOG_SUCCESS',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* EKYCErrorEvent – tên event trả về từ native callback error.
|
|
61
|
+
* Đồng bộ với Android enum EKYCErrorEvent.
|
|
62
|
+
*
|
|
63
|
+
* @see EkycNativeAndroid/Module/SDKCore/src/main/java/finos/sdk/core/define/EKYCErrorEvent.kt
|
|
64
|
+
*/
|
|
65
|
+
export enum EKYCErrorEvent {
|
|
66
|
+
SDK_START_ERROR = 'SDK_START_ERROR',
|
|
67
|
+
OCR_ERROR = 'OCR_ERROR',
|
|
68
|
+
LIVENESS_ERROR = 'LIVENESS_ERROR',
|
|
69
|
+
FACE_ERROR = 'FACE_ERROR',
|
|
70
|
+
NFC_ERROR = 'NFC_ERROR',
|
|
71
|
+
C06_ERROR = 'C06_ERROR',
|
|
72
|
+
SDK_DETAIL = 'SDK_DETAIL',
|
|
73
|
+
SMS_OTP_ERROR = 'SMS_OTP_ERROR',
|
|
74
|
+
ESIGN_ERROR = 'ESIGN_ERROR',
|
|
75
|
+
USER_CANCEL = 'USER_CANCEL',
|
|
76
|
+
}
|
|
@@ -64,6 +64,7 @@ export interface ESignSignRequestConfirm {
|
|
|
64
64
|
export interface ESignApiResponse {
|
|
65
65
|
status: number;
|
|
66
66
|
msg: string;
|
|
67
|
+
errorCode?: string;
|
|
67
68
|
data?: {
|
|
68
69
|
sessionId?: string;
|
|
69
70
|
[key: string]: any;
|
|
@@ -78,6 +79,7 @@ export interface ESignApiResponse {
|
|
|
78
79
|
export interface ESignPdfResult {
|
|
79
80
|
status: number;
|
|
80
81
|
msg: string;
|
|
82
|
+
errorCode?: string;
|
|
81
83
|
data?: {
|
|
82
84
|
transactionId: string;
|
|
83
85
|
[key: string]: any; // Cho phép các field động khác
|
|
@@ -38,11 +38,23 @@ export function customActionsToStrings(actions: SDKFaceDetectStatus[]): string[]
|
|
|
38
38
|
return actions.map(a => a as string);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/** Text config for the back-press confirmation bottom sheet (v1.4.6+). All fields optional – fallback to built-in strings. */
|
|
42
|
+
export interface LivenessBackConfirmConfig {
|
|
43
|
+
titleVi?: string;
|
|
44
|
+
titleEn?: string;
|
|
45
|
+
bodyVi?: string;
|
|
46
|
+
bodyEn?: string;
|
|
47
|
+
confirmButtonVi?: string;
|
|
48
|
+
confirmButtonEn?: string;
|
|
49
|
+
cancelButtonVi?: string;
|
|
50
|
+
cancelButtonEn?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
41
53
|
export interface LivenessConfig {
|
|
42
54
|
appKey: string;
|
|
43
55
|
transactionId?: string;
|
|
44
56
|
// old fields usingRandomAction and isStraight removed in 1.3.1
|
|
45
|
-
// usingRandomAction: boolean;
|
|
57
|
+
// usingRandomAction: boolean;
|
|
46
58
|
// isStraight: boolean;
|
|
47
59
|
selfieImage: string;
|
|
48
60
|
// New fields for version 1.3.0
|
|
@@ -52,6 +64,9 @@ export interface LivenessConfig {
|
|
|
52
64
|
customActions?: SDKFaceDetectStatus[];
|
|
53
65
|
activeActionCount?: number;
|
|
54
66
|
forceCaptureTimeout?: number;
|
|
67
|
+
// New fields for version 1.4.6
|
|
68
|
+
isShowBackConfirmation?: boolean;
|
|
69
|
+
backConfirmConfig?: LivenessBackConfirmConfig;
|
|
55
70
|
}
|
|
56
71
|
|
|
57
72
|
export interface CheckLivenessResponse {
|