@finos_sdk/sdk-ekyc 1.2.9 → 1.3.2

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.
@@ -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.2.9"
68
+ def sdkVersion = "1.3.2"
69
69
  implementation("finos.sdk.ekyc:ekyc:$sdkVersion")
70
70
  implementation("finos.sdk.ekyc:ekycui:$sdkVersion")
71
71
  implementation("finos.sdk.ekyc:nfc:$sdkVersion")
@@ -8,6 +8,7 @@ import com.facebook.react.bridge.Promise
8
8
  import com.facebook.react.bridge.ReactApplicationContext
9
9
  import com.facebook.react.bridge.ReactContextBaseJavaModule
10
10
  import com.facebook.react.bridge.ReactMethod
11
+ import com.facebook.react.bridge.ReadableArray
11
12
  import com.facebook.react.bridge.WritableArray
12
13
  import com.facebook.react.bridge.WritableMap
13
14
  import com.facebook.react.module.annotations.ReactModule
@@ -15,6 +16,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule
15
16
  import finos.sdk.c06.SdkEkycC06
16
17
  import finos.sdk.core.define.EKYCEvent
17
18
  import finos.sdk.core.define.SDKType
19
+ import finos.sdk.core.define.SDKFaceDetectStatus
18
20
  import finos.sdk.core.model.response.SDKEkycResult
19
21
  import finos.sdk.core.model.sdk.config.AppKeyConfig
20
22
  import finos.sdk.core.model.sdk.config.C06Config
@@ -35,7 +37,7 @@ import finos.sdk.ocr.SdkEkycOcr
35
37
  import finos.sdk.smsotp.SdkSmsOtpService
36
38
  import finos.sdk.core.model.sdk.config.SmsOtpConfig
37
39
  import vn.softdreams.easyca.sdk.SdkeSign
38
- import vn.softdreams.easyca.sdk.utils.UserEsignModel
40
+
39
41
  import org.json.JSONObject
40
42
  import java.io.File
41
43
  import java.io.FileOutputStream
@@ -330,10 +332,14 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
330
332
  fun startLiveness(
331
333
  appKey: String,
332
334
  selfieImage: String,
333
- usingRandomAction: Boolean,
334
335
  transactionId: String,
335
- isStraight: Boolean,
336
336
  switchFrontCamera: Boolean?,
337
+ useActiveLiveness: Boolean?,
338
+ autoCapture: Boolean?,
339
+ isShowCameraFont: Boolean?,
340
+ customActionsArray: ReadableArray?,
341
+ activeActionCount: Int?,
342
+ forceCaptureTimeout: Double?,
337
343
  promise: Promise
338
344
  ) {
339
345
  Log.d(TAG, "▶️ startLiveness() called")
@@ -350,13 +356,38 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
350
356
  return
351
357
  }
352
358
 
359
+ // Parse customActions from ReadableArray
360
+ val customActions: List<SDKFaceDetectStatus>? = if (customActionsArray != null && customActionsArray.size() > 0) {
361
+ val actions = mutableListOf<SDKFaceDetectStatus>()
362
+ for (i in 0 until customActionsArray.size()) {
363
+ val actionString = customActionsArray.getString(i)
364
+ when (actionString) {
365
+ "LEFT" -> actions.add(SDKFaceDetectStatus.LEFT)
366
+ "RIGHT" -> actions.add(SDKFaceDetectStatus.RIGHT)
367
+ "STRAIGHT" -> actions.add(SDKFaceDetectStatus.STRAIGHT)
368
+ else -> Log.w(TAG, "Unknown action: $actionString")
369
+ }
370
+ }
371
+ if (actions.isNotEmpty()) actions else null
372
+ } else {
373
+ null
374
+ }
375
+
353
376
  val livenessConfig =
354
377
  LivenessConfig(
378
+ isActiveLiveness = useActiveLiveness ?: false,
379
+ autoCapture = autoCapture ?: true,
380
+ isShowCameraFont = isShowCameraFont ?: (switchFrontCamera ?: true),
381
+ // Custom actions từ checkboxes (nếu có chọn)
382
+ // Nếu có actions được chọn → sử dụng customActions
383
+ // Nếu không có actions nào được chọn → sử dụng random actions với activeActionCount
384
+ customActions = customActions,
385
+ // Number of random actions (1-10), only used when customActions = null
386
+ // activeActionCount = 2 → 2 random actions + STRAIGHT
387
+ activeActionCount = activeActionCount ?: 2,
388
+ forceCaptureTimeout = (forceCaptureTimeout ?: 0.0).toLong(),
355
389
  selfieImage = imageFile,
356
- usingRandomAction = usingRandomAction,
357
- isStraight = isStraight,
358
- transactionId = transactionId,
359
- isShowCameraFont = switchFrontCamera ?: false
390
+ transactionId = transactionId
360
391
  )
361
392
  val ekycConfig =
362
393
  EKYCConfigSDK(
@@ -965,8 +996,8 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
965
996
  // ==================== eSign Methods ====================
966
997
 
967
998
  @ReactMethod
968
- fun initializeESign(promise: Promise) {
969
- Log.d(TAG, "▶️ initializeESign() called")
999
+ fun initializeESign(finosToken: String?, promise: Promise) {
1000
+ Log.d(TAG, "▶️ initializeESign() called with token: ${finosToken?.take(10)}...")
970
1001
  try {
971
1002
  val currentActivity = reactApplicationContext.currentActivity
972
1003
  if (currentActivity == null) {
@@ -977,6 +1008,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
977
1008
 
978
1009
  SdkeSign.initializeESign(
979
1010
  context = currentActivity,
1011
+ finosToken = finosToken,
980
1012
  callbackSuccess = { code, message ->
981
1013
  Log.d(TAG, "✅ initializeESign() success")
982
1014
  val (eventMap, promiseMap) = createSeparateMaps { map ->
@@ -990,11 +1022,11 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
990
1022
  Log.e(TAG, "❌ initializeESign() failed - Event: $event, Message: ${error.message}")
991
1023
  val errorMap = Arguments.createMap().apply {
992
1024
  putString("event", event.name.toString())
993
- putString("message", error.message)
994
- putString("code", error.code)
1025
+ putString("message", error.message ?: "")
1026
+ putString("code", error.code.toString())
995
1027
  }
996
1028
  sendEvent("onESignError", errorMap)
997
- promise.reject(event.name.toString(), error.message)
1029
+ promise.reject(event.name.toString(), error.message ?: "Unknown Error")
998
1030
  }
999
1031
  )
1000
1032
  } catch (e: Exception) {
@@ -1003,13 +1035,40 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1003
1035
  }
1004
1036
  }
1005
1037
 
1038
+ @ReactMethod
1039
+ fun getSdkToken(
1040
+ identity: String,
1041
+ name: String,
1042
+ deviceId: String,
1043
+ promise: Promise
1044
+ ) {
1045
+ Log.d(TAG, "▶️ getSdkToken() called")
1046
+ try {
1047
+ SdkeSign.getSdkToken(
1048
+ cccd = identity, // Map identity param to cccd
1049
+ name = name,
1050
+ deviceId = deviceId,
1051
+ callbackSuccess = { token ->
1052
+ Log.d(TAG, "✅ getSdkToken() success")
1053
+ promise.resolve(token)
1054
+ },
1055
+ callbackError = { event, error ->
1056
+ Log.e(TAG, "❌ getSdkToken() failed: $error")
1057
+ // error might be String or Object, toString() covers both
1058
+ promise.reject("GET_SDK_TOKEN_ERROR", error.toString())
1059
+ }
1060
+ )
1061
+ } catch (e: Exception) {
1062
+ Log.e(TAG, "❌ getSdkToken() exception: ${e.message}", e)
1063
+ promise.reject("ESIGN_EXCEPTION", e.message, e)
1064
+ }
1065
+ }
1066
+
1006
1067
  @ReactMethod
1007
1068
  fun openSessionId(
1008
1069
  accessToken: String?,
1009
1070
  username: String?,
1010
1071
  rememberMe: Boolean?,
1011
- userEsignModelJson: String?,
1012
- privateKeyFilePath: String?,
1013
1072
  promise: Promise
1014
1073
  ) {
1015
1074
  Log.d(TAG, "▶️ openSessionId() called")
@@ -1042,56 +1101,16 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1042
1101
  Log.e(TAG, "❌ openSessionId() failed - Event: $event, Message: ${error.message}")
1043
1102
  val errorMap = Arguments.createMap().apply {
1044
1103
  putString("event", event.name.toString())
1045
- putString("message", error.message)
1046
- putString("code", error.code)
1104
+ putString("message", error.message ?: "")
1105
+ putString("code", error.code.toString())
1047
1106
  }
1048
1107
  sendEvent("onESignError", errorMap)
1049
- promise.reject(event.name.toString(), error.message)
1050
- }
1051
- )
1052
- } else if (userEsignModelJson != null && privateKeyFilePath != null) {
1053
- // Option 2: Auto-create token from user info
1054
- val json = JSONObject(userEsignModelJson)
1055
- val userInfo = UserEsignModel(
1056
- cccd = json.getString("cccd"),
1057
- name = json.getString("name"),
1058
- device = json.optString("device", "Android"),
1059
- deviceId = json.optString("deviceId", android.provider.Settings.Secure.getString(
1060
- reactApplicationContext.contentResolver,
1061
- android.provider.Settings.Secure.ANDROID_ID
1062
- ) ?: "")
1063
- )
1064
-
1065
- SdkeSign.openSessionId(
1066
- context = currentActivity,
1067
- userEsignModel = userInfo,
1068
- privateKeyFilePath = privateKeyFilePath,
1069
- username = username ?: "",
1070
- rememberMe = rememberMe ?: false,
1071
- callbackSuccess = { deviceState, code, message ->
1072
- Log.d(TAG, "✅ openSessionId() success")
1073
- val (eventMap, promiseMap) = createSeparateMaps { map ->
1074
- map.putString("deviceState", deviceState)
1075
- map.putString("code", code.toString())
1076
- map.putString("message", message)
1077
- }
1078
- sendEvent("onESignOpenSessionSuccess", eventMap)
1079
- promise.resolve(promiseMap)
1080
- },
1081
- callbackError = { event, error ->
1082
- Log.e(TAG, "❌ openSessionId() failed - Event: $event, Message: ${error.message}")
1083
- val errorMap = Arguments.createMap().apply {
1084
- putString("event", event.name.toString())
1085
- putString("message", error.message)
1086
- putString("code", error.code)
1087
- }
1088
- sendEvent("onESignError", errorMap)
1089
- promise.reject(event.name.toString(), error.message)
1108
+ promise.reject(event.name.toString(), error.message ?: "Unknown Error")
1090
1109
  }
1091
1110
  )
1092
1111
  } else {
1093
1112
  Log.e(TAG, "❌ openSessionId() failed: Invalid parameters")
1094
- promise.reject("INVALID_PARAMS", "Either accessToken or (userEsignModelJson + privateKeyFilePath) must be provided")
1113
+ promise.reject("INVALID_PARAMS", "accessToken must be provided")
1095
1114
  }
1096
1115
  } catch (e: Exception) {
1097
1116
  Log.e(TAG, "❌ openSessionId() exception: ${e.message}", e)
@@ -1133,11 +1152,11 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1133
1152
  Log.e(TAG, "❌ registerDevice() failed - Event: $event, Message: ${error.message}")
1134
1153
  val errorMap = Arguments.createMap().apply {
1135
1154
  putString("event", event.name.toString())
1136
- putString("message", error.message)
1137
- putString("code", error.code)
1155
+ putString("message", error.message ?: "")
1156
+ putString("code", error.code.toString())
1138
1157
  }
1139
1158
  sendEvent("onESignError", errorMap)
1140
- promise.reject(event.name.toString(), error.message)
1159
+ promise.reject(event.name.toString(), error.message ?: "Unknown Error")
1141
1160
  }
1142
1161
  )
1143
1162
  } catch (e: Exception) {
@@ -1156,7 +1175,6 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1156
1175
  try {
1157
1176
  val currentActivity = reactApplicationContext.currentActivity
1158
1177
  if (currentActivity == null) {
1159
- Log.e(TAG, "❌ listCerts() failed: Activity not available")
1160
1178
  promise.reject("NO_ACTIVITY", "Activity not available")
1161
1179
  return
1162
1180
  }
@@ -1166,7 +1184,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1166
1184
  pageNumber = pageNumber,
1167
1185
  pageSize = pageSize,
1168
1186
  callbackSuccess = { certs ->
1169
- Log.d(TAG, "✅ listCerts() success - Count: ${certs.size}")
1187
+ // Bắn raw data lên - để EKYCModule.ts xử lý
1170
1188
  val (eventMap, promiseMap) = createSeparateMapsWithArray(
1171
1189
  arrayBuilder = { array: WritableArray ->
1172
1190
  certs.forEach { cert ->
@@ -1185,18 +1203,17 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1185
1203
  promise.resolve(promiseMap)
1186
1204
  },
1187
1205
  callbackError = { event, error ->
1188
- Log.e(TAG, "❌ listCerts() failed - Event: $event, Message: ${error.message}")
1206
+ // Bắn raw data lên - để EKYCModule.ts xử
1189
1207
  val errorMap = Arguments.createMap().apply {
1190
1208
  putString("event", event.name.toString())
1191
- putString("message", error.message)
1192
- putString("code", error.code)
1209
+ putString("message", error.message ?: "")
1210
+ putString("code", error.code.toString())
1193
1211
  }
1194
1212
  sendEvent("onESignError", errorMap)
1195
- promise.reject(event.name.toString(), error.message)
1213
+ promise.reject(event.name.toString(), error.message ?: "Unknown Error")
1196
1214
  }
1197
1215
  )
1198
1216
  } catch (e: Exception) {
1199
- Log.e(TAG, "❌ listCerts() exception: ${e.message}", e)
1200
1217
  promise.reject("ESIGN_EXCEPTION", e.message, e)
1201
1218
  }
1202
1219
  }
@@ -1207,10 +1224,22 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1207
1224
  promise: Promise
1208
1225
  ) {
1209
1226
  Log.d(TAG, "▶️ verifyCert() called")
1227
+
1228
+ if (serial.isBlank()) {
1229
+ val errorMsg = "Certificate serial không được để trống"
1230
+ val errorMap = Arguments.createMap().apply {
1231
+ putString("event", "SDK_START_ERROR")
1232
+ putString("message", errorMsg)
1233
+ putString("code", "INVALID_SERIAL")
1234
+ }
1235
+ sendEvent("onESignError", errorMap)
1236
+ promise.reject("INVALID_SERIAL", errorMsg)
1237
+ return
1238
+ }
1239
+
1210
1240
  try {
1211
1241
  val currentActivity = reactApplicationContext.currentActivity
1212
1242
  if (currentActivity == null) {
1213
- Log.e(TAG, "❌ verifyCert() failed: Activity not available")
1214
1243
  promise.reject("NO_ACTIVITY", "Activity not available")
1215
1244
  return
1216
1245
  }
@@ -1219,7 +1248,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1219
1248
  context = currentActivity,
1220
1249
  serial = serial,
1221
1250
  callbackSuccess = { code, message ->
1222
- Log.d(TAG, "✅ verifyCert() success")
1251
+ // Bắn raw data lên - để EKYCModule.ts xử
1223
1252
  val (eventMap, promiseMap) = createSeparateMaps { map ->
1224
1253
  map.putString("code", code.toString())
1225
1254
  map.putString("message", message)
@@ -1228,18 +1257,19 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1228
1257
  promise.resolve(promiseMap)
1229
1258
  },
1230
1259
  callbackError = { event, error ->
1231
- Log.e(TAG, "❌ verifyCert() failed - Event: $event, Message: ${error.message}")
1260
+ // Bắn raw data lên - để EKYCModule.ts xử
1261
+ val errorMessage = error.message ?: ""
1262
+ val errorCode = error.code.toString()
1232
1263
  val errorMap = Arguments.createMap().apply {
1233
1264
  putString("event", event.name.toString())
1234
- putString("message", error.message)
1235
- putString("code", error.code)
1265
+ putString("message", errorMessage)
1266
+ putString("code", errorCode)
1236
1267
  }
1237
1268
  sendEvent("onESignError", errorMap)
1238
- promise.reject(event.name.toString(), error.message)
1269
+ promise.reject(event.name.toString(), errorMessage)
1239
1270
  }
1240
1271
  )
1241
1272
  } catch (e: Exception) {
1242
- Log.e(TAG, "❌ verifyCert() exception: ${e.message}", e)
1243
1273
  promise.reject("ESIGN_EXCEPTION", e.message, e)
1244
1274
  }
1245
1275
  }
@@ -1254,7 +1284,6 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1254
1284
  try {
1255
1285
  val currentActivity = reactApplicationContext.currentActivity
1256
1286
  if (currentActivity == null) {
1257
- Log.e(TAG, "❌ listSignRequest() failed: Activity not available")
1258
1287
  promise.reject("NO_ACTIVITY", "Activity not available")
1259
1288
  return
1260
1289
  }
@@ -1264,14 +1293,16 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1264
1293
  pageNumber = pageNumber,
1265
1294
  pageSize = pageSize,
1266
1295
  callbackSuccess = { requests ->
1267
- Log.d(TAG, "✅ listSignRequest() success - Count: ${requests.size}")
1296
+ // Bắn raw data lên - để EKYCModule.ts xử lý
1268
1297
  val (eventMap, promiseMap) = createSeparateMapsWithArray(
1269
1298
  arrayBuilder = { array: WritableArray ->
1270
1299
  requests.forEach { request ->
1271
1300
  val requestMap = Arguments.createMap().apply {
1272
1301
  putString("requestId", request.requestId)
1273
- putString("documentName", request.documentName)
1274
- putString("status", request.status)
1302
+ putString("authId", request.authId ?: "")
1303
+ putString("authData", request.authData ?: "")
1304
+ putString("status", request.authId ?: "")
1305
+ putString("documentName", request.authData ?: "")
1275
1306
  }
1276
1307
  array.pushMap(requestMap)
1277
1308
  }
@@ -1282,18 +1313,17 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1282
1313
  promise.resolve(promiseMap)
1283
1314
  },
1284
1315
  callbackError = { event, error ->
1285
- Log.e(TAG, "❌ listSignRequest() failed - Event: $event, Message: ${error.message}")
1316
+ // Bắn raw data lên - để EKYCModule.ts xử
1286
1317
  val errorMap = Arguments.createMap().apply {
1287
1318
  putString("event", event.name.toString())
1288
- putString("message", error.message)
1289
- putString("code", error.code)
1319
+ putString("message", error.message ?: "")
1320
+ putString("code", error.code.toString())
1290
1321
  }
1291
1322
  sendEvent("onESignError", errorMap)
1292
- promise.reject(event.name.toString(), error.message)
1323
+ promise.reject(event.name.toString(), error.message ?: "Unknown Error")
1293
1324
  }
1294
1325
  )
1295
1326
  } catch (e: Exception) {
1296
- Log.e(TAG, "❌ listSignRequest() exception: ${e.message}", e)
1297
1327
  promise.reject("ESIGN_EXCEPTION", e.message, e)
1298
1328
  }
1299
1329
  }
@@ -1308,6 +1338,8 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1308
1338
  promise: Promise
1309
1339
  ) {
1310
1340
  Log.d(TAG, "▶️ confirmSign() called")
1341
+ Log.d(TAG, " 📋 Request params - signRequestId: $signRequestId, confirm: $confirm")
1342
+ Log.d(TAG, " 📋 Auth params - authId: ${authId?.take(20)}..., authData: ${authData?.take(20)}...")
1311
1343
  try {
1312
1344
  val currentActivity = reactApplicationContext.currentActivity
1313
1345
  if (currentActivity == null) {
@@ -1316,6 +1348,7 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1316
1348
  return
1317
1349
  }
1318
1350
 
1351
+ Log.d(TAG, " 🔄 Calling SdkeSign.confirmSign()")
1319
1352
  SdkeSign.confirmSign(
1320
1353
  context = currentActivity,
1321
1354
  signRequestId = signRequestId,
@@ -1324,7 +1357,8 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1324
1357
  authData = authData ?: "",
1325
1358
  confirm = confirm,
1326
1359
  callbackSuccess = { code, message ->
1327
- Log.d(TAG, "✅ confirmSign() success")
1360
+ Log.d(TAG, "✅ confirmSign() success - Code: $code, Message: $message")
1361
+ // Bắn raw data lên - để EKYCModule.ts xử lý
1328
1362
  val (eventMap, promiseMap) = createSeparateMaps { map ->
1329
1363
  map.putString("code", code.toString())
1330
1364
  map.putString("message", message)
@@ -1333,69 +1367,47 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1333
1367
  promise.resolve(promiseMap)
1334
1368
  },
1335
1369
  callbackError = { event, error ->
1336
- Log.e(TAG, "❌ confirmSign() failed - Event: $event, Message: ${error.message}")
1337
- val errorMap = Arguments.createMap().apply {
1338
- putString("event", event.name.toString())
1339
- putString("message", error.message)
1340
- putString("code", error.code)
1370
+ val errorMessage = error.message ?: ""
1371
+ val errorCode = error.code.toString()
1372
+
1373
+ Log.d(TAG, "🔍 confirmSign() error callback - Message: '$errorMessage', Code: '$errorCode'")
1374
+
1375
+ // Check if message contains "thành công" or code == "0" -> treat as success
1376
+ if (errorMessage.contains("thành công", ignoreCase = true) || errorCode == "0") {
1377
+ Log.d(TAG, "✅ confirmSign() success (async operation) - Message: $errorMessage")
1378
+ val (eventMap, promiseMap) = createSeparateMaps { map ->
1379
+ map.putString("code", "200")
1380
+ map.putString("message", errorMessage)
1381
+ }
1382
+ sendEvent("onESignConfirmSignSuccess", eventMap)
1383
+ promise.resolve(promiseMap)
1384
+ } else {
1385
+ Log.e(TAG, "❌ confirmSign() failed - Event: $event, Message: $errorMessage, Code: $errorCode")
1386
+ val errorMap = Arguments.createMap().apply {
1387
+ putString("event", event.name.toString())
1388
+ putString("message", errorMessage)
1389
+ putString("code", errorCode)
1390
+ }
1391
+ sendEvent("onESignError", errorMap)
1392
+ promise.reject(event.name.toString(), errorMessage)
1341
1393
  }
1342
- sendEvent("onESignError", errorMap)
1343
- promise.reject(event.name.toString(), error.message)
1344
1394
  }
1345
1395
  )
1346
1396
  } catch (e: Exception) {
1347
- Log.e(TAG, "❌ confirmSign() exception: ${e.message}", e)
1348
1397
  promise.reject("ESIGN_EXCEPTION", e.message, e)
1349
1398
  }
1350
1399
  }
1351
1400
 
1352
- @ReactMethod
1353
- fun authenticate(
1354
- username: String,
1355
- password: String,
1356
- promise: Promise
1357
- ) {
1358
- Log.d(TAG, "▶️ authenticate() called")
1359
- try {
1360
- SdkeSign.authenticate(
1361
- username = username,
1362
- password = password,
1363
- callbackSuccess = { token, userId ->
1364
- Log.d(TAG, "✅ authenticate() success")
1365
- val (eventMap, promiseMap) = createSeparateMaps { map ->
1366
- map.putString("token", token)
1367
- map.putString("userId", userId.toString())
1368
- }
1369
- sendEvent("onESignAuthenticateSuccess", eventMap)
1370
- promise.resolve(promiseMap)
1371
- },
1372
- callbackError = { event, error ->
1373
- Log.e(TAG, "❌ authenticate() failed - Event: $event, Message: ${error.message}")
1374
- val errorMap = Arguments.createMap().apply {
1375
- putString("event", event.name.toString())
1376
- putString("message", error.message)
1377
- putString("code", error.code)
1378
- }
1379
- sendEvent("onESignError", errorMap)
1380
- promise.reject(event.name.toString(), error.message)
1381
- }
1382
- )
1383
- } catch (e: Exception) {
1384
- Log.e(TAG, "❌ authenticate() exception: ${e.message}", e)
1385
- promise.reject("ESIGN_EXCEPTION", e.message, e)
1386
- }
1387
- }
1401
+
1388
1402
 
1389
1403
  @ReactMethod
1390
1404
  fun registerRemoteSigning(
1391
- accessToken: String,
1392
1405
  requestJson: String,
1393
1406
  promise: Promise
1394
1407
  ) {
1395
1408
  Log.d(TAG, "▶️ registerRemoteSigning() called")
1396
1409
  try {
1397
1410
  SdkeSign.registerRemoteSigning(
1398
- accessToken = accessToken,
1399
1411
  requestJson = requestJson,
1400
1412
  callbackSuccess = { rawResponse ->
1401
1413
  Log.d(TAG, "✅ registerRemoteSigning() success")
@@ -1406,14 +1418,28 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1406
1418
  promise.resolve(promiseMap)
1407
1419
  },
1408
1420
  callbackError = { event, error ->
1409
- Log.e(TAG, "❌ registerRemoteSigning() failed - Event: $event, Message: ${error.message}")
1410
- val errorMap = Arguments.createMap().apply {
1411
- putString("event", event.name.toString())
1412
- putString("message", error.message)
1413
- putString("code", error.code)
1421
+ val errorMessage = error.message ?: ""
1422
+ val errorCode = error.code.toString()
1423
+
1424
+ // Check if message contains "thành công" or code == "0" -> treat as success
1425
+ if (errorMessage.contains("thành công", ignoreCase = true) || errorCode == "0") {
1426
+ Log.d(TAG, "✅ registerRemoteSigning() success (async operation) - Message: $errorMessage")
1427
+ val (eventMap, promiseMap) = createSeparateMaps { map ->
1428
+ map.putString("response", "{\"status\":1,\"msg\":\"$errorMessage\"}")
1429
+ map.putString("message", errorMessage)
1430
+ }
1431
+ sendEvent("onESignRegisterRemoteSigningSuccess", eventMap)
1432
+ promise.resolve(promiseMap)
1433
+ } else {
1434
+ Log.e(TAG, "❌ registerRemoteSigning() failed - Event: $event, Message: $errorMessage")
1435
+ val errorMap = Arguments.createMap().apply {
1436
+ putString("event", event.name.toString())
1437
+ putString("message", errorMessage)
1438
+ putString("code", errorCode)
1439
+ }
1440
+ sendEvent("onESignError", errorMap)
1441
+ promise.reject(event.name.toString(), errorMessage)
1414
1442
  }
1415
- sendEvent("onESignError", errorMap)
1416
- promise.reject(event.name.toString(), error.message)
1417
1443
  }
1418
1444
  )
1419
1445
  } catch (e: Exception) {
@@ -1424,17 +1450,15 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1424
1450
 
1425
1451
  @ReactMethod
1426
1452
  fun signPdf(
1427
- accessToken: String,
1428
1453
  requestJson: String,
1429
1454
  promise: Promise
1430
1455
  ) {
1431
1456
  Log.d(TAG, "▶️ signPdf() called")
1432
1457
  try {
1433
1458
  SdkeSign.signPdf(
1434
- accessToken = accessToken,
1435
1459
  requestJson = requestJson,
1436
1460
  callbackSuccess = { rawResponse ->
1437
- Log.d(TAG, "✅ signPdf() success")
1461
+ // Bắn raw data lên - để EKYCModule.ts xử
1438
1462
  val (eventMap, promiseMap) = createSeparateMaps { map ->
1439
1463
  map.putString("response", rawResponse)
1440
1464
  }
@@ -1442,35 +1466,45 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1442
1466
  promise.resolve(promiseMap)
1443
1467
  },
1444
1468
  callbackError = { event, error ->
1445
- Log.e(TAG, "❌ signPdf() failed - Event: $event, Message: ${error.message}")
1446
- val errorMap = Arguments.createMap().apply {
1447
- putString("event", event.name.toString())
1448
- putString("message", error.message)
1449
- putString("code", error.code)
1469
+ val errorMessage = error.message ?: ""
1470
+ val errorCode = error.code.toString()
1471
+
1472
+ // Check if message contains "thành công" or code == "0" -> treat as success
1473
+ if (errorMessage.contains("thành công", ignoreCase = true) || errorCode == "0") {
1474
+ Log.d(TAG, "✅ signPdf() success (async operation) - Message: $errorMessage")
1475
+ val (eventMap, promiseMap) = createSeparateMaps { map ->
1476
+ map.putString("response", "{\"status\":1,\"msg\":\"$errorMessage\"}")
1477
+ map.putString("message", errorMessage)
1478
+ }
1479
+ sendEvent("onESignSignPdfSuccess", eventMap)
1480
+ promise.resolve(promiseMap)
1481
+ } else {
1482
+ val errorMap = Arguments.createMap().apply {
1483
+ putString("event", event.name.toString())
1484
+ putString("message", errorMessage)
1485
+ putString("code", errorCode)
1486
+ }
1487
+ sendEvent("onESignError", errorMap)
1488
+ promise.reject(event.name.toString(), errorMessage)
1450
1489
  }
1451
- sendEvent("onESignError", errorMap)
1452
- promise.reject(event.name.toString(), error.message)
1453
1490
  }
1454
1491
  )
1455
1492
  } catch (e: Exception) {
1456
- Log.e(TAG, "❌ signPdf() exception: ${e.message}", e)
1457
1493
  promise.reject("ESIGN_EXCEPTION", e.message, e)
1458
1494
  }
1459
1495
  }
1460
1496
 
1461
1497
  @ReactMethod
1462
1498
  fun sendConfirmationDocument(
1463
- accessToken: String,
1464
1499
  requestJson: String,
1465
1500
  promise: Promise
1466
1501
  ) {
1467
1502
  Log.d(TAG, "▶️ sendConfirmationDocument() called")
1468
1503
  try {
1469
1504
  SdkeSign.sendConfirmationDocument(
1470
- accessToken = accessToken,
1471
1505
  requestJson = requestJson,
1472
1506
  callbackSuccess = { rawResponse ->
1473
- Log.d(TAG, "✅ sendConfirmationDocument() success")
1507
+ // Bắn raw data lên - để EKYCModule.ts xử
1474
1508
  val (eventMap, promiseMap) = createSeparateMaps { map ->
1475
1509
  map.putString("response", rawResponse)
1476
1510
  }
@@ -1478,18 +1512,30 @@ class EKYCModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMo
1478
1512
  promise.resolve(promiseMap)
1479
1513
  },
1480
1514
  callbackError = { event, error ->
1481
- Log.e(TAG, "❌ sendConfirmationDocument() failed - Event: $event, Message: ${error.message}")
1482
- val errorMap = Arguments.createMap().apply {
1483
- putString("event", event.name.toString())
1484
- putString("message", error.message)
1485
- putString("code", error.code)
1515
+ val errorMessage = error.message ?: ""
1516
+ val errorCode = error.code.toString()
1517
+
1518
+ // Check if message contains "thành công" or code == "0" -> treat as success
1519
+ if (errorMessage.contains("thành công", ignoreCase = true) || errorCode == "0") {
1520
+ Log.d(TAG, "✅ sendConfirmationDocument() success (async operation) - Message: $errorMessage")
1521
+ val (eventMap, promiseMap) = createSeparateMaps { map ->
1522
+ map.putString("response", "{\"status\":1,\"msg\":\"$errorMessage\"}")
1523
+ map.putString("message", errorMessage)
1524
+ }
1525
+ sendEvent("onESignSendConfirmationDocumentSuccess", eventMap)
1526
+ promise.resolve(promiseMap)
1527
+ } else {
1528
+ val errorMap = Arguments.createMap().apply {
1529
+ putString("event", event.name.toString())
1530
+ putString("message", errorMessage)
1531
+ putString("code", errorCode)
1532
+ }
1533
+ sendEvent("onESignError", errorMap)
1534
+ promise.reject(event.name.toString(), errorMessage)
1486
1535
  }
1487
- sendEvent("onESignError", errorMap)
1488
- promise.reject(event.name.toString(), error.message)
1489
1536
  }
1490
1537
  )
1491
1538
  } catch (e: Exception) {
1492
- Log.e(TAG, "❌ sendConfirmationDocument() exception: ${e.message}", e)
1493
1539
  promise.reject("ESIGN_EXCEPTION", e.message, e)
1494
1540
  }
1495
1541
  }