nimbbl-mobile-react-native-sdk 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +122 -167
- package/android/src/main/AndroidManifest.xml +0 -4
- package/android/src/main/java/com/nimbbl/reactnative/NimbblCheckoutActivity.kt +43 -52
- package/android/src/main/java/com/nimbbl/reactnative/NimbblReactNativeSDKModule.kt +250 -55
- package/ios/NimbblReactNativeSDK.swift +6 -33
- package/lib/NimbblSDK.d.ts +3 -31
- package/lib/NimbblSDK.js +23 -101
- package/lib/constants.d.ts +2 -13
- package/lib/constants.js +3 -16
- package/lib/index.d.ts +2 -2
- package/lib/index.js +1 -3
- package/lib/types.d.ts +24 -10
- package/lib/types.js +1 -1
- package/package.json +8 -2
|
@@ -3,19 +3,97 @@ package com.nimbbl.reactnative
|
|
|
3
3
|
import android.app.Activity
|
|
4
4
|
import android.content.Intent
|
|
5
5
|
import com.facebook.react.bridge.*
|
|
6
|
-
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
7
6
|
import tech.nimbbl.webviewsdk.core.NimbblCheckoutSDK
|
|
8
7
|
import tech.nimbbl.webviewsdk.core.NimbblShopOrderCreation
|
|
9
8
|
import tech.nimbbl.webviewsdk.models.NimbblCheckoutOptions
|
|
10
9
|
import tech.nimbbl.webviewsdk.models.interfaces.NimbblCheckoutPaymentListener
|
|
11
10
|
import kotlinx.coroutines.*
|
|
12
11
|
import retrofit2.Response
|
|
12
|
+
import java.io.Serializable
|
|
13
|
+
import org.json.JSONObject
|
|
14
|
+
import org.json.JSONException
|
|
13
15
|
|
|
14
16
|
class NimbblReactNativeSDKModule(private val reactContext: ReactApplicationContext) :
|
|
15
17
|
ReactContextBaseJavaModule(reactContext), ActivityEventListener {
|
|
16
18
|
|
|
17
19
|
companion object {
|
|
18
|
-
private
|
|
20
|
+
private var instance: NimbblReactNativeSDKModule? = null
|
|
21
|
+
|
|
22
|
+
fun handleCheckoutResponse(data: MutableMap<String, Any>) {
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
instance?.let { module ->
|
|
26
|
+
// Convert Map to WritableMap
|
|
27
|
+
val responseData = Arguments.createMap().apply {
|
|
28
|
+
data.forEach { (key, value) ->
|
|
29
|
+
when (value) {
|
|
30
|
+
is String -> {
|
|
31
|
+
// Special handling for 'order' field - parse JSON string to object
|
|
32
|
+
if (key == "order" && value.startsWith("{") && value.endsWith("}")) {
|
|
33
|
+
try {
|
|
34
|
+
val jsonObject = JSONObject(value)
|
|
35
|
+
val orderMap = Arguments.createMap()
|
|
36
|
+
|
|
37
|
+
// Convert JSONObject to WritableMap
|
|
38
|
+
jsonObject.keys().forEach { jsonKey ->
|
|
39
|
+
val jsonValue = jsonObject.get(jsonKey)
|
|
40
|
+
when (jsonValue) {
|
|
41
|
+
is String -> orderMap.putString(jsonKey, jsonValue)
|
|
42
|
+
is Number -> orderMap.putDouble(jsonKey, jsonValue.toDouble())
|
|
43
|
+
is Boolean -> orderMap.putBoolean(jsonKey, jsonValue)
|
|
44
|
+
is JSONObject -> {
|
|
45
|
+
val nestedMap = Arguments.createMap()
|
|
46
|
+
jsonValue.keys().forEach { nestedKey ->
|
|
47
|
+
val nestedValue = jsonValue.get(nestedKey)
|
|
48
|
+
when (nestedValue) {
|
|
49
|
+
is String -> nestedMap.putString(nestedKey, nestedValue)
|
|
50
|
+
is Number -> nestedMap.putDouble(nestedKey, nestedValue.toDouble())
|
|
51
|
+
is Boolean -> nestedMap.putBoolean(nestedKey, nestedValue)
|
|
52
|
+
else -> nestedMap.putString(nestedKey, nestedValue.toString())
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
orderMap.putMap(jsonKey, nestedMap)
|
|
56
|
+
}
|
|
57
|
+
else -> orderMap.putString(jsonKey, jsonValue.toString())
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
putMap(key, orderMap)
|
|
62
|
+
} catch (e: JSONException) {
|
|
63
|
+
putString(key, value)
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
putString(key, value)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
is Number -> putDouble(key, value.toDouble())
|
|
70
|
+
is Boolean -> putBoolean(key, value)
|
|
71
|
+
is Map<*, *> -> {
|
|
72
|
+
val nestedMap = Arguments.createMap()
|
|
73
|
+
(value as Map<String, Any>).forEach { (nestedKey, nestedValue) ->
|
|
74
|
+
when (nestedValue) {
|
|
75
|
+
is String -> nestedMap.putString(nestedKey, nestedValue)
|
|
76
|
+
is Number -> nestedMap.putDouble(nestedKey, nestedValue.toDouble())
|
|
77
|
+
is Boolean -> nestedMap.putBoolean(nestedKey, nestedValue)
|
|
78
|
+
else -> nestedMap.putString(nestedKey, nestedValue.toString())
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
putMap(key, nestedMap)
|
|
82
|
+
}
|
|
83
|
+
else -> putString(key, value.toString())
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Use callback if available
|
|
89
|
+
if (module.checkoutCallback != null) {
|
|
90
|
+
module.checkoutCallback?.invoke(responseData)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} catch (e: Exception) {
|
|
94
|
+
// Error in handleCheckoutResponse - ignore
|
|
95
|
+
}
|
|
96
|
+
}
|
|
19
97
|
}
|
|
20
98
|
|
|
21
99
|
private var config: MutableMap<String, Any> = mutableMapOf()
|
|
@@ -24,28 +102,24 @@ class NimbblReactNativeSDKModule(private val reactContext: ReactApplicationConte
|
|
|
24
102
|
|
|
25
103
|
init {
|
|
26
104
|
reactContext.addActivityEventListener(this)
|
|
105
|
+
instance = this
|
|
27
106
|
}
|
|
28
107
|
|
|
29
108
|
override fun getName(): String {
|
|
30
109
|
return "NimbblReactNativeSDK"
|
|
31
110
|
}
|
|
32
111
|
|
|
33
|
-
|
|
34
|
-
return mutableMapOf(
|
|
35
|
-
"SDK_VERSION" to "1.0.0",
|
|
36
|
-
"PLATFORM" to "android"
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
|
|
112
|
+
|
|
40
113
|
@ReactMethod
|
|
41
114
|
fun addListener(@Suppress("UNUSED_PARAMETER") eventName: String) {
|
|
42
115
|
// Required for NativeEventEmitter - no action needed
|
|
43
116
|
}
|
|
44
|
-
|
|
117
|
+
|
|
45
118
|
@ReactMethod
|
|
46
119
|
fun removeListeners(@Suppress("UNUSED_PARAMETER") count: Int) {
|
|
47
120
|
// Required for NativeEventEmitter - no action needed
|
|
48
121
|
}
|
|
122
|
+
|
|
49
123
|
|
|
50
124
|
@ReactMethod
|
|
51
125
|
fun setCheckoutCallback(callback: Callback) {
|
|
@@ -53,7 +127,7 @@ class NimbblReactNativeSDKModule(private val reactContext: ReactApplicationConte
|
|
|
53
127
|
try {
|
|
54
128
|
callback.invoke(result)
|
|
55
129
|
} catch (e: Exception) {
|
|
56
|
-
// Error calling
|
|
130
|
+
// Error calling React Native callback - ignore
|
|
57
131
|
}
|
|
58
132
|
}
|
|
59
133
|
}
|
|
@@ -68,19 +142,14 @@ class NimbblReactNativeSDKModule(private val reactContext: ReactApplicationConte
|
|
|
68
142
|
|
|
69
143
|
// Extract configuration
|
|
70
144
|
this.config.clear()
|
|
71
|
-
this.config["
|
|
72
|
-
|
|
73
|
-
config.getMap("options")?.let { options ->
|
|
74
|
-
this.config["timeout"] = if (options.hasKey("timeout")) options.getInt("timeout") else 30000
|
|
75
|
-
this.config["enable_logging"] = if (options.hasKey("enable_logging")) options.getBoolean("enable_logging") else false
|
|
76
|
-
this.config["enable_analytics"] = if (options.hasKey("enable_analytics")) options.getBoolean("enable_analytics") else true
|
|
77
|
-
this.config["api_base_url"] = if (options.hasKey("api_base_url")) options.getString("api_base_url") ?: "https://api.nimbbl.tech" else "https://api.nimbbl.tech"
|
|
78
|
-
}
|
|
145
|
+
this.config["api_base_url"] = config.getString("api_base_url") ?: "https://api.nimbbl.tech"
|
|
79
146
|
|
|
80
147
|
// Set environment URL on the native SDK during initialization
|
|
81
148
|
val apiBaseUrl = this.config["api_base_url"] as? String
|
|
82
149
|
if (!apiBaseUrl.isNullOrEmpty()) {
|
|
83
|
-
|
|
150
|
+
// Ensure URL ends with / to prevent URL construction issues
|
|
151
|
+
val normalizedUrl = if (apiBaseUrl.endsWith("/")) apiBaseUrl else apiBaseUrl + "/"
|
|
152
|
+
NimbblCheckoutSDK.getInstance().setEnvironmentUrl(normalizedUrl)
|
|
84
153
|
}
|
|
85
154
|
|
|
86
155
|
isInitialized = true
|
|
@@ -243,21 +312,96 @@ class NimbblReactNativeSDKModule(private val reactContext: ReactApplicationConte
|
|
|
243
312
|
return
|
|
244
313
|
}
|
|
245
314
|
|
|
246
|
-
//
|
|
315
|
+
// Use the NimbblCheckoutActivity with proper callback setup
|
|
247
316
|
try {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
317
|
+
// Set up the callback to receive the result
|
|
318
|
+
NimbblCheckoutActivity.setResultCallback { result ->
|
|
319
|
+
|
|
320
|
+
// Convert Map to WritableMap
|
|
321
|
+
val responseData = Arguments.createMap().apply {
|
|
322
|
+
result.forEach { (key, value) ->
|
|
323
|
+
when (value) {
|
|
324
|
+
is String -> {
|
|
325
|
+
// Special handling for 'order' field - parse JSON string to object
|
|
326
|
+
if (key == "order" && value.startsWith("{") && value.endsWith("}")) {
|
|
327
|
+
try {
|
|
328
|
+
val jsonObject = JSONObject(value)
|
|
329
|
+
val orderMap = Arguments.createMap()
|
|
330
|
+
|
|
331
|
+
// Convert JSONObject to WritableMap
|
|
332
|
+
jsonObject.keys().forEach { jsonKey ->
|
|
333
|
+
val jsonValue = jsonObject.get(jsonKey)
|
|
334
|
+
when (jsonValue) {
|
|
335
|
+
is String -> orderMap.putString(jsonKey, jsonValue)
|
|
336
|
+
is Number -> orderMap.putDouble(jsonKey, jsonValue.toDouble())
|
|
337
|
+
is Boolean -> orderMap.putBoolean(jsonKey, jsonValue)
|
|
338
|
+
is JSONObject -> {
|
|
339
|
+
val nestedMap = Arguments.createMap()
|
|
340
|
+
jsonValue.keys().forEach { nestedKey ->
|
|
341
|
+
val nestedValue = jsonValue.get(nestedKey)
|
|
342
|
+
when (nestedValue) {
|
|
343
|
+
is String -> nestedMap.putString(nestedKey, nestedValue)
|
|
344
|
+
is Number -> nestedMap.putDouble(nestedKey, nestedValue.toDouble())
|
|
345
|
+
is Boolean -> nestedMap.putBoolean(nestedKey, nestedValue)
|
|
346
|
+
else -> nestedMap.putString(nestedKey, nestedValue.toString())
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
orderMap.putMap(jsonKey, nestedMap)
|
|
350
|
+
}
|
|
351
|
+
else -> orderMap.putString(jsonKey, jsonValue.toString())
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
putMap(key, orderMap)
|
|
356
|
+
} catch (e: JSONException) {
|
|
357
|
+
putString(key, value)
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
putString(key, value)
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
is Number -> putDouble(key, value.toDouble())
|
|
364
|
+
is Boolean -> putBoolean(key, value)
|
|
365
|
+
is Map<*, *> -> {
|
|
366
|
+
val nestedMap = Arguments.createMap()
|
|
367
|
+
(value as Map<String, Any>).forEach { (nestedKey, nestedValue) ->
|
|
368
|
+
when (nestedValue) {
|
|
369
|
+
is String -> nestedMap.putString(nestedKey, nestedValue)
|
|
370
|
+
is Number -> nestedMap.putDouble(nestedKey, nestedValue.toDouble())
|
|
371
|
+
is Boolean -> nestedMap.putBoolean(nestedKey, nestedValue)
|
|
372
|
+
else -> nestedMap.putString(nestedKey, nestedValue.toString())
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
putMap(key, nestedMap)
|
|
376
|
+
}
|
|
377
|
+
else -> putString(key, value.toString())
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Use callback if available
|
|
383
|
+
if (checkoutCallback != null) {
|
|
384
|
+
try {
|
|
385
|
+
checkoutCallback?.invoke(responseData)
|
|
386
|
+
} catch (e: Exception) {
|
|
387
|
+
// Error invoking checkout callback - ignore
|
|
388
|
+
}
|
|
389
|
+
}
|
|
256
390
|
}
|
|
257
391
|
|
|
258
|
-
//
|
|
259
|
-
|
|
260
|
-
|
|
392
|
+
// Add a small delay to ensure callback is properly set up
|
|
393
|
+
android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
|
|
394
|
+
// Start the NimbblCheckoutActivity
|
|
395
|
+
val intent = Intent(currentActivity, NimbblCheckoutActivity::class.java).apply {
|
|
396
|
+
putExtra(NimbblCheckoutActivity.EXTRA_ORDER_TOKEN, orderToken)
|
|
397
|
+
putExtra(NimbblCheckoutActivity.EXTRA_PAYMENT_MODE_CODE, paymentModeCode)
|
|
398
|
+
putExtra(NimbblCheckoutActivity.EXTRA_BANK_CODE, bankCode)
|
|
399
|
+
putExtra(NimbblCheckoutActivity.EXTRA_WALLET_CODE, walletCode)
|
|
400
|
+
putExtra(NimbblCheckoutActivity.EXTRA_PAYMENT_FLOW, paymentFlow)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
currentActivity.startActivity(intent)
|
|
404
|
+
}, 50) // 50ms delay to ensure callback is set up
|
|
261
405
|
|
|
262
406
|
} catch (e: Exception) {
|
|
263
407
|
promise.reject("CHECKOUT_FAILED", "Error starting checkout activity: ${e.message}")
|
|
@@ -276,47 +420,98 @@ class NimbblReactNativeSDKModule(private val reactContext: ReactApplicationConte
|
|
|
276
420
|
}
|
|
277
421
|
|
|
278
422
|
|
|
279
|
-
private fun sendEvent(eventName: String, params: WritableMap?) {
|
|
280
|
-
try {
|
|
281
|
-
reactContext
|
|
282
|
-
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
283
|
-
.emit(eventName, params)
|
|
284
|
-
} catch (e: Exception) {
|
|
285
|
-
// Error sending event, ignore
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
423
|
|
|
289
424
|
override fun onActivityResult(activity: Activity?, requestCode: Int, resultCode: Int, data: Intent?) {
|
|
425
|
+
|
|
290
426
|
// Handle NimbblCheckoutActivity results
|
|
291
427
|
if (requestCode == 1001) {
|
|
292
428
|
val responseData = if (data != null) {
|
|
293
|
-
val
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
429
|
+
val rawData = data.getSerializableExtra("response_data") as? MutableMap<String, Any>
|
|
430
|
+
|
|
431
|
+
if (rawData != null) {
|
|
432
|
+
// Convert Map to WritableMap directly
|
|
433
|
+
Arguments.createMap().apply {
|
|
434
|
+
rawData.forEach { (key, value) ->
|
|
435
|
+
when (value) {
|
|
436
|
+
is String -> {
|
|
437
|
+
// Special handling for 'order' field - parse JSON string to object
|
|
438
|
+
if (key == "order" && value.startsWith("{") && value.endsWith("}")) {
|
|
439
|
+
try {
|
|
440
|
+
val jsonObject = JSONObject(value)
|
|
441
|
+
val orderMap = Arguments.createMap()
|
|
442
|
+
|
|
443
|
+
// Convert JSONObject to WritableMap
|
|
444
|
+
jsonObject.keys().forEach { jsonKey ->
|
|
445
|
+
val jsonValue = jsonObject.get(jsonKey)
|
|
446
|
+
when (jsonValue) {
|
|
447
|
+
is String -> orderMap.putString(jsonKey, jsonValue)
|
|
448
|
+
is Number -> orderMap.putDouble(jsonKey, jsonValue.toDouble())
|
|
449
|
+
is Boolean -> orderMap.putBoolean(jsonKey, jsonValue)
|
|
450
|
+
is JSONObject -> {
|
|
451
|
+
val nestedMap = Arguments.createMap()
|
|
452
|
+
jsonValue.keys().forEach { nestedKey ->
|
|
453
|
+
val nestedValue = jsonValue.get(nestedKey)
|
|
454
|
+
when (nestedValue) {
|
|
455
|
+
is String -> nestedMap.putString(nestedKey, nestedValue)
|
|
456
|
+
is Number -> nestedMap.putDouble(nestedKey, nestedValue.toDouble())
|
|
457
|
+
is Boolean -> nestedMap.putBoolean(nestedKey, nestedValue)
|
|
458
|
+
else -> nestedMap.putString(nestedKey, nestedValue.toString())
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
orderMap.putMap(jsonKey, nestedMap)
|
|
462
|
+
}
|
|
463
|
+
else -> orderMap.putString(jsonKey, jsonValue.toString())
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
putMap(key, orderMap)
|
|
468
|
+
} catch (e: JSONException) {
|
|
469
|
+
putString(key, value)
|
|
470
|
+
}
|
|
471
|
+
} else {
|
|
472
|
+
putString(key, value)
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
is Number -> putDouble(key, value.toDouble())
|
|
476
|
+
is Boolean -> putBoolean(key, value)
|
|
477
|
+
is Map<*, *> -> {
|
|
478
|
+
val nestedMap = Arguments.createMap()
|
|
479
|
+
(value as Map<String, Any>).forEach { (nestedKey, nestedValue) ->
|
|
480
|
+
when (nestedValue) {
|
|
481
|
+
is String -> nestedMap.putString(nestedKey, nestedValue)
|
|
482
|
+
is Number -> nestedMap.putDouble(nestedKey, nestedValue.toDouble())
|
|
483
|
+
is Boolean -> nestedMap.putBoolean(nestedKey, nestedValue)
|
|
484
|
+
else -> nestedMap.putString(nestedKey, nestedValue.toString())
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
putMap(key, nestedMap)
|
|
488
|
+
}
|
|
489
|
+
else -> putString(key, value.toString())
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
} else {
|
|
494
|
+
Arguments.createMap().apply {
|
|
495
|
+
putString("status", "failed")
|
|
496
|
+
putString("message", "No response data received")
|
|
497
|
+
}
|
|
300
498
|
}
|
|
301
499
|
} else {
|
|
302
500
|
Arguments.createMap().apply {
|
|
303
501
|
putString("status", "failed")
|
|
304
502
|
putString("message", "Payment was cancelled or failed")
|
|
305
|
-
putString("order_id", "")
|
|
306
|
-
putString("payment_id", "")
|
|
307
|
-
putString("data", "")
|
|
308
503
|
}
|
|
309
504
|
}
|
|
310
505
|
|
|
311
|
-
// Use callback if available
|
|
506
|
+
// Use callback if available
|
|
312
507
|
if (checkoutCallback != null) {
|
|
313
508
|
checkoutCallback?.invoke(responseData)
|
|
314
|
-
} else {
|
|
315
|
-
sendEvent("checkout_response", responseData)
|
|
316
509
|
}
|
|
510
|
+
// Note: Removed fallback to event emitter for cleaner implementation
|
|
317
511
|
}
|
|
318
512
|
}
|
|
319
513
|
|
|
514
|
+
|
|
320
515
|
override fun onNewIntent(intent: Intent?) {
|
|
321
516
|
// Handle new intents if needed
|
|
322
517
|
}
|
|
@@ -325,5 +520,5 @@ class NimbblReactNativeSDKModule(private val reactContext: ReactApplicationConte
|
|
|
325
520
|
super.onCatalystInstanceDestroy()
|
|
326
521
|
reactContext.removeActivityEventListener(this)
|
|
327
522
|
}
|
|
328
|
-
|
|
523
|
+
|
|
329
524
|
}
|
|
@@ -8,7 +8,6 @@ class NimbblReactNativeSDK: RCTEventEmitter, NimbblCheckoutSDKDelegate {
|
|
|
8
8
|
|
|
9
9
|
private var config: [String: Any] = [:]
|
|
10
10
|
private var isInitialized = false
|
|
11
|
-
private var hasListeners = false
|
|
12
11
|
private var checkoutCallback: RCTResponseSenderBlock?
|
|
13
12
|
|
|
14
13
|
override init() {
|
|
@@ -16,30 +15,11 @@ class NimbblReactNativeSDK: RCTEventEmitter, NimbblCheckoutSDKDelegate {
|
|
|
16
15
|
NimbblCheckoutSDK.shared.delegate = self
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
override func supportedEvents() -> [String]! {
|
|
20
|
-
return [
|
|
21
|
-
"checkout_response"
|
|
22
|
-
]
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
override func constantsToExport() -> [AnyHashable: Any]! {
|
|
26
|
-
return [
|
|
27
|
-
"SDK_VERSION": "1.0.0",
|
|
28
|
-
"PLATFORM": "ios"
|
|
29
|
-
]
|
|
30
|
-
}
|
|
31
18
|
|
|
32
19
|
override static func requiresMainQueueSetup() -> Bool {
|
|
33
20
|
return false
|
|
34
21
|
}
|
|
35
22
|
|
|
36
|
-
override func startObserving() {
|
|
37
|
-
hasListeners = true
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
override func stopObserving() {
|
|
41
|
-
hasListeners = false
|
|
42
|
-
}
|
|
43
23
|
|
|
44
24
|
@objc
|
|
45
25
|
override func addListener(_ eventName: String!) {
|
|
@@ -62,19 +42,14 @@ class NimbblReactNativeSDK: RCTEventEmitter, NimbblCheckoutSDKDelegate {
|
|
|
62
42
|
|
|
63
43
|
// Extract configuration
|
|
64
44
|
self.config.removeAll()
|
|
65
|
-
self.config["
|
|
66
|
-
|
|
67
|
-
if let options = config["options"] as? [String: Any] {
|
|
68
|
-
self.config["timeout"] = options["timeout"] as? Int ?? 30000
|
|
69
|
-
self.config["enable_logging"] = options["enable_logging"] as? Bool ?? false
|
|
70
|
-
self.config["enable_analytics"] = options["enable_analytics"] as? Bool ?? true
|
|
71
|
-
self.config["api_base_url"] = options["api_base_url"] as? String ?? "https://api.nimbbl.tech"
|
|
72
|
-
}
|
|
45
|
+
self.config["api_base_url"] = config["api_base_url"] as? String ?? "https://api.nimbbl.tech"
|
|
73
46
|
|
|
74
47
|
// Set environment URL on the native SDK during initialization
|
|
75
48
|
let apiBaseUrl = self.config["api_base_url"] as? String
|
|
76
49
|
if let apiBaseUrl = apiBaseUrl {
|
|
77
|
-
|
|
50
|
+
// Ensure URL ends with / to prevent URL construction issues
|
|
51
|
+
let normalizedUrl = apiBaseUrl.hasSuffix("/") ? apiBaseUrl : apiBaseUrl + "/"
|
|
52
|
+
NimbblCheckoutSDK.shared.environmentUrl = normalizedUrl
|
|
78
53
|
}
|
|
79
54
|
|
|
80
55
|
isInitialized = true
|
|
@@ -199,11 +174,9 @@ class NimbblReactNativeSDK: RCTEventEmitter, NimbblCheckoutSDKDelegate {
|
|
|
199
174
|
|
|
200
175
|
func onCheckoutResponse(data: [AnyHashable: Any]) {
|
|
201
176
|
if let callback = checkoutCallback {
|
|
202
|
-
// Use direct callback
|
|
177
|
+
// Use direct callback
|
|
203
178
|
callback([data])
|
|
204
|
-
} else if hasListeners {
|
|
205
|
-
// Fallback to event emitter
|
|
206
|
-
sendEvent(withName: "checkout_response", body: data)
|
|
207
179
|
}
|
|
180
|
+
// Note: Removed fallback to event emitter for cleaner implementation
|
|
208
181
|
}
|
|
209
182
|
}
|
package/lib/NimbblSDK.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @fileoverview Main Nimbbl SDK for React Native
|
|
3
|
-
* @version 1.
|
|
3
|
+
* @version 1.3.0
|
|
4
4
|
* @author Nimbbl Tech
|
|
5
5
|
*
|
|
6
6
|
* This is a wrapper around the native Android and iOS SDKs
|
|
7
7
|
*/
|
|
8
|
-
import { SDKConfig } from './types';
|
|
8
|
+
import { SDKConfig, CheckoutOptions } from './types';
|
|
9
9
|
/**
|
|
10
10
|
* Main Nimbbl SDK Class
|
|
11
11
|
* Provides the primary interface for integrating Nimbbl payment functionality
|
|
@@ -15,8 +15,6 @@ export default class NimbblSDK {
|
|
|
15
15
|
private static shared;
|
|
16
16
|
private config;
|
|
17
17
|
private isInitialized;
|
|
18
|
-
private eventEmitter;
|
|
19
|
-
private eventListeners;
|
|
20
18
|
constructor();
|
|
21
19
|
/**
|
|
22
20
|
* Get shared instance (matching iOS pattern)
|
|
@@ -53,33 +51,7 @@ export default class NimbblSDK {
|
|
|
53
51
|
* @param options - Checkout options
|
|
54
52
|
* @returns Promise resolving to checkout result
|
|
55
53
|
*/
|
|
56
|
-
checkout(options:
|
|
57
|
-
orderToken: string;
|
|
58
|
-
paymentModeCode?: string;
|
|
59
|
-
bankCode?: string;
|
|
60
|
-
walletCode?: string;
|
|
61
|
-
paymentFlow?: string;
|
|
62
|
-
}): Promise<{
|
|
63
|
-
success: boolean;
|
|
64
|
-
message?: string;
|
|
65
|
-
data?: any;
|
|
66
|
-
}>;
|
|
67
|
-
/**
|
|
68
|
-
* Add unified checkout response listener (recommended approach)
|
|
69
|
-
* This method handles both success and failure cases in a single callback
|
|
70
|
-
* @param listener - Callback function that receives checkout response data
|
|
71
|
-
*/
|
|
72
|
-
addCheckoutResponseListener(listener: (data: any) => void): void;
|
|
73
|
-
/**
|
|
74
|
-
* Remove unified checkout response listener
|
|
75
|
-
* @param listener - Callback function to remove
|
|
76
|
-
*/
|
|
77
|
-
removeCheckoutResponseListener(listener: (data: any) => void): void;
|
|
78
|
-
/**
|
|
79
|
-
* Validate SDK configuration
|
|
80
|
-
* @param config - Configuration to validate
|
|
81
|
-
*/
|
|
82
|
-
private validateConfig;
|
|
54
|
+
checkout(options: CheckoutOptions): Promise<any>;
|
|
83
55
|
}
|
|
84
56
|
export declare const nimbblSDK: NimbblSDK;
|
|
85
57
|
//# sourceMappingURL=NimbblSDK.d.ts.map
|