@yuno-payments/yuno-sdk-react-native 1.0.16 → 1.0.17-rc.1

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/ios/YunoSdk.swift CHANGED
@@ -1,6 +1,20 @@
1
1
  import Foundation
2
+ import React
2
3
  import YunoSDK
3
4
 
5
+ /**
6
+ * Implementation of PaymentMethodSelected protocol for Lite SDK.
7
+ */
8
+ private class PaymentMethodSelection: NSObject, PaymentMethodSelected {
9
+ let paymentMethodType: String
10
+ let vaultedToken: String?
11
+
12
+ init(paymentMethodType: String, vaultedToken: String?) {
13
+ self.paymentMethodType = paymentMethodType
14
+ self.vaultedToken = vaultedToken
15
+ }
16
+ }
17
+
4
18
  /**
5
19
  * Yuno SDK React Native Module for iOS.
6
20
  *
@@ -12,8 +26,12 @@ class YunoSdk: RCTEventEmitter {
12
26
  private var isInitialized = false
13
27
  private var currentCountryCode: String?
14
28
  private var currentLanguage: String?
15
- private var customerSession: String = ""
16
- private var checkoutSession: String = ""
29
+ var customerSession: String = ""
30
+ var checkoutSession: String = ""
31
+
32
+ // Store last payment status to prevent stale status from previous flows
33
+ private var lastPaymentStatus: String?
34
+ private var isPaymentFlowCleared: Bool = false
17
35
 
18
36
  override init() {
19
37
  super.init()
@@ -27,10 +45,23 @@ class YunoSdk: RCTEventEmitter {
27
45
  return [
28
46
  "YunoPaymentStatus",
29
47
  "YunoEnrollmentStatus",
30
- "YunoOneTimeToken"
48
+ "YunoOneTimeToken",
49
+ "YunoOneTimeTokenInfo",
50
+ "onPaymentMethodSelected",
51
+ "onPaymentMethodError"
31
52
  ]
32
53
  }
33
54
 
55
+ @objc
56
+ override func addListener(_ eventName: String) {
57
+ super.addListener(eventName)
58
+ }
59
+
60
+ @objc
61
+ override func removeListeners(_ count: Double) {
62
+ super.removeListeners(count)
63
+ }
64
+
34
65
  /**
35
66
  * Initialize the Yuno SDK with configuration.
36
67
  */
@@ -55,28 +86,36 @@ class YunoSdk: RCTEventEmitter {
55
86
  self.currentLanguage = lang
56
87
  }
57
88
 
58
- // Parse card flow
59
- var cardFlow: YunoCardFlow = .oneStep
60
- if let flow = yunoConfig["cardFlow"] as? String {
61
- cardFlow = self.mapToCardFlow(flow)
89
+ // Parse card flow (React Native sends "cardType", not "cardFlow")
90
+ var cardFlow: CardFormType = .oneStep
91
+ if let flow = yunoConfig["cardType"] as? String {
92
+ cardFlow = self.mapToCardFormType(flow)
62
93
  }
63
94
 
64
95
  // Parse other config options
65
- let saveCardEnabled = yunoConfig["saveCardEnabled"] as? Bool ?? false
66
- let keepLoader = yunoConfig["keepLoader"] as? Bool ?? false
96
+ let saveCardEnabled = yunoConfig["savedCardEnable"] as? Bool ?? false
97
+ // keepLoader is inverted from showPaymentStatus (if showPaymentStatus is false, keepLoader should be true)
98
+ let showPaymentStatus = yunoConfig["showPaymentStatus"] as? Bool ?? true
99
+ let keepLoader = !showPaymentStatus
67
100
 
68
101
  // Initialize Yuno SDK
69
102
  Yuno.initialize(
70
103
  apiKey: apiKey,
71
104
  config: YunoConfig(
72
- cardFlow: cardFlow,
105
+ cardFormType: cardFlow,
73
106
  saveCardEnabled: saveCardEnabled,
74
107
  keepLoader: keepLoader
75
- )
108
+ ),
109
+ callback: {
110
+ print("✅ Yuno.initialize callback invoked")
111
+ resolver(nil)
112
+ }
76
113
  )
77
114
 
115
+ // Mark as initialized immediately after calling initialize (not inside callback)
116
+ // Similar to Android's approach where it marks immediately after Yuno.initialize()
78
117
  self.isInitialized = true
79
- resolver(nil)
118
+ print("✅ YunoSdk module marked as initialized (countryCode: \(countryCode), language: \(self.currentLanguage ?? "nil"))")
80
119
  } catch {
81
120
  rejecter("INITIALIZATION_ERROR", "Failed to initialize Yuno SDK: \(error.localizedDescription)", error)
82
121
  }
@@ -155,20 +194,20 @@ class YunoSdk: RCTEventEmitter {
155
194
  throw NSError(domain: "YunoSdk", code: -1, userInfo: [NSLocalizedDescriptionKey: "methodSelected is required"])
156
195
  }
157
196
 
158
- guard let vaultedToken = methodSelected["vaultedToken"] as? String, !vaultedToken.isEmpty else {
159
- throw NSError(domain: "YunoSdk", code: -1, userInfo: [NSLocalizedDescriptionKey: "vaultedToken is required"])
160
- }
161
-
162
197
  guard let paymentMethodType = methodSelected["paymentMethodType"] as? String, !paymentMethodType.isEmpty else {
163
198
  throw NSError(domain: "YunoSdk", code: -1, userInfo: [NSLocalizedDescriptionKey: "paymentMethodType is required"])
164
199
  }
165
200
 
201
+ // vaultedToken is OPTIONAL (only required when using saved cards)
202
+ let vaultedToken = methodSelected["vaultedToken"] as? String
203
+
166
204
  let showPaymentStatus = arguments["showPaymentStatus"] as? Bool ?? true
167
205
 
168
206
  self.checkoutSession = checkoutSession
169
207
  self.currentCountryCode = countryCode
170
208
 
171
- let paymentSelected = Yuno.PaymentSelected(
209
+ // Create a PaymentMethodSelected implementation
210
+ let paymentSelected = PaymentMethodSelection(
172
211
  paymentMethodType: paymentMethodType,
173
212
  vaultedToken: vaultedToken
174
213
  )
@@ -201,12 +240,9 @@ class YunoSdk: RCTEventEmitter {
201
240
  }
202
241
 
203
242
  DispatchQueue.main.async {
204
- do {
205
- Yuno.startPayment(showPaymentStatus: showPaymentStatus)
206
- resolver(nil)
207
- } catch {
208
- rejecter("PAYMENT_ERROR", "Failed to start payment: \(error.localizedDescription)", error)
209
- }
243
+ // Start payment using the delegate already registered via getPaymentMethodViewAsync
244
+ Yuno.startPayment(showPaymentStatus: showPaymentStatus)
245
+ resolver(nil)
210
246
  }
211
247
  }
212
248
 
@@ -215,7 +251,9 @@ class YunoSdk: RCTEventEmitter {
215
251
  */
216
252
  @objc
217
253
  func continuePayment(
218
- _ showPaymentStatus: Bool,
254
+ _ checkoutSession: String,
255
+ countryCode: String,
256
+ showPaymentStatus: Bool,
219
257
  resolver: @escaping RCTPromiseResolveBlock,
220
258
  rejecter: @escaping RCTPromiseRejectBlock
221
259
  ) {
@@ -224,13 +262,18 @@ class YunoSdk: RCTEventEmitter {
224
262
  return
225
263
  }
226
264
 
227
- DispatchQueue.main.async {
228
- do {
229
- Yuno.continuePayment()
230
- resolver(nil)
231
- } catch {
232
- rejecter("CONTINUE_PAYMENT_ERROR", "Failed to continue payment: \(error.localizedDescription)", error)
233
- }
265
+ DispatchQueue.main.async { [weak self] in
266
+ guard let self = self else { return }
267
+
268
+ // Update checkout session and country code for the delegate
269
+ self.checkoutSession = checkoutSession
270
+ self.currentCountryCode = countryCode
271
+
272
+ // Continue payment using the delegate already registered
273
+ // The SDK will read checkoutSession and countryCode from the delegate properties
274
+ Yuno.continuePayment()
275
+
276
+ resolver(nil)
234
277
  }
235
278
  }
236
279
 
@@ -261,14 +304,13 @@ class YunoSdk: RCTEventEmitter {
261
304
  throw NSError(domain: "YunoSdk", code: -1, userInfo: [NSLocalizedDescriptionKey: "methodSelected is required"])
262
305
  }
263
306
 
264
- guard let vaultedToken = methodSelected["vaultedToken"] as? String, !vaultedToken.isEmpty else {
265
- throw NSError(domain: "YunoSdk", code: -1, userInfo: [NSLocalizedDescriptionKey: "vaultedToken is required"])
266
- }
267
-
268
307
  guard let paymentMethodType = methodSelected["paymentMethodType"] as? String, !paymentMethodType.isEmpty else {
269
308
  throw NSError(domain: "YunoSdk", code: -1, userInfo: [NSLocalizedDescriptionKey: "paymentMethodType is required"])
270
309
  }
271
310
 
311
+ // vaultedToken is OPTIONAL (only required when using saved cards)
312
+ let vaultedToken = methodSelected["vaultedToken"] as? String
313
+
272
314
  let showPaymentStatus = arguments["showPaymentStatus"] as? Bool ?? true
273
315
 
274
316
  var countryCode = arguments["countryCode"] as? String
@@ -283,7 +325,7 @@ class YunoSdk: RCTEventEmitter {
283
325
  self.checkoutSession = checkoutSession
284
326
  self.currentCountryCode = safeCountryCode
285
327
 
286
- let paymentSelected = Yuno.PaymentSelected(
328
+ let paymentSelected = PaymentMethodSelection(
287
329
  paymentMethodType: paymentMethodType,
288
330
  vaultedToken: vaultedToken
289
331
  )
@@ -343,30 +385,84 @@ class YunoSdk: RCTEventEmitter {
343
385
  }
344
386
  }
345
387
 
388
+ /**
389
+ * Gets the last One Time Token (OTT) that was generated.
390
+ */
391
+ @objc
392
+ func getLastOneTimeToken(
393
+ _ resolver: @escaping RCTPromiseResolveBlock,
394
+ rejecter: @escaping RCTPromiseRejectBlock
395
+ ) {
396
+ // iOS doesn't need this implementation since tokens are emitted immediately
397
+ // Return nil as there's no stored token
398
+ resolver(nil)
399
+ }
400
+
401
+ /**
402
+ * Gets the last OneTimeTokenInfo object stored by the SDK.
403
+ */
404
+ @objc
405
+ func getLastOneTimeTokenInfo(
406
+ _ resolver: @escaping RCTPromiseResolveBlock,
407
+ rejecter: @escaping RCTPromiseRejectBlock
408
+ ) {
409
+ // iOS doesn't need this implementation since tokens are emitted immediately
410
+ // Return nil as there's no stored token info
411
+ resolver(nil)
412
+ }
413
+
414
+ /**
415
+ * Clears the last OTT tokens stored by the SDK.
416
+ */
417
+ @objc
418
+ func clearLastOneTimeToken(
419
+ _ resolver: @escaping RCTPromiseResolveBlock,
420
+ rejecter: @escaping RCTPromiseRejectBlock
421
+ ) {
422
+ // iOS doesn't need this implementation since tokens aren't stored
423
+ // Just resolve successfully
424
+ resolver(nil)
425
+ }
426
+
427
+ /**
428
+ * Clears the last payment status to prevent stale status from previous flows.
429
+ */
430
+ @objc
431
+ func clearLastPaymentStatus(
432
+ _ resolver: @escaping RCTPromiseResolveBlock,
433
+ rejecter: @escaping RCTPromiseRejectBlock
434
+ ) {
435
+ // Don't set to nil - keep the last status to compare against stale events
436
+ // Just mark that we're starting a fresh flow
437
+ isPaymentFlowCleared = true
438
+ print("💫 Payment status cleared - fresh flow starting (last status was: \(lastPaymentStatus ?? "nil"))")
439
+ resolver(true)
440
+ }
441
+
346
442
  // MARK: - Helper Methods
347
443
 
348
- private func mapToCardFlow(_ cardFlow: String) -> YunoCardFlow {
349
- switch cardFlow {
350
- case "STEP_BY_STEP":
444
+ private func mapToCardFormType(_ cardFormType: String) -> CardFormType {
445
+ switch cardFormType.uppercased() {
446
+ case "STEP_BY_STEP", "TWO_STEPS":
351
447
  return .multiStep
352
448
  default:
353
449
  return .oneStep
354
450
  }
355
451
  }
356
452
 
357
- private func mapStatusToString(_ status: YunoPaymentStatus) -> String {
358
- switch status {
359
- case .rejected:
453
+ private func mapResultToString(_ result: Yuno.Result) -> String {
454
+ switch result {
455
+ case .reject:
360
456
  return "REJECTED"
361
457
  case .succeeded:
362
458
  return "SUCCEEDED"
363
- case .failed:
459
+ case .fail:
364
460
  return "FAILED"
365
461
  case .processing:
366
462
  return "PROCESSING"
367
463
  case .internalError:
368
464
  return "INTERNAL_ERROR"
369
- case .cancelledByUser:
465
+ case .userCancelled:
370
466
  return "CANCELLED_BY_USER"
371
467
  @unknown default:
372
468
  return "INTERNAL_ERROR"
@@ -375,21 +471,55 @@ class YunoSdk: RCTEventEmitter {
375
471
 
376
472
  // MARK: - Event Emitters
377
473
 
378
- private func sendPaymentStatusEvent(status: YunoPaymentStatus, token: String? = nil) {
379
- var params: [String: Any] = ["status": mapStatusToString(status)]
474
+ internal func sendPaymentStatusEvent(result: Yuno.Result, token: String? = nil) {
475
+ let statusString = mapResultToString(result)
476
+ sendPaymentStatusEvent(status: statusString, token: token)
477
+ }
478
+
479
+ internal func sendPaymentStatusEvent(status: String, token: String? = nil) {
480
+ // If we just cleared the status and this is the same status as before,
481
+ // it's a stale event from the native SDK - ignore it
482
+ if isPaymentFlowCleared && status == lastPaymentStatus {
483
+ print("🚫 Ignoring stale payment status: \(status) (from previous flow)")
484
+ isPaymentFlowCleared = false
485
+ lastPaymentStatus = nil // Clear it now that we've ignored the stale event
486
+ return
487
+ }
488
+
489
+ // Reset the cleared flag after processing first real new event
490
+ if isPaymentFlowCleared {
491
+ print("✅ First new status after clear: \(status) (previous was: \(lastPaymentStatus ?? "nil"))")
492
+ isPaymentFlowCleared = false
493
+ }
494
+
495
+ // Store the current status for future comparison
496
+ lastPaymentStatus = status
497
+
498
+ print("✅ Emitting payment status: \(status)")
499
+ var params: [String: Any] = ["status": status]
380
500
  if let token = token {
381
501
  params["token"] = token
382
502
  }
383
503
  sendEvent(withName: "YunoPaymentStatus", body: params)
384
504
  }
385
505
 
386
- private func sendEnrollmentStatusEvent(status: YunoPaymentStatus) {
387
- let params: [String: Any] = ["status": mapStatusToString(status)]
506
+ private func sendEnrollmentStatusEvent(result: Yuno.Result) {
507
+ let params: [String: Any] = ["status": mapResultToString(result)]
388
508
  sendEvent(withName: "YunoEnrollmentStatus", body: params)
389
509
  }
390
510
 
391
- private func sendOneTimeTokenEvent(token: String) {
511
+ internal func sendOneTimeTokenEvent(token: String) {
392
512
  sendEvent(withName: "YunoOneTimeToken", body: token)
513
+
514
+ // Also emit the OneTimeTokenInfo event with the token
515
+ let tokenInfo: [String: Any] = [
516
+ "token": token
517
+ ]
518
+ sendEvent(withName: "YunoOneTimeTokenInfo", body: tokenInfo)
519
+ }
520
+
521
+ private func sendOneTimeTokenInfoEvent(tokenInfo: [String: Any]) {
522
+ sendEvent(withName: "YunoOneTimeTokenInfo", body: tokenInfo)
393
523
  }
394
524
  }
395
525
 
@@ -399,44 +529,33 @@ extension YunoSdk: YunoPaymentDelegate {
399
529
  sendOneTimeTokenEvent(token: token)
400
530
  }
401
531
 
532
+ func yunoCreatePayment(with token: String, information: [String : Any]) {
533
+ // Send both token and token info
534
+ sendOneTimeTokenEvent(token: token)
535
+ sendOneTimeTokenInfoEvent(tokenInfo: information)
536
+ }
537
+
402
538
  func yunoPaymentResult(_ result: Yuno.Result) {
403
- sendPaymentStatusEvent(status: mapResultToStatus(result))
539
+ sendPaymentStatusEvent(result: result)
404
540
  }
405
541
 
406
542
  var countryCode: String {
407
543
  return currentCountryCode ?? ""
408
544
  }
409
545
 
410
- var checkoutSession: String {
411
- return self.checkoutSession
546
+ var language: String? {
547
+ return currentLanguage
412
548
  }
413
549
 
414
- private func mapResultToStatus(_ result: Yuno.Result) -> YunoPaymentStatus {
415
- switch result {
416
- case .succeeded:
417
- return .succeeded
418
- case .failed:
419
- return .failed
420
- case .rejected:
421
- return .rejected
422
- case .processing:
423
- return .processing
424
- case .cancelledByUser:
425
- return .cancelledByUser
426
- @unknown default:
427
- return .internalError
428
- }
550
+ var viewController: UIViewController? {
551
+ return RCTPresentedViewController()
429
552
  }
430
553
  }
431
554
 
432
555
  // MARK: - YunoEnrollmentDelegate Extension
433
556
  extension YunoSdk: YunoEnrollmentDelegate {
434
557
  func yunoEnrollmentResult(_ result: Yuno.Result) {
435
- sendEnrollmentStatusEvent(status: mapResultToStatus(result))
436
- }
437
-
438
- var customerSession: String {
439
- return self.customerSession
558
+ sendEnrollmentStatusEvent(result: result)
440
559
  }
441
560
  }
442
561
 
@@ -42,11 +42,11 @@ const NativeYunoPaymentMethodsView = (0, _reactNative.requireNativeComponent)('Y
42
42
  * YunoPaymentMethods Component
43
43
  *
44
44
  * A React Native component that displays available payment methods using the native Yuno SDK.
45
- * This component embeds the native `PaymentMethodListViewComponent` from the Yuno Android SDK.
45
+ * This component embeds the native payment methods list view from the Yuno SDK.
46
46
  *
47
47
  * **Platform Support:**
48
48
  * - ✅ Android (using Jetpack Compose)
49
- * - ⚠️ iOS (coming soon)
49
+ * - iOS (using SwiftUI with UIHostingController)
50
50
  *
51
51
  * **Important:**
52
52
  * - The Yuno SDK must be initialized before using this component
@@ -87,6 +87,10 @@ const NativeYunoPaymentMethodsView = (0, _reactNative.requireNativeComponent)('Y
87
87
  * - User interactions and selections
88
88
  * - Error states and loading indicators
89
89
  *
90
+ * **Technical Note:** On iOS, uses `UIHostingController` to wrap the SwiftUI view from
91
+ * Yuno SDK's `getPaymentMethodViewAsync`, providing seamless integration with React Native.
92
+ * Android uses Jetpack Compose with native `PaymentMethodListViewComponent`.
93
+ *
90
94
  * @public
91
95
  */
92
96
  const YunoPaymentMethods = ({
@@ -94,7 +98,8 @@ const YunoPaymentMethods = ({
94
98
  countryCode,
95
99
  onPaymentMethodSelected,
96
100
  onPaymentMethodError,
97
- style
101
+ style,
102
+ testID
98
103
  }) => {
99
104
  // Set up event listeners
100
105
  (0, _react.useEffect)(() => {
@@ -129,13 +134,8 @@ const YunoPaymentMethods = ({
129
134
  });
130
135
  };
131
136
  }, [onPaymentMethodSelected, onPaymentMethodError]);
132
-
133
- // Platform check
134
- if (_reactNative.Platform.OS !== 'android') {
135
- console.warn('YunoPaymentMethods: This component is currently only supported on Android. iOS support coming soon.');
136
- return null;
137
- }
138
137
  return /*#__PURE__*/_react.default.createElement(NativeYunoPaymentMethodsView, {
138
+ testID: testID,
139
139
  checkoutSession: checkoutSession,
140
140
  countryCode: countryCode,
141
141
  style: style
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","LINKING_ERROR","Platform","select","ios","YunoSdkNative","NativeModules","YunoSdk","eventEmitter","NativeEventEmitter","NativeYunoPaymentMethodsView","requireNativeComponent","YunoPaymentMethods","checkoutSession","countryCode","onPaymentMethodSelected","onPaymentMethodError","style","useEffect","console","warn","subscriptions","selectionListener","addListener","event","push","errorListener","forEach","sub","remove","OS","createElement","exports"],"sourceRoot":"../../src","sources":["YunoPaymentMethods.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","LINKING_ERROR","Platform","select","ios","YunoSdkNative","NativeModules","YunoSdk","eventEmitter","NativeEventEmitter","NativeYunoPaymentMethodsView","requireNativeComponent","YunoPaymentMethods","checkoutSession","countryCode","onPaymentMethodSelected","onPaymentMethodError","style","testID","useEffect","console","warn","subscriptions","selectionListener","addListener","event","push","errorListener","forEach","sub","remove","createElement","exports"],"sourceRoot":"../../src","sources":["YunoPaymentMethods.tsx"],"mappings":"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","ignoreList":[]}
@@ -6,20 +6,30 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.YunoSdk = void 0;
7
7
  var _reactNative = require("react-native");
8
8
  var _enums = require("./core/enums");
9
- const LINKING_ERROR = `The package '@y.uno/yuno-sdk-react-native' doesn't seem to be linked. Make sure: \n\n` + _reactNative.Platform.select({
9
+ const LINKING_ERROR = `The package '@yuno/yuno-sdk-react-native' doesn't seem to be linked. Make sure: \n\n` + _reactNative.Platform.select({
10
10
  ios: "- Run 'pod install'\n",
11
11
  default: ''
12
12
  }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
13
- const YunoSdkNative = _reactNative.NativeModules.YunoSdk ? _reactNative.NativeModules.YunoSdk : new Proxy({}, {
14
- get() {
13
+
14
+ /**
15
+ * Devuelve el módulo nativo YunoSdk o lanza un error de linking
16
+ */
17
+ function getYunoNative() {
18
+ const native = _reactNative.NativeModules.YunoSdk;
19
+ if (!native) {
15
20
  throw new Error(LINKING_ERROR);
16
21
  }
17
- });
22
+ return native;
23
+ }
18
24
 
19
25
  /**
20
- * Event emitter for Yuno SDK events.
26
+ * Devuelve un NativeEventEmitter para el módulo YunoSdk
27
+ * Se crea sólo cuando hace falta (no en top-level).
21
28
  */
22
- const eventEmitter = new _reactNative.NativeEventEmitter(YunoSdkNative);
29
+ function getYunoEventEmitter() {
30
+ const native = getYunoNative();
31
+ return new _reactNative.NativeEventEmitter(native);
32
+ }
23
33
 
24
34
  /**
25
35
  * Payment state event data.
@@ -125,7 +135,7 @@ class YunoSdk {
125
135
  // Store country code and language
126
136
  this.countryCode = countryCode;
127
137
  this.language = config.lang;
128
- await YunoSdkNative.initialize(apiKey, countryCode, config, iosConfig, androidConfig);
138
+ await getYunoNative().initialize(apiKey, countryCode, config, iosConfig, androidConfig);
129
139
  this.isInitialized = true;
130
140
  }
131
141
 
@@ -149,7 +159,7 @@ class YunoSdk {
149
159
  ...params,
150
160
  countryCode: params.countryCode ?? this.getCountryCode()
151
161
  };
152
- return YunoSdkNative.enrollmentPayment(args);
162
+ return getYunoNative().enrollmentPayment(args);
153
163
  }
154
164
 
155
165
  /**
@@ -173,7 +183,7 @@ class YunoSdk {
173
183
  static async startPaymentLite(params, countryCode) {
174
184
  this.checkInitialized();
175
185
  const code = countryCode ?? this.getCountryCode();
176
- return YunoSdkNative.startPaymentLite(params, code);
186
+ return getYunoNative().startPaymentLite(params, code);
177
187
  }
178
188
 
179
189
  /**
@@ -188,7 +198,7 @@ class YunoSdk {
188
198
  */
189
199
  static async startPayment(showPaymentStatus = true) {
190
200
  this.checkInitialized();
191
- return YunoSdkNative.startPayment(showPaymentStatus);
201
+ return getYunoNative().startPayment(showPaymentStatus);
192
202
  }
193
203
 
194
204
  /**
@@ -206,7 +216,7 @@ class YunoSdk {
206
216
  static async continuePayment(checkoutSession, countryCode, showPaymentStatus = true) {
207
217
  this.checkInitialized();
208
218
  const code = countryCode ?? this.getCountryCode();
209
- return YunoSdkNative.continuePayment(checkoutSession, code, showPaymentStatus);
219
+ return getYunoNative().continuePayment(checkoutSession, code, showPaymentStatus);
210
220
  }
211
221
 
212
222
  /**
@@ -235,7 +245,7 @@ class YunoSdk {
235
245
  ...params,
236
246
  countryCode: params.countryCode ?? this.getCountryCode()
237
247
  };
238
- const statusString = await YunoSdkNative.startPaymentSeamlessLite(args, this.getLanguage());
248
+ const statusString = await getYunoNative().startPaymentSeamlessLite(args, this.getLanguage());
239
249
  return statusString;
240
250
  }
241
251
 
@@ -249,7 +259,7 @@ class YunoSdk {
249
259
  */
250
260
  static async hideLoader() {
251
261
  this.checkInitialized();
252
- return YunoSdkNative.hideLoader();
262
+ return getYunoNative().hideLoader();
253
263
  }
254
264
 
255
265
  /**
@@ -272,7 +282,7 @@ class YunoSdk {
272
282
  return;
273
283
  }
274
284
  this.checkInitialized();
275
- return YunoSdkNative.receiveDeeplink(url);
285
+ return getYunoNative().receiveDeeplink(url);
276
286
  }
277
287
 
278
288
  /**
@@ -292,7 +302,7 @@ class YunoSdk {
292
302
  * ```
293
303
  */
294
304
  static async getLastOneTimeToken() {
295
- return YunoSdkNative.getLastOneTimeToken();
305
+ return getYunoNative().getLastOneTimeToken();
296
306
  }
297
307
 
298
308
  /**
@@ -309,7 +319,7 @@ class YunoSdk {
309
319
  * ```
310
320
  */
311
321
  static async getLastOneTimeTokenInfo() {
312
- return YunoSdkNative.getLastOneTimeTokenInfo();
322
+ return getYunoNative().getLastOneTimeTokenInfo();
313
323
  }
314
324
 
315
325
  /**
@@ -326,7 +336,25 @@ class YunoSdk {
326
336
  * ```
327
337
  */
328
338
  static async clearLastOneTimeToken() {
329
- return YunoSdkNative.clearLastOneTimeToken();
339
+ return getYunoNative().clearLastOneTimeToken();
340
+ }
341
+
342
+ /**
343
+ * Clears the last stored payment status.
344
+ * This should be called at the start of each new payment flow
345
+ * to prevent stale status from previous flows affecting new transactions.
346
+ *
347
+ * @returns Promise that resolves when the status is cleared
348
+ *
349
+ * @example
350
+ * ```typescript
351
+ * // Clear payment status before starting a new flow
352
+ * await YunoSdk.clearLastPaymentStatus();
353
+ * await YunoSdk.startPayment({ checkoutSession, countryCode });
354
+ * ```
355
+ */
356
+ static async clearLastPaymentStatus() {
357
+ return getYunoNative().clearLastPaymentStatus();
330
358
  }
331
359
 
332
360
  /**
@@ -352,7 +380,8 @@ class YunoSdk {
352
380
  * ```
353
381
  */
354
382
  static onPaymentStatus(listener) {
355
- const subscription = eventEmitter.addListener('YunoPaymentStatus', listener);
383
+ const emitter = getYunoEventEmitter();
384
+ const subscription = emitter.addListener('YunoPaymentStatus', listener);
356
385
  return {
357
386
  remove: () => subscription.remove()
358
387
  };
@@ -381,7 +410,8 @@ class YunoSdk {
381
410
  * ```
382
411
  */
383
412
  static onEnrollmentStatus(listener) {
384
- const subscription = eventEmitter.addListener('YunoEnrollmentStatus', listener);
413
+ const emitter = getYunoEventEmitter();
414
+ const subscription = emitter.addListener('YunoEnrollmentStatus', listener);
385
415
  return {
386
416
  remove: () => subscription.remove()
387
417
  };
@@ -404,7 +434,8 @@ class YunoSdk {
404
434
  * ```
405
435
  */
406
436
  static onOneTimeToken(listener) {
407
- const subscription = eventEmitter.addListener('YunoOneTimeToken', listener);
437
+ const emitter = getYunoEventEmitter();
438
+ const subscription = emitter.addListener('YunoOneTimeToken', listener);
408
439
  return {
409
440
  remove: () => subscription.remove()
410
441
  };
@@ -428,7 +459,8 @@ class YunoSdk {
428
459
  * ```
429
460
  */
430
461
  static onOneTimeTokenInfo(listener) {
431
- const subscription = eventEmitter.addListener('YunoOneTimeTokenInfo', listener);
462
+ const emitter = getYunoEventEmitter();
463
+ const subscription = emitter.addListener('YunoOneTimeTokenInfo', listener);
432
464
  return {
433
465
  remove: () => subscription.remove()
434
466
  };