@jimrising/easymerchantsdk-react-native 1.8.1 → 1.8.4

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.
Files changed (21) hide show
  1. package/.idea/caches/deviceStreaming.xml +22 -0
  2. package/README.md +160 -51
  3. package/android/build/.transforms/15b6a8a60a6b32d0dcaf609723cf365b/transformed/classes/classes_dex/classes.dex +0 -0
  4. package/android/build/.transforms/8508f1428f740032c45a43f48b1bbe1e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  5. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1$1.class.uniqueId1 +0 -0
  6. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1.class.uniqueId0 +0 -0
  7. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$2.class.uniqueId3 +0 -0
  8. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule.class.uniqueId2 +0 -0
  9. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkPackage.class.uniqueId4 +0 -0
  10. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  11. package/android/build.gradle +1 -1
  12. package/ios/Classes/EasyMerchantSdk.m +0 -1
  13. package/ios/Classes/EasyPayViewController.swift +7 -20
  14. package/ios/Models/Request.swift +221 -38
  15. package/ios/Pods/UserDefaults/UserStoreSingleton.swift +40 -11
  16. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +5 -1
  17. package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +13 -4
  18. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +7 -2
  19. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +28 -17
  20. package/ios/easymerchantsdk.podspec +1 -1
  21. package/package.json +1 -1
@@ -135,6 +135,17 @@
135
135
  <option name="screenX" value="1080" />
136
136
  <option name="screenY" value="2400" />
137
137
  </PersistentDeviceSelectionData>
138
+ <PersistentDeviceSelectionData>
139
+ <option name="api" value="35" />
140
+ <option name="brand" value="google" />
141
+ <option name="codename" value="akita" />
142
+ <option name="id" value="akita" />
143
+ <option name="manufacturer" value="Google" />
144
+ <option name="name" value="Pixel 8a" />
145
+ <option name="screenDensity" value="420" />
146
+ <option name="screenX" value="1080" />
147
+ <option name="screenY" value="2400" />
148
+ </PersistentDeviceSelectionData>
138
149
  <PersistentDeviceSelectionData>
139
150
  <option name="api" value="34" />
140
151
  <option name="brand" value="motorola" />
@@ -509,6 +520,17 @@
509
520
  <option name="screenX" value="1008" />
510
521
  <option name="screenY" value="2244" />
511
522
  </PersistentDeviceSelectionData>
523
+ <PersistentDeviceSelectionData>
524
+ <option name="api" value="34" />
525
+ <option name="brand" value="motorola" />
526
+ <option name="codename" value="lion" />
527
+ <option name="id" value="lion" />
528
+ <option name="manufacturer" value="Motorola" />
529
+ <option name="name" value="moto g04" />
530
+ <option name="screenDensity" value="280" />
531
+ <option name="screenX" value="720" />
532
+ <option name="screenY" value="1612" />
533
+ </PersistentDeviceSelectionData>
512
534
  <PersistentDeviceSelectionData>
513
535
  <option name="api" value="33" />
514
536
  <option name="brand" value="google" />
package/README.md CHANGED
@@ -7,7 +7,7 @@ To add the path of sdk in your project. Open your `package.json` file and inside
7
7
 
8
8
  ```json
9
9
  "dependencies": {
10
- "@jimrising/easymerchantsdk-react-native": "^1.8.1"
10
+ "@jimrising/easymerchantsdk-react-native": "^1.8.4"
11
11
  },
12
12
  ```
13
13
 
@@ -137,29 +137,47 @@ const App = () => {
137
137
  const [email, setEmail] = useState('');
138
138
  const [environment, setEnvironment] = useState('sandbox');
139
139
  const [isRecurring, setIsRecurring] = useState(false);
140
- const [emailEditable, setEmailEditable] = useState(true); // Android only
141
- const [isEmail, setIsEmail] = useState(true); // iOS only
140
+ const [isAuthenticatedACH, setAuthenticatedACH] = useState(false);
141
+ const [isSecureAuthentication, setSecureAuthentication] = useState(false);
142
+ const [isBillingVisible, setBillingVisible] = useState(false);
143
+ const [isAdditionalVisible, setAdditionalVisible] = useState(false);
144
+ const [emailEditable, setEmailEditable] = useState(true);
145
+ const [isEmail, setIsEmail] = useState(true);
142
146
  const [result, setResult] = useState('');
143
147
  const [referenceToken, setReferenceToken] = useState('');
144
148
  const [loading, setLoading] = useState(false);
149
+ const [apiKey, setApiKey] = useState('');
150
+ const [apiSecret, setApiSecret] = useState('');
145
151
 
146
- useEffect(() => {
147
- const setupIOS = async () => {
148
- if (Platform.OS === 'ios') {
149
- try {
150
- await EasyMerchantSdk.setViewController();
151
- await EasyMerchantSdk.configureEnvironment(
152
- environment,
153
- 'apiKey',
154
- 'secretKey'
155
- );
156
- } catch (err) {
157
- console.error('iOS Initialization Error:', err);
158
- }
152
+ useEffect(() => {
153
+ const key = environment === 'staging'
154
+ ? 'stagingApiKey'
155
+ : 'sandboxApiKey';
156
+
157
+ const secret = environment === 'staging'
158
+ ? 'stagingApiSecretKey'
159
+ : 'sandboxApiSecretKey';
160
+
161
+ setApiKey(key);
162
+ setApiSecret(secret);
163
+
164
+ const setupIOS = async () => {
165
+ if (Platform.OS === 'ios') {
166
+ try {
167
+ await EasyMerchantSdk.setViewController();
168
+ await EasyMerchantSdk.configureEnvironment(
169
+ environment,
170
+ key,
171
+ secret
172
+ );
173
+ } catch (err) {
174
+ console.error('iOS Initialization Error:', err);
159
175
  }
160
- };
161
- setupIOS();
162
- }, [environment]);
176
+ }
177
+ };
178
+ setupIOS();
179
+ }, [environment]);
180
+
163
181
 
164
182
  const handlePayment = async () => {
165
183
  if (!amount || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0) {
@@ -174,8 +192,8 @@ const App = () => {
174
192
  if (Platform.OS === 'android') {
175
193
  const config = {
176
194
  amount,
177
- apiKey: 'apiKey',
178
- secretKey: 'secretKey',
195
+ apiKey: apiKey,
196
+ secretKey: apiSecret,
179
197
  jsonConfig: {
180
198
  environment,
181
199
  amount,
@@ -183,8 +201,8 @@ const App = () => {
183
201
  currency: 'usd',
184
202
  saveCard: true,
185
203
  saveAccount: true,
186
- authenticatedACH: true,
187
- secureAuthentication: false,
204
+ authenticatedACH: isAuthenticatedACH,
205
+ secureAuthentication: isSecureAuthentication,
188
206
  showReceipt: true,
189
207
  showDonate: false,
190
208
  showTotal: true,
@@ -194,18 +212,18 @@ const App = () => {
194
212
  email,
195
213
  name: 'Pavan',
196
214
  fields: {
197
- visibility: { billing: true, additional: false },
215
+ visibility: { billing: isBillingVisible, additional: isAdditionalVisible },
198
216
  billing: [
199
217
  { name: 'address', required: true, value: 'New Address' },
200
- { name: 'country', required: true, value: 'USA' },
218
+ { name: 'country', required: true, value: 'India' },
201
219
  { name: 'state', required: true, value: 'California' },
202
- { name: 'city', required: true, value: 'California' },
220
+ { name: 'city', required: true, value: 'Goa' },
203
221
  { name: 'postal_code', required: true, value: '1432456' },
204
222
  ],
205
223
  additional: [
206
224
  { name: 'name', required: true, value: 'Test User 7' },
207
225
  { name: 'email_address', required: true, value: 'usertest@gmail.com' },
208
- { name: 'phone_number', required: false, value: '8978967895' },
226
+ { name: 'phone_number', required: true, value: '8978967895' },
209
227
  { name: 'description', required: true, value: 'Hi This is description' },
210
228
  ],
211
229
  },
@@ -252,6 +270,7 @@ const App = () => {
252
270
  const response = await RNEasymerchantsdk.makePayment(config);
253
271
  console.log('Full payment response:', response);
254
272
  setResult(JSON.stringify(response, null, 2));
273
+
255
274
  } catch (error) {
256
275
  setResult(`Error: ${error.message}`);
257
276
  Alert.alert('Payment Error', error.message);
@@ -265,9 +284,9 @@ const App = () => {
265
284
 
266
285
  const handleBilling = async () => {
267
286
  const billingInfo = {
268
- visibility: { billing: false, additional: false },
287
+ visibility: { billing: isBillingVisible, additional: isAdditionalVisible },
269
288
  billing: {
270
- address: 'San Fran',
289
+ address: 'San Fransisco',
271
290
  country: 'USA',
272
291
  state: 'California',
273
292
  city: 'Paris',
@@ -294,22 +313,23 @@ const App = () => {
294
313
  },
295
314
  };
296
315
 
297
- const themeConfiguration = {
298
- bodyBackgroundColor: "#121212",
299
- containerBackgroundColor: "#1E1E1E",
300
- primaryFontColor: "#FFFFFF",
301
- secondaryFontColor: "#B0B0B0",
302
- primaryButtonBackgroundColor: "#2563EB",
303
- primaryButtonHoverColor: "#1D4ED8",
304
- primaryButtonFontColor: "#FFFFFF",
305
- secondaryButtonBackgroundColor: "#374151",
306
- secondaryButtonHoverColor: "#4B5563",
307
- secondaryButtonFontColor: "#E5E7EB",
308
- borderRadius: "8",
309
- fontSize: "14",
310
- fontWeight: 500,
311
- fontFamily: "\"Inter\", sans-serif"
312
- };
316
+ const themeConfiguration = {
317
+ bodyBackgroundColor: "#0f1715",
318
+ containerBackgroundColor: "#152321",
319
+ primaryFontColor: "#FFFFFF",
320
+ secondaryFontColor: "#A0B5A4",
321
+ primaryButtonBackgroundColor: "#10B981",
322
+ primaryButtonHoverColor: "#059669",
323
+ primaryButtonFontColor: "#FFFFFF",
324
+ secondaryButtonBackgroundColor: "#374151",
325
+ secondaryButtonHoverColor: "#4B5563",
326
+ secondaryButtonFontColor: "#E5E7EB",
327
+ borderRadius: "8",
328
+ fontSize: "14",
329
+ fontWeight: 500,
330
+ fontFamily: "\"Inter\", sans-serif"
331
+ };
332
+
313
333
 
314
334
  const authConfig = {
315
335
  role: 'business',
@@ -330,7 +350,7 @@ const App = () => {
330
350
  false, // tokenOnly
331
351
  true, // saveCard
332
352
  true, // saveAccount
333
- true, // authenticatedACH
353
+ isAuthenticatedACH, // authenticatedACH
334
354
  authConfig, // grailPayParams
335
355
  'Submit',
336
356
  isRecurring, // isRecurring
@@ -338,7 +358,7 @@ const App = () => {
338
358
  isRecurring ? ['weekly', 'monthly'] : [], // if isRecurring == true then it is required
339
359
  isRecurring ? 'custom' : '', // if isRecurring == true then it is required
340
360
  isRecurring ? '07/08/2025' : '', // if isRecurring == true then it is required
341
- true, // secureAuthentication
361
+ isSecureAuthentication, // secureAuthentication
342
362
  true, // showReceipt
343
363
  true, // showTotal
344
364
  true, // showSubmitButton
@@ -356,6 +376,20 @@ const App = () => {
356
376
  }
357
377
  };
358
378
 
379
+ const handleCheckStatus = async () => {
380
+ setLoading(true);
381
+ try {
382
+ const response = await RNEasymerchantsdk.checkPaymentStatus();
383
+ console.log('Full payment response:', response);
384
+ setResult(JSON.stringify(response, null, 2));
385
+ } catch (error) {
386
+ setResult(`Error: ${error.message}`);
387
+ Alert.alert('Status Check Error', error.message);
388
+ } finally {
389
+ setLoading(false);
390
+ }
391
+ };
392
+
359
393
  const handlePaymentReference = async () => {
360
394
  if (Platform.OS === 'android') {
361
395
  setResult('❌ Payment Reference not supported on Android');
@@ -378,6 +412,8 @@ const App = () => {
378
412
  <ScrollView contentContainerStyle={styles.scrollContent}>
379
413
  <Text style={styles.title}>EasyMerchant SDK</Text>
380
414
 
415
+ <Text style={styles.label}>amount</Text>
416
+
381
417
  <TextInput
382
418
  style={styles.input}
383
419
  placeholder="Enter amount (e.g., 10.00)"
@@ -386,6 +422,8 @@ const App = () => {
386
422
  onChangeText={setAmount}
387
423
  />
388
424
 
425
+ <Text style={styles.label}>Email</Text>
426
+
389
427
  <TextInput
390
428
  style={styles.input}
391
429
  placeholder="Enter email"
@@ -410,6 +448,38 @@ const App = () => {
410
448
  </View>
411
449
  </View>
412
450
 
451
+
452
+ <View style={styles.pickerContainer}>
453
+ <Text style={styles.label}>Billing Visible:</Text>
454
+ <View style={styles.buttonGroup}>
455
+ <Button
456
+ title="Yes"
457
+ onPress={() => setBillingVisible(true)}
458
+ color={isBillingVisible ? '#2563EB' : '#ccc'}
459
+ />
460
+ <Button
461
+ title="No"
462
+ onPress={() => setBillingVisible(false)}
463
+ color={!isBillingVisible ? '#2563EB' : '#ccc'}
464
+ />
465
+ </View>
466
+ </View>
467
+
468
+ <View style={styles.pickerContainer}>
469
+ <Text style={styles.label}>Additional Info Visible:</Text>
470
+ <View style={styles.buttonGroup}>
471
+ <Button
472
+ title="Yes"
473
+ onPress={() => setAdditionalVisible(true)}
474
+ color={isAdditionalVisible ? '#2563EB' : '#ccc'}
475
+ />
476
+ <Button
477
+ title="No"
478
+ onPress={() => setAdditionalVisible(false)}
479
+ color={!isAdditionalVisible ? '#2563EB' : '#ccc'}
480
+ />
481
+ </View>
482
+ </View>
413
483
  <View style={styles.pickerContainer}>
414
484
  <Text style={styles.label}>Recurring Payment:</Text>
415
485
  <View style={styles.buttonGroup}>
@@ -426,6 +496,38 @@ const App = () => {
426
496
  </View>
427
497
  </View>
428
498
 
499
+ <View style={styles.pickerContainer}>
500
+ <Text style={styles.label}>AuthenticatedACH:</Text>
501
+ <View style={styles.buttonGroup}>
502
+ <Button
503
+ title="Yes"
504
+ onPress={() => setAuthenticatedACH(true)}
505
+ color={isAuthenticatedACH ? '#2563EB' : '#ccc'}
506
+ />
507
+ <Button
508
+ title="No"
509
+ onPress={() => setAuthenticatedACH(false)}
510
+ color={!isAuthenticatedACH ? '#2563EB' : '#ccc'}
511
+ />
512
+ </View>
513
+ </View>
514
+
515
+ <View style={styles.pickerContainer}>
516
+ <Text style={styles.label}>SecureAuthentication:</Text>
517
+ <View style={styles.buttonGroup}>
518
+ <Button
519
+ title="Yes"
520
+ onPress={() => setSecureAuthentication(true)}
521
+ color={isSecureAuthentication ? '#2563EB' : '#ccc'}
522
+ />
523
+ <Button
524
+ title="No"
525
+ onPress={() => setSecureAuthentication(false)}
526
+ color={!isSecureAuthentication ? '#2563EB' : '#ccc'}
527
+ />
528
+ </View>
529
+ </View>
530
+
429
531
  {Platform.OS === 'android' ? (
430
532
  <View style={styles.pickerContainer}>
431
533
  <Text style={styles.label}>Email Editable (Android):</Text>
@@ -460,10 +562,17 @@ const App = () => {
460
562
  </View>
461
563
  )}
462
564
 
463
- <View style={styles.buttonGroup}>
464
- <Button title="Pay" onPress={handlePayment} />
465
- <Button title="Payment Ref" onPress={handlePaymentReference} />
466
- </View>
565
+
566
+ <View style={styles.buttonGroup}>
567
+ <Button title="Pay" onPress={handlePayment} />
568
+ {Platform.OS === 'ios' ? (
569
+ <Button title="Payment Ref" onPress={handlePaymentReference} />
570
+ ) : (
571
+ <Button title="Check Status" onPress={handleCheckStatus} disabled={loading} />
572
+ )}
573
+ </View>
574
+
575
+
467
576
 
468
577
  <Text selectable style={styles.result}>{result}</Text>
469
578
  </ScrollView>
@@ -39,7 +39,7 @@ repositories {
39
39
  }
40
40
 
41
41
  dependencies {
42
- implementation 'com.app:paysdk:1.3.6'
42
+ implementation 'com.app:paysdk:1.3.7'
43
43
  implementation 'com.hbb20:ccp:2.7.3'
44
44
  implementation 'com.github.bumptech.glide:glide:4.16.0'
45
45
  implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1"
@@ -11,7 +11,6 @@
11
11
 
12
12
  @implementation EasyMerchantSdk
13
13
 
14
-
15
14
  RCT_EXPORT_MODULE()
16
15
 
17
16
  RCT_EXPORT_METHOD(configureEnvironment:(NSString *)env
@@ -7,13 +7,11 @@
7
7
 
8
8
  import UIKit
9
9
 
10
- // @available(iOS 16.0, *)
11
10
  @objc
12
11
  public protocol EasyPayViewControllerDelegate {
13
12
  func easyPayController(_ controller: EasyPayViewController, didFinishWith result: SDKResult)
14
13
  }
15
14
 
16
- // @available(iOS 16.0, *)
17
15
  @objc
18
16
  public final class EasyPayViewController: UINavigationController {
19
17
 
@@ -48,8 +46,8 @@ public final class EasyPayViewController: UINavigationController {
48
46
  super.init(nibName: nil, bundle: nil)
49
47
 
50
48
  if let themeConfiguration = request.themeConfiguration {
51
- UserStoreSingleton.shared.updateThemeConfiguration(with: themeConfiguration)
52
- }
49
+ UserStoreSingleton.shared.updateThemeConfiguration(with: themeConfiguration)
50
+ }
53
51
 
54
52
  self.modalPresentationStyle = .fullScreen
55
53
  self.isModalInPresentation = true
@@ -63,30 +61,19 @@ public final class EasyPayViewController: UINavigationController {
63
61
  let vc = UIStoryboard(name: "easymerchantsdk", bundle: Bundle.easyPayBundle).instantiateViewController(withIdentifier: "PaymentInfoVC") as! PaymentInfoVC
64
62
  vc.modalPresentationStyle = .overFullScreen
65
63
  vc.configureWith(request: request, delegate: easyPayDelegate)
66
- vc.amount = Int(request.amount ?? 0.0) // Set the amount here
64
+ vc.amount = Int(request.amount ?? 0) // Set the amount here.
65
+ vc.selectedPaymentMethod = "Card"
66
+
67
+ vc.logOut()
67
68
  self.navigationBar.isHidden = true
68
69
  self.setViewControllers([vc], animated: false)
69
70
  }
70
-
71
- }
72
-
73
- // @available(iOS 16.0, *)
74
- private extension EasyPayViewController {
75
- func setupDetents() {
76
- if let sheetController = self.sheetPresentationController {
77
- sheetController.prefersGrabberVisible = false
78
- var detents: [UISheetPresentationController.Detent] = []
79
- detents.append(.large())
80
- sheetController.detents = detents
81
- }
82
- }
71
+
83
72
  }
84
73
 
85
74
  private extension EasyPayViewController {
86
-
87
75
  private static func runFirstTimeSetup() {
88
76
  UIFont.registerEasyPayFonts()
89
77
  Self.isFirstTimeSetupComleted = true
90
78
  }
91
-
92
79
  }
@@ -171,7 +171,7 @@ public final class Request: NSObject {
171
171
  public let isEmail: Bool?
172
172
  public let email: String?
173
173
  public let name: String?
174
-
174
+
175
175
  public init(
176
176
  amount: Double? = nil,
177
177
  currency: String? = nil,
@@ -284,6 +284,13 @@ public final class Request: NSObject {
284
284
 
285
285
  super.init()
286
286
 
287
+ // /// ✅ Clear old user data first
288
+ // DispatchQueue.main.async {
289
+ // if let topVC = UIApplication.topViewController() as? PaymentInfoVC {
290
+ // topVC.logOut()
291
+ // }
292
+ // }
293
+
287
294
  // If tokenOnly is true, fetch only the clientToken and do not open the SDK
288
295
  if tokenOnly {
289
296
  self.paymentIntentApi { success in
@@ -315,93 +322,237 @@ public final class Request: NSObject {
315
322
  }
316
323
 
317
324
  //MARK: - Payment Intent Api
325
+ // func paymentIntentApi(completion: @escaping (Bool) -> Void) {
326
+ // guard let serviceURL = URL(string: EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.paymentIntent.path()) else {
327
+ // showErrorAndDismiss(message: "Invalid payment URL.")
328
+ // completion(false)
329
+ // return
330
+ // }
331
+ //
332
+ // var request = URLRequest(url: serviceURL)
333
+ // request.httpMethod = "POST"
334
+ // request.addValue("application/json", forHTTPHeaderField: "Content-Type")
335
+ // request.addValue(EnvironmentConfig.apiKey ?? "", forHTTPHeaderField: "X-Api-Key")
336
+ // request.addValue(EnvironmentConfig.apiSecret ?? "", forHTTPHeaderField: "X-Api-Secret")
337
+ //
338
+ // // Recurring date validation
339
+ // if let startDateString = recurringStartDate,
340
+ // let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
341
+ // let today = Calendar.current.startOfDay(for: Date())
342
+ // let startDay = Calendar.current.startOfDay(for: startDate)
343
+ //
344
+ // if startDay < today {
345
+ // showErrorAndDismiss(message: "The recurring start date cannot be in the past. Please select today or a future date.")
346
+ // completion(false)
347
+ // return
348
+ // }
349
+ // }
350
+ //
351
+ // let params: [String: Any] = [
352
+ // "amount": amount ?? 0,
353
+ // // "allowed_cycles": String(recurringIntervals?.count ?? 0),
354
+ // "allowed_cycles": numOfCycle ?? 0,
355
+ // "intervals": recurringIntervals?.map { $0.rawValue } ?? [],
356
+ // "is_recurring": self.is_recurring ?? false,
357
+ // "recurring_start_date": recurringStartDate ?? "",
358
+ // "recurring_start_date_type": recurringStartDateType?.rawValue ?? ""
359
+ // ]
360
+ //
361
+ // do {
362
+ // request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
363
+ // } catch {
364
+ // showErrorAndDismiss(message: "Failed to encode payment data.")
365
+ // completion(false)
366
+ // return
367
+ // }
368
+ //
369
+ // let task = URLSession.shared.dataTask(with: request) { data, response, error in
370
+ // guard let httpResponse = response as? HTTPURLResponse, error == nil else {
371
+ // self.showErrorAndDismiss(message: error?.localizedDescription ?? "An unknown error occurred.")
372
+ // completion(false)
373
+ // return
374
+ // }
375
+ //
376
+ // if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
377
+ // if let data = data {
378
+ // do {
379
+ // if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
380
+ // if let clientToken = responseObject["client_token"] as? String {
381
+ // UserStoreSingleton.shared.clientToken = clientToken
382
+ // print(clientToken)
383
+ // }
384
+ // if let paymentIntent = responseObject["payment_intent"] as? String {
385
+ // UserStoreSingleton.shared.paymentIntent = paymentIntent
386
+ // }
387
+ // self.hostedCheckoutsApi { success in
388
+ // completion(success)
389
+ // }
390
+ // return
391
+ // } else {
392
+ // self.showErrorAndDismiss(message: "Invalid response format.")
393
+ // }
394
+ // } catch {
395
+ // self.showErrorAndDismiss(message: "Failed to parse response.")
396
+ // }
397
+ // } else {
398
+ // self.showErrorAndDismiss(message: "No response data received.")
399
+ // }
400
+ // } else {
401
+ // var message = "Payment request failed with status code: \(httpResponse.statusCode)"
402
+ // if let data = data,
403
+ // let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
404
+ // let msg = responseObj["message"] as? String {
405
+ // message = msg
406
+ // }
407
+ // self.showErrorAndDismiss(message: message)
408
+ // }
409
+ // completion(false)
410
+ // }
411
+ //
412
+ // task.resume()
413
+ // }
414
+
415
+ // MARK: - Payment Intent Api
318
416
  func paymentIntentApi(completion: @escaping (Bool) -> Void) {
417
+ // ✅ Show Loader
418
+ DispatchQueue.main.async {
419
+ UIApplication.topViewController()?.ep_showLoadingIndicator()
420
+ }
421
+
319
422
  guard let serviceURL = URL(string: EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.paymentIntent.path()) else {
320
- showErrorAndDismiss(message: "Invalid payment URL.")
423
+ DispatchQueue.main.async {
424
+ UIApplication.topViewController()?.ep_hideLoadingIndicator()
425
+ self.showErrorAndDismiss(message: "Invalid payment URL.")
426
+ }
321
427
  completion(false)
322
428
  return
323
429
  }
324
-
430
+
325
431
  var request = URLRequest(url: serviceURL)
326
432
  request.httpMethod = "POST"
327
433
  request.addValue("application/json", forHTTPHeaderField: "Content-Type")
328
434
  request.addValue(EnvironmentConfig.apiKey ?? "", forHTTPHeaderField: "X-Api-Key")
329
435
  request.addValue(EnvironmentConfig.apiSecret ?? "", forHTTPHeaderField: "X-Api-Secret")
330
-
331
- // Recurring date validation
436
+
437
+ // Validate recurring start date
332
438
  if let startDateString = recurringStartDate,
333
439
  let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
334
440
  let today = Calendar.current.startOfDay(for: Date())
335
441
  let startDay = Calendar.current.startOfDay(for: startDate)
336
-
442
+
337
443
  if startDay < today {
338
- showErrorAndDismiss(message: "The recurring start date cannot be in the past. Please select today or a future date.")
444
+ DispatchQueue.main.async {
445
+ UIApplication.topViewController()?.ep_hideLoadingIndicator()
446
+ self.showErrorAndDismiss(message: "The recurring start date cannot be in the past. Please select today or a future date.")
447
+ }
339
448
  completion(false)
340
449
  return
341
450
  }
342
451
  }
343
-
452
+
344
453
  let params: [String: Any] = [
345
454
  "amount": amount ?? 0,
346
- // "allowed_cycles": String(recurringIntervals?.count ?? 0),
347
455
  "allowed_cycles": numOfCycle ?? 0,
348
456
  "intervals": recurringIntervals?.map { $0.rawValue } ?? [],
349
457
  "is_recurring": self.is_recurring ?? false,
350
458
  "recurring_start_date": recurringStartDate ?? "",
351
459
  "recurring_start_date_type": recurringStartDateType?.rawValue ?? ""
352
460
  ]
353
-
461
+
354
462
  do {
355
463
  request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
356
464
  } catch {
357
- showErrorAndDismiss(message: "Failed to encode payment data.")
465
+ DispatchQueue.main.async {
466
+ UIApplication.topViewController()?.ep_hideLoadingIndicator()
467
+ self.showErrorAndDismiss(message: "Failed to encode payment data.")
468
+ }
358
469
  completion(false)
359
470
  return
360
471
  }
361
-
362
- let task = URLSession.shared.dataTask(with: request) { data, response, error in
363
- guard let httpResponse = response as? HTTPURLResponse, error == nil else {
364
- self.showErrorAndDismiss(message: error?.localizedDescription ?? "An unknown error occurred.")
472
+
473
+ URLSession.shared.dataTask(with: request) { data, response, error in
474
+ defer {
475
+ DispatchQueue.main.async {
476
+ UIApplication.topViewController()?.ep_hideLoadingIndicator()
477
+ }
478
+ }
479
+
480
+ if let error = error {
481
+ DispatchQueue.main.async {
482
+ self.showErrorAndDismiss(message: error.localizedDescription)
483
+ }
365
484
  completion(false)
366
485
  return
367
486
  }
368
-
487
+
488
+ guard let httpResponse = response as? HTTPURLResponse else {
489
+ DispatchQueue.main.async {
490
+ self.showErrorAndDismiss(message: "Invalid response.")
491
+ }
492
+ completion(false)
493
+ return
494
+ }
495
+
369
496
  if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
370
- if let data = data {
371
- do {
372
- if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
373
- if let clientToken = responseObject["client_token"] as? String {
374
- UserStoreSingleton.shared.clientToken = clientToken
375
- }
376
- if let paymentIntent = responseObject["payment_intent"] as? String {
377
- UserStoreSingleton.shared.paymentIntent = paymentIntent
378
- }
379
- self.hostedCheckoutsApi { success in
380
- completion(success)
381
- }
382
- return
383
- } else {
497
+ guard let data = data else {
498
+ DispatchQueue.main.async {
499
+ self.showErrorAndDismiss(message: "No response data received.")
500
+ }
501
+ completion(false)
502
+ return
503
+ }
504
+
505
+ do {
506
+ guard let responseObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
507
+ DispatchQueue.main.async {
384
508
  self.showErrorAndDismiss(message: "Invalid response format.")
385
509
  }
386
- } catch {
510
+ completion(false)
511
+ return
512
+ }
513
+
514
+ // ✅ Save values into UserStoreSingleton
515
+ if let clientToken = responseObject["client_token"] as? String {
516
+ UserStoreSingleton.shared.clientToken = clientToken
517
+ print("✅ Saved Client Token: \(clientToken)")
518
+ }
519
+ if let paymentIntent = responseObject["payment_intent"] as? String {
520
+ UserStoreSingleton.shared.paymentIntent = paymentIntent
521
+ print("✅ Saved Payment Intent: \(paymentIntent)")
522
+ }
523
+
524
+ // ✅ Proceed to next step only after saving
525
+ self.hostedCheckoutsApi { success in
526
+ DispatchQueue.main.async {
527
+ UIApplication.topViewController()?.ep_hideLoadingIndicator()
528
+ }
529
+ completion(success)
530
+ }
531
+ return
532
+
533
+ } catch {
534
+ DispatchQueue.main.async {
387
535
  self.showErrorAndDismiss(message: "Failed to parse response.")
388
536
  }
389
- } else {
390
- self.showErrorAndDismiss(message: "No response data received.")
537
+ completion(false)
538
+ return
391
539
  }
540
+
392
541
  } else {
393
542
  var message = "Payment request failed with status code: \(httpResponse.statusCode)"
394
543
  if let data = data,
395
- let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
544
+ let responseObj = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
396
545
  let msg = responseObj["message"] as? String {
397
546
  message = msg
398
547
  }
399
- self.showErrorAndDismiss(message: message)
548
+ DispatchQueue.main.async {
549
+ self.showErrorAndDismiss(message: message)
550
+ }
400
551
  }
552
+
401
553
  completion(false)
402
- }
403
-
404
- task.resume()
554
+
555
+ }.resume()
405
556
  }
406
557
 
407
558
  private func showErrorAndDismiss(message: String) {
@@ -663,3 +814,35 @@ extension UIApplication {
663
814
  }
664
815
  }
665
816
 
817
+
818
+ extension UIViewController {
819
+
820
+ func ep_showLoadingIndicator() {
821
+ let tag = 99999 // A unique tag so we can identify and remove the loader later
822
+ if self.view.viewWithTag(tag) == nil {
823
+ let loader = UIActivityIndicatorView(style: .large)
824
+ loader.center = self.view.center
825
+ loader.tag = tag
826
+ loader.startAnimating()
827
+ loader.color = .gray
828
+ loader.hidesWhenStopped = true
829
+ loader.translatesAutoresizingMaskIntoConstraints = false
830
+ self.view.addSubview(loader)
831
+
832
+ // Optional: center constraints
833
+ NSLayoutConstraint.activate([
834
+ loader.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
835
+ loader.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
836
+ ])
837
+ }
838
+ }
839
+
840
+ func ep_hideLoadingIndicator() {
841
+ let tag = 99999
842
+ if let loader = self.view.viewWithTag(tag) as? UIActivityIndicatorView {
843
+ loader.stopAnimating()
844
+ loader.removeFromSuperview()
845
+ }
846
+ }
847
+ }
848
+
@@ -234,12 +234,6 @@ class UserStoreSingleton: NSObject {
234
234
  }
235
235
  }
236
236
 
237
- // func updateThemeConfiguration(with json: [String: Any]) {
238
- // json.forEach { key, value in
239
- // UserDefaults.standard.set(value, forKey: key)
240
- // }
241
- // }
242
-
243
237
  func updateThemeConfiguration(with themeConfiguration: ThemeConfiguration) {
244
238
  self.body_bg_col = themeConfiguration.bodyBackgroundColor
245
239
  self.container_bg_col = themeConfiguration.containerBackgroundColor
@@ -256,13 +250,38 @@ class UserStoreSingleton: NSObject {
256
250
  }
257
251
 
258
252
  // Method to clear user data from UserDefaults
253
+ // func clearUserData() {
254
+ // UserDefaults.standard.removeObject(forKey: "customer_id")
255
+ // UserDefaults.standard.removeObject(forKey: "verificationEmail")
256
+ // UserDefaults.standard.removeObject(forKey: "customer_token")
257
+ // UserDefaults.standard.removeObject(forKey: "client_token")
258
+ // UserDefaults.standard.synchronize() // Optional, but can help ensure the changes are applied immediately
259
+ // }
260
+
259
261
  func clearUserData() {
260
- UserDefaults.standard.removeObject(forKey: "customer_id")
261
- UserDefaults.standard.removeObject(forKey: "verificationEmail")
262
- UserDefaults.standard.removeObject(forKey: "customer_token")
263
- UserDefaults.standard.synchronize() // Optional, but can help ensure the changes are applied immediately
262
+ let keysToRemove = [
263
+ "client_token",
264
+ "payment_intent",
265
+ "merchant_email",
266
+ "merchant_name",
267
+ "payment_account",
268
+ "price",
269
+ "isLoggedIn",
270
+ "customer_id",
271
+ "customer_token",
272
+ "verificationEmail",
273
+ "payment_methods",
274
+ "bank_widget_key",
275
+ "vendor_id",
276
+ ]
277
+
278
+ for key in keysToRemove {
279
+ UserDefaults.standard.removeObject(forKey: key)
280
+ }
281
+
282
+ UserDefaults.standard.synchronize()
264
283
  }
265
-
284
+
266
285
  @objc private func handleAppTermination() {
267
286
  print("App is terminating. Clearing user data...")
268
287
  clearUserData()
@@ -273,3 +292,13 @@ class UserStoreSingleton: NSObject {
273
292
  }
274
293
 
275
294
  }
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
+
303
+
304
+
@@ -324,7 +324,8 @@ class AdditionalInfoVC: BaseVC {
324
324
  grailPayAccountChargeApi(customerId: UserStoreSingleton.shared.customerId)
325
325
  } else {
326
326
  // Navigate to EmailVerificationVC for all other payment methods
327
- if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
327
+ // if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
328
+ if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
328
329
 
329
330
  emailVerificationVC.billingInfoData = billingInfoData
330
331
  emailVerificationVC.selectedPaymentMethod = selectedPaymentMethod
@@ -337,6 +338,7 @@ class AdditionalInfoVC: BaseVC {
337
338
  emailVerificationVC.additionalInfo = fieldSection?.additional
338
339
  emailVerificationVC.visibility = fieldSection?.visibility
339
340
  emailVerificationVC.amount = amount
341
+ emailVerificationVC.email = userEmail
340
342
 
341
343
  // Payment method-specific data
342
344
  switch selectedPaymentMethod {
@@ -1710,6 +1712,7 @@ class AdditionalInfoVC: BaseVC {
1710
1712
  paymentDoneVC.visibility = self.visibility
1711
1713
  paymentDoneVC.amount = self.amount
1712
1714
  paymentDoneVC.cardApiParams = params
1715
+
1713
1716
  // if self.visibility?.billing == true {
1714
1717
  paymentDoneVC.billingInfoData = self.billingInfo
1715
1718
  var billingDict: [String: Any] = [:]
@@ -1907,6 +1910,7 @@ class AdditionalInfoVC: BaseVC {
1907
1910
  paymentDoneVC.visibility = self.visibility
1908
1911
  paymentDoneVC.amount = self.amount
1909
1912
  paymentDoneVC.cardApiParams = params
1913
+
1910
1914
  // if self.visibility?.billing == true {
1911
1915
  paymentDoneVC.billingInfoData = self.billingInfo
1912
1916
  var billingDict: [String: Any] = [:]
@@ -682,7 +682,8 @@ class BillingInfoVC: BaseVC {
682
682
 
683
683
  }
684
684
  else if !isAdditionalVisible && isSavedForFuture {
685
- let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
685
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
686
+ let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
686
687
  vc.cardNumber = cardNumber
687
688
  vc.expiryDate = expiryDate
688
689
  vc.cvv = cvv
@@ -754,7 +755,8 @@ class BillingInfoVC: BaseVC {
754
755
  navigationController?.pushViewController(vc, animated: true)
755
756
  }
756
757
  else if !isAdditionalVisible && isSavedForFuture {
757
- let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
758
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
759
+ let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
758
760
  vc.accountName = accountName
759
761
  vc.routingNumber = routingNumber
760
762
  vc.accountType = accountType
@@ -764,7 +766,7 @@ class BillingInfoVC: BaseVC {
764
766
  vc.fieldSection = updatedFieldSection
765
767
  vc.selectedPaymentMethod = selectedPaymentMethod
766
768
  vc.easyPayDelegate = easyPayDelegate
767
- vc.request = request
769
+ vc.request = self.request
768
770
  vc.chosenPlan = chosenPlan
769
771
  vc.startDate = startDate
770
772
  vc.billingInfo = updatedFieldSection.billing
@@ -776,6 +778,7 @@ class BillingInfoVC: BaseVC {
776
778
  vc.grailPayAccountID = grailPayAccountID
777
779
  vc.selectedGrailPayAccountType = selectedGrailPayAccountType
778
780
  vc.selectedGrailPayAccountName = selectedGrailPayAccountName
781
+ vc.email = userEmail
779
782
  navigationController?.pushViewController(vc, animated: true)
780
783
  }
781
784
  else if isFrom == "SavedBank" {
@@ -815,7 +818,8 @@ class BillingInfoVC: BaseVC {
815
818
  navigationController?.pushViewController(vc, animated: true)
816
819
  }
817
820
  else if !isAdditionalVisible && isSavedForFuture {
818
- let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
821
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
822
+ let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
819
823
  vc.billingInfoData = updatedBillingData
820
824
  vc.fieldSection = updatedFieldSection
821
825
  vc.billingInfo = updatedFieldSection.billing
@@ -833,6 +837,11 @@ class BillingInfoVC: BaseVC {
833
837
  vc.selectedGrailPayAccountType = selectedGrailPayAccountType
834
838
  vc.selectedGrailPayAccountName = selectedGrailPayAccountName
835
839
  vc.userEmail = userEmail
840
+ vc.email = userEmail
841
+
842
+ vc.grailPayAccountID = self.grailPayAccountID
843
+ vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
844
+ vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
836
845
  navigationController?.pushViewController(vc, animated: true)
837
846
  }
838
847
  else {
@@ -76,9 +76,12 @@ class OTPVerificationVC: BaseVC {
76
76
 
77
77
  var isSavedNewCard: Bool = false
78
78
 
79
+ var isSavedNewAccount: Bool?
80
+ var isFrom = String()
81
+
79
82
  override func viewDidLoad() {
80
83
  super.viewDidLoad()
81
- emailVerificationApi()
84
+ // emailVerificationApi()
82
85
 
83
86
  uiFinishingTouchElements()
84
87
 
@@ -111,6 +114,7 @@ class OTPVerificationVC: BaseVC {
111
114
  }
112
115
 
113
116
  override func viewWillAppear(_ animated: Bool) {
117
+ emailVerificationApi()
114
118
  startTimer()
115
119
  uiFinishingTouchElements()
116
120
  }
@@ -291,7 +295,7 @@ class OTPVerificationVC: BaseVC {
291
295
  let token = UserStoreSingleton.shared.clientToken
292
296
  print("Setting clientToken header: \(token ?? "None")")
293
297
  request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
294
-
298
+
295
299
  // Add API headers
296
300
  if let apiKey = EnvironmentConfig.apiKey,
297
301
  let apiSecret = EnvironmentConfig.apiSecret {
@@ -1813,6 +1817,7 @@ class OTPVerificationVC: BaseVC {
1813
1817
  paymentDoneVC.visibility = self.visibility
1814
1818
  paymentDoneVC.amount = self.amount
1815
1819
  paymentDoneVC.cardApiParams = params
1820
+
1816
1821
  // if self.visibility?.billing == true {
1817
1822
  paymentDoneVC.billingInfoData = self.billingInfo
1818
1823
  var billingDict: [String: Any] = [:]
@@ -406,7 +406,18 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
406
406
  //MARK: - View Did Load
407
407
  override func viewDidLoad() {
408
408
  super.viewDidLoad()
409
- // logOut()
409
+ // Then: safely start new API call
410
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
411
+ self.request?.paymentIntentApi { success in
412
+ if success {
413
+ print("Payment Intent completed")
414
+ // Continue flow
415
+ } else {
416
+ print("Payment Intent failed")
417
+ // Handle failure
418
+ }
419
+ }
420
+ }
410
421
 
411
422
  viewAppearanceOn()
412
423
 
@@ -730,9 +741,9 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
730
741
  self.viewAddNewCard.isHidden = true
731
742
  }
732
743
  else {
733
- self.getShowCardsApi()
744
+ // self.getShowCardsApi()
734
745
  self.viewCardFields.isHidden = true
735
- self.viewSingleSavedCard.isHidden = false
746
+ // self.viewSingleSavedCard.isHidden = false
736
747
  self.viewBtnShowSavedCards.isHidden = true
737
748
  self.viewBtnShowSavedCardHeight.constant = 0
738
749
  self.viewBtnShowSavedCardTopCon.constant = 0
@@ -4312,7 +4323,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
4312
4323
  print("isLoggedIn after clear: \(UserStoreSingleton.shared.isLoggedIn ?? false)")
4313
4324
 
4314
4325
  UserStoreSingleton.shared.isLoggedIn = false
4315
- self.settingsView.isHidden = true
4326
+ // self.settingsView.isHidden = true
4316
4327
  self.btnSettings.isHidden = true
4317
4328
  // self.txtFieldEmail.text = ""
4318
4329
  self.txtFieldOTPText1.text = ""
@@ -5207,13 +5218,13 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
5207
5218
 
5208
5219
  // MARK: - GET Show Cards API
5209
5220
  func getShowCardsApi() {
5210
- showLoadingIndicator()
5221
+ // showLoadingIndicator()
5211
5222
 
5212
5223
  let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.getCards.path()
5213
5224
 
5214
5225
  guard let serviceURL = URL(string: fullURL) else {
5215
5226
  print("❌ Invalid URL: \(fullURL)")
5216
- hideLoadingIndicator()
5227
+ // hideLoadingIndicator()
5217
5228
  return
5218
5229
  }
5219
5230
 
@@ -5236,11 +5247,11 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
5236
5247
  let task = session.dataTask(with: uRLRequest) { [weak self] (data, response, error) in
5237
5248
  guard let self = self else { return }
5238
5249
 
5239
- defer {
5240
- DispatchQueue.main.async {
5241
- self.hideLoadingIndicator()
5242
- }
5243
- }
5250
+ // defer {
5251
+ // DispatchQueue.main.async {
5252
+ // self.hideLoadingIndicator()
5253
+ // }
5254
+ // }
5244
5255
 
5245
5256
  if let error = error {
5246
5257
  print("❌ Error in getShowCardsApi: \(error.localizedDescription)")
@@ -7201,13 +7212,13 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
7201
7212
  //MARK: - Bank Api's
7202
7213
  // MARK: - GET Show Bank Accounts API
7203
7214
  func getShowBankAccountsApi() {
7204
- showLoadingIndicator()
7215
+ // showLoadingIndicator()
7205
7216
 
7206
7217
  let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.account.path()
7207
7218
 
7208
7219
  guard let serviceURL = URL(string: fullURL) else {
7209
7220
  print("Invalid URL")
7210
- hideLoadingIndicator()
7221
+ // hideLoadingIndicator()
7211
7222
  return
7212
7223
  }
7213
7224
 
@@ -7218,7 +7229,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
7218
7229
  // Retrieve and validate customer token
7219
7230
  guard let token = UserStoreSingleton.shared.customerToken, !token.isEmpty else {
7220
7231
  print("Customer token is missing or empty")
7221
- hideLoadingIndicator()
7232
+ // hideLoadingIndicator()
7222
7233
  showAlert(message: "Session expired. Please log in again.")
7223
7234
  return
7224
7235
  }
@@ -7230,9 +7241,9 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
7230
7241
  let task = session.dataTask(with: urlRequest) { [weak self] (data, response, error) in
7231
7242
  guard let self = self else { return }
7232
7243
 
7233
- DispatchQueue.main.async {
7234
- self.hideLoadingIndicator()
7235
- }
7244
+ // DispatchQueue.main.async {
7245
+ // self.hideLoadingIndicator()
7246
+ // }
7236
7247
 
7237
7248
  if let error = error {
7238
7249
  print("Error: \(error.localizedDescription)")
@@ -1,6 +1,6 @@
1
1
  Pod::Spec.new do |s|
2
2
  s.name = 'easymerchantsdk'
3
- s.version = '1.8.1'
3
+ s.version = '1.8.4'
4
4
  s.summary = 'A React Native SDK for Easy Merchant.'
5
5
  s.description = <<-DESC
6
6
  A React Native SDK to enable Easy Merchant functionality in mobile applications.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jimrising/easymerchantsdk-react-native",
3
- "version": "1.8.1",
3
+ "version": "1.8.4",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {