@jimrising/easymerchantsdk-react-native 1.4.2 → 1.4.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 (32) hide show
  1. package/README.md +15 -4
  2. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$1.dex +0 -0
  3. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  4. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  5. package/android/build/.transforms/e9a664a11ce12edf79cd87b1e07aa243/transformed/classes/classes_dex/classes.dex +0 -0
  6. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  7. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  8. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  9. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  10. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  11. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  12. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  13. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  14. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1.class.uniqueId2 +0 -0
  15. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$2.class.uniqueId0 +0 -0
  16. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule.class.uniqueId3 +0 -0
  17. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  18. package/android/build.gradle +1 -1
  19. package/android/src/main/java/com/reactlibrary/RNEasymerchantsdkModule.java +0 -1
  20. package/ios/Classes/EasyMerchantSdk.m +4 -2
  21. package/ios/Classes/EasyMerchantSdk.swift +2 -0
  22. package/ios/Models/Request.swift +45 -54
  23. package/ios/Models/Result.swift +1 -0
  24. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +310 -88
  25. package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +289 -59
  26. package/ios/Pods/ViewControllers/EmailVerificationVC.swift +41 -86
  27. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +208 -129
  28. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +1304 -158
  29. package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +24 -258
  30. package/ios/easymerchantsdk.podspec +1 -1
  31. package/ios/easymerchantsdk.storyboard +93 -12
  32. package/package.json +1 -1
@@ -205,6 +205,8 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
205
205
  @IBOutlet weak var txtFieldSelectDateGrailPayBankView: TextFieldStackView!
206
206
  @IBOutlet weak var bankIconGrailPayBankView: UIImageView!
207
207
  @IBOutlet weak var viewSaveAccountForFutureGrailPayView: UIStackView!
208
+ @IBOutlet weak var txtFieldEmailGrailPayView: TextFieldStackView!
209
+ @IBOutlet weak var viewTxtFieldEmailGrailPayView: UIView!
208
210
 
209
211
  //New GrailPay Account
210
212
  @IBOutlet weak var viewAddNewGrailPayAccount: UIView!
@@ -274,7 +276,6 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
274
276
  @IBOutlet weak var heightSubViewNewAccountFields: NSLayoutConstraint!
275
277
  @IBOutlet weak var viewSaveAccountForFutureNewAccountView: UIStackView!
276
278
 
277
-
278
279
  //Crypto
279
280
  @IBOutlet weak var viewCrypto: UIView!
280
281
  @IBOutlet weak var viewCryptoTryAgain: UIView!
@@ -422,29 +423,69 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
422
423
  self.view.addGestureRecognizer(tapGesture)
423
424
 
424
425
  //// Check if billingInfoData is available
426
+ // if let billingInfoData = request.billingInfoData,
427
+ // let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
428
+ //
429
+ // let billingVisible = fieldSection.visibility.billing
430
+ // let suffix = billingVisible ? " (Billing Info)" : " (Additional Info)"
431
+ // let buttonText = (request?.submitButtonText?.isEmpty == false
432
+ // ? request!.submitButtonText! + suffix
433
+ // : "Next" + suffix)
434
+ //
435
+ // btnNext.setTitle(buttonText, for: .normal)
436
+ // btnPayNowNewCardView.setTitle(buttonText, for: .normal)
437
+ // btnPayNowNewAccountView.setTitle(buttonText, for: .normal)
438
+ // btnPayNowSingleCard.setTitle(buttonText, for: .normal)
439
+ // btnPayNowSingleAccountView.setTitle(buttonText, for: .normal)
440
+ // } else {
441
+ // let amountValue = request?.amount ?? 0
442
+ // let amountText = String(format: "$%.2f", amountValue)
443
+ // let submitText = request?.submitButtonText
444
+ //
445
+ // let defaultTitle = (submitText?.isEmpty == false)
446
+ // ? "\(submitText!) (\(amountText))"
447
+ // : "Pay Now (\(amountText))"
448
+ //
449
+ // btnNext.setTitle(defaultTitle, for: .normal)
450
+ // btnPayNowNewCardView.setTitle(defaultTitle, for: .normal)
451
+ // btnPayNowNewAccountView.setTitle(defaultTitle, for: .normal)
452
+ // btnPayNowSingleCard.setTitle(defaultTitle, for: .normal)
453
+ // btnPayNowSingleAccountView.setTitle(defaultTitle, for: .normal)
454
+ // }
455
+
425
456
  if let billingInfoData = request.billingInfoData,
426
457
  let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
427
458
 
428
459
  let billingVisible = fieldSection.visibility.billing
429
- let suffix = billingVisible ? " (Billing Info)" : " (Additional Info)"
430
- let buttonText = (request?.submitButtonText?.isEmpty == false
431
- ? request!.submitButtonText! + suffix
432
- : "Next" + suffix)
433
-
460
+ let additionalVisible = fieldSection.visibility.additional
461
+ let submitText = request?.submitButtonText?.isEmpty == false ? request!.submitButtonText! : "Pay Now"
462
+ let amountText = String(format: "$%.2f", request?.amount ?? 0)
463
+
464
+ var buttonText: String
465
+
466
+ if !billingVisible && !additionalVisible {
467
+ // Both visibility false – show submitText with amount only
468
+ buttonText = "\(submitText) (\(amountText))"
469
+ } else if billingVisible {
470
+ buttonText = "\(submitText) (Billing Info)"
471
+ } else if additionalVisible {
472
+ buttonText = "\(submitText) (Additional Info)"
473
+ } else {
474
+ // Fallback
475
+ buttonText = "\(submitText) (\(amountText))"
476
+ }
477
+
434
478
  btnNext.setTitle(buttonText, for: .normal)
435
479
  btnPayNowNewCardView.setTitle(buttonText, for: .normal)
436
480
  btnPayNowNewAccountView.setTitle(buttonText, for: .normal)
437
481
  btnPayNowSingleCard.setTitle(buttonText, for: .normal)
438
482
  btnPayNowSingleAccountView.setTitle(buttonText, for: .normal)
439
483
  } else {
440
- let amountValue = request?.amount ?? 0
441
- let amountText = String(format: "$%.2f", amountValue)
442
- let submitText = request?.submitButtonText
443
-
444
- let defaultTitle = (submitText?.isEmpty == false)
445
- ? "\(submitText!) (\(amountText))"
446
- : "Pay Now (\(amountText))"
447
-
484
+ // When no billingInfoData present
485
+ let amountText = String(format: "$%.2f", request?.amount ?? 0)
486
+ let submitText = request?.submitButtonText?.isEmpty == false ? request!.submitButtonText! : "Pay Now"
487
+ let defaultTitle = "\(submitText) (\(amountText))"
488
+
448
489
  btnNext.setTitle(defaultTitle, for: .normal)
449
490
  btnPayNowNewCardView.setTitle(defaultTitle, for: .normal)
450
491
  btnPayNowNewAccountView.setTitle(defaultTitle, for: .normal)
@@ -989,6 +1030,9 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
989
1030
  txtFieldRoutingNumberNewAccountView.tintColor = uiColor
990
1031
  txtFieldNameOnCardNewCardView.tintColor = uiColor
991
1032
  txtFieldNameOnCardUpdateCardView.tintColor = uiColor
1033
+ txtFieldEmailGrailPayView.tintColor = uiColor
1034
+ txtFieldEmailCardView.tintColor = uiColor
1035
+ txtFieldEmailAccountView.tintColor = uiColor
992
1036
  cardNumberTextField.tintColor = uiColor
993
1037
  cardExpiryTextField.tintColor = uiColor
994
1038
  cardCvvTextField.tintColor = uiColor
@@ -1260,6 +1304,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
1260
1304
  txtFieldAccountNumber.delegate = self
1261
1305
  txtFieldConfirmBankAccount.delegate = self
1262
1306
  txtFieldEmailAccountView.textField.delegate = self
1307
+ txtFieldEmailGrailPayView.textField.delegate = self
1263
1308
  }
1264
1309
 
1265
1310
  private func updateSaveButtons() {
@@ -1886,8 +1931,62 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
1886
1931
  }
1887
1932
 
1888
1933
  // Redirect based on billing visibility
1889
- if fieldSection.visibility.billing {
1890
- // Instantiate BillingInfoVC and pass the selected card data and CVV text
1934
+ // if fieldSection.visibility.billing {
1935
+ // // Instantiate BillingInfoVC and pass the selected card data and CVV text
1936
+ // let billingInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
1937
+ //
1938
+ // billingInfoVC.isFrom = "SavedCards"
1939
+ // billingInfoVC.selectedCard = self.selectedCard // Passing the selected card data
1940
+ // billingInfoVC.cvvText = cvvText // Passing the CVV text
1941
+ // billingInfoVC.amount = Int(self.request.amount ?? 0)
1942
+ // billingInfoVC.selectedPaymentMethod = self.selectedPaymentMethod
1943
+ //
1944
+ // if let billingInfoData = self.request.billingInfoData {
1945
+ // billingInfoVC.billingInfoData = billingInfoData
1946
+ // }
1947
+ //
1948
+ // billingInfoVC.request = self.request
1949
+ // billingInfoVC.chosenPlan = self.txtFieldSelectPlanSingleSavedCard.text
1950
+ // billingInfoVC.startDate = self.txtFieldSelectDateSingleSavedCard.text
1951
+ //
1952
+ // billingInfoVC.billingInfo = fieldSection.billing
1953
+ // billingInfoVC.additionalInfo = fieldSection.additional
1954
+ // billingInfoVC.visibility = fieldSection.visibility
1955
+ //
1956
+ // // Navigate to BillingInfoVC
1957
+ // self.navigationController?.pushViewController(billingInfoVC, animated: true)
1958
+ // }
1959
+ // else {
1960
+ // let additionalInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
1961
+ // additionalInfoVC.isFrom = "SavedCards"
1962
+ // additionalInfoVC.selectedCard = self.selectedCard // Passing the selected card data
1963
+ // additionalInfoVC.cvvText = cvvText // Passing the CVV text
1964
+ // additionalInfoVC.amount = Int(self.request.amount ?? 0)
1965
+ // additionalInfoVC.selectedPaymentMethod = self.selectedPaymentMethod
1966
+ //
1967
+ // if let billingInfoData = self.request.billingInfoData {
1968
+ // additionalInfoVC.billingInfoData = billingInfoData
1969
+ // }
1970
+ //
1971
+ // additionalInfoVC.request = self.request
1972
+ // additionalInfoVC.chosenPlan = self.txtFieldSelectPlanSingleSavedCard.text
1973
+ // additionalInfoVC.startDate = self.txtFieldSelectDateSingleSavedCard.text
1974
+ //
1975
+ // additionalInfoVC.billingInfo = fieldSection.billing
1976
+ // additionalInfoVC.additionalInfo = fieldSection.additional
1977
+ // additionalInfoVC.visibility = fieldSection.visibility
1978
+ //
1979
+ // self.navigationController?.pushViewController(additionalInfoVC, animated: true)
1980
+ // }
1981
+
1982
+ let showBilling = fieldSection.visibility.billing
1983
+ let showAdditional = fieldSection.visibility.additional
1984
+
1985
+ if !showBilling && !showAdditional {
1986
+ self.paymentIntentFromShowCardApi()
1987
+ }
1988
+ else if showBilling {
1989
+ // Push to BillingInfoVC
1891
1990
  let billingInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
1892
1991
 
1893
1992
  billingInfoVC.isFrom = "SavedCards"
@@ -1912,6 +2011,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
1912
2011
  self.navigationController?.pushViewController(billingInfoVC, animated: true)
1913
2012
  }
1914
2013
  else {
2014
+ // Push to AdditionalInfoVC
1915
2015
  let additionalInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
1916
2016
  additionalInfoVC.isFrom = "SavedCards"
1917
2017
  additionalInfoVC.selectedCard = self.selectedCard // Passing the selected card data
@@ -1933,6 +2033,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
1933
2033
 
1934
2034
  self.navigationController?.pushViewController(additionalInfoVC, animated: true)
1935
2035
  }
2036
+
1936
2037
  }
1937
2038
  }
1938
2039
  catch {
@@ -2086,10 +2187,75 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2086
2187
  }
2087
2188
 
2088
2189
  // Redirect based on billing visibility
2089
- if fieldSection.visibility.billing {
2090
- // Instantiate BillingInfoVC and pass the card details
2091
- let billingInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2092
-
2190
+ // if fieldSection.visibility.billing {
2191
+ // // Instantiate BillingInfoVC and pass the card details
2192
+ // let billingInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2193
+ //
2194
+ // // Pass the card details
2195
+ // billingInfoVC.cardNumber = cardNumber
2196
+ // billingInfoVC.expiryDate = expiryDate
2197
+ // billingInfoVC.cvv = cvv
2198
+ // billingInfoVC.nameOnCard = nameOnCard
2199
+ // billingInfoVC.isSavedNewCard = self.isSavedNewCardForFuture
2200
+ //
2201
+ // billingInfoVC.isFrom = "AddNewCard"
2202
+ // billingInfoVC.amount = Int(self.request.amount ?? 0)
2203
+ // billingInfoVC.selectedPaymentMethod = self.selectedPaymentMethod
2204
+ //
2205
+ // if let billingInfoData = self.request.billingInfoData {
2206
+ // billingInfoVC.billingInfoData = billingInfoData
2207
+ // }
2208
+ //
2209
+ // billingInfoVC.request = self.request
2210
+ // billingInfoVC.chosenPlan = self.txtFieldSelectPlanNewCardView.text
2211
+ // billingInfoVC.startDate = self.txtFieldSelectDateNewCardView.text
2212
+ //
2213
+ // billingInfoVC.billingInfo = fieldSection.billing
2214
+ // billingInfoVC.additionalInfo = fieldSection.additional
2215
+ // billingInfoVC.visibility = fieldSection.visibility
2216
+ //
2217
+ // // Navigate to BillingInfoVC
2218
+ // self.navigationController?.pushViewController(billingInfoVC, animated: true)
2219
+ // }
2220
+ // else {
2221
+ // let additionalInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2222
+ //
2223
+ // // Pass the card details
2224
+ // additionalInfoVC.cardNumber = cardNumber
2225
+ // additionalInfoVC.expiryDate = expiryDate
2226
+ // additionalInfoVC.cvv = cvv
2227
+ // additionalInfoVC.nameOnCard = nameOnCard
2228
+ // additionalInfoVC.isSavedNewCard = self.isSavedNewCardForFuture
2229
+ //
2230
+ // additionalInfoVC.isFrom = "AddNewCard"
2231
+ // additionalInfoVC.amount = Int(self.request.amount ?? 0)
2232
+ // additionalInfoVC.selectedPaymentMethod = self.selectedPaymentMethod
2233
+ //
2234
+ // if let billingInfoData = self.request.billingInfoData {
2235
+ // additionalInfoVC.billingInfoData = billingInfoData
2236
+ // }
2237
+ //
2238
+ // additionalInfoVC.request = self.request
2239
+ // additionalInfoVC.chosenPlan = self.txtFieldSelectPlanNewCardView.text
2240
+ // additionalInfoVC.startDate = self.txtFieldSelectDateNewCardView.text
2241
+ //
2242
+ // additionalInfoVC.billingInfo = fieldSection.billing
2243
+ // additionalInfoVC.additionalInfo = fieldSection.additional
2244
+ // additionalInfoVC.visibility = fieldSection.visibility
2245
+ //
2246
+ // self.navigationController?.pushViewController(additionalInfoVC, animated: true)
2247
+ // }
2248
+
2249
+
2250
+ let showBilling = fieldSection.visibility.billing
2251
+ let showAdditional = fieldSection.visibility.additional
2252
+
2253
+ if !showBilling && !showAdditional {
2254
+ self.threeDSecurePaymentNewCardApi(customerId: UserStoreSingleton.shared.customerId ?? "")
2255
+ }
2256
+ else if showBilling {
2257
+ // Push to BillingInfoVC
2258
+ let billingInfoVC = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2093
2259
  // Pass the card details
2094
2260
  billingInfoVC.cardNumber = cardNumber
2095
2261
  billingInfoVC.expiryDate = expiryDate
@@ -2112,13 +2278,11 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2112
2278
  billingInfoVC.billingInfo = fieldSection.billing
2113
2279
  billingInfoVC.additionalInfo = fieldSection.additional
2114
2280
  billingInfoVC.visibility = fieldSection.visibility
2115
-
2116
- // Navigate to BillingInfoVC
2117
2281
  self.navigationController?.pushViewController(billingInfoVC, animated: true)
2118
2282
  }
2119
2283
  else {
2120
- let additionalInfoVC = UIStoryboard(name: "easymerchantsdk", bundle: .easyPayBundle).instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2121
-
2284
+ // Push to AdditionalInfoVC
2285
+ let additionalInfoVC = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2122
2286
  // Pass the card details
2123
2287
  additionalInfoVC.cardNumber = cardNumber
2124
2288
  additionalInfoVC.expiryDate = expiryDate
@@ -2141,7 +2305,6 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2141
2305
  additionalInfoVC.billingInfo = fieldSection.billing
2142
2306
  additionalInfoVC.additionalInfo = fieldSection.additional
2143
2307
  additionalInfoVC.visibility = fieldSection.visibility
2144
-
2145
2308
  self.navigationController?.pushViewController(additionalInfoVC, animated: true)
2146
2309
  }
2147
2310
  }
@@ -2554,6 +2717,9 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2554
2717
 
2555
2718
  @IBAction private func actionBtnLinkGrailPayBankAccount(_ sender: UIButton) {
2556
2719
  if isBankAccountConnected {
2720
+
2721
+ let email = self.txtFieldEmailGrailPayView.text.trimmingCharacters(in: .whitespacesAndNewlines)
2722
+
2557
2723
  // Recurring Plan + Date Validation (only if is_recurring is true)
2558
2724
  if let req = self.request, req.is_recurring == true {
2559
2725
  if self.txtFieldChosePlanGrailPayBankView.text.isEmpty {
@@ -2569,6 +2735,15 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2569
2735
  }
2570
2736
  }
2571
2737
 
2738
+ if email.isEmpty {
2739
+ self.showAlert(title: "Missing Information", message: "Please enter an email address.")
2740
+ return
2741
+ }
2742
+ else if !self.isValidEmail(email) {
2743
+ self.showAlert(title: "Invalid Email", message: "Please enter a valid email address.")
2744
+ return
2745
+ }
2746
+
2572
2747
  guard agreeTermsAndCondtition else {
2573
2748
  self.showAlert(title: "Terms and Conditions", message: "Please agree to the terms and conditions.")
2574
2749
  return
@@ -2588,7 +2763,72 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2588
2763
  print("Billing Info Data: \(jsonDict)")
2589
2764
 
2590
2765
  // Redirect based on billing visibility
2591
- if fieldSection.visibility.billing {
2766
+ // if fieldSection.visibility.billing {
2767
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2768
+ // vc.billingInfoData = billingInfoData
2769
+ // vc.request = self.request
2770
+ // vc.chosenPlan = self.txtFieldChosePlanGrailPayBankView.text
2771
+ // vc.startDate = self.txtFieldSelectDateGrailPayBankView.text
2772
+ // vc.selectedPaymentMethod = "GrailPay"
2773
+ // vc.isSavedForFuture = self.isSavedForFuture
2774
+ // vc.grailPayAccountID = self.grailPayAccountID
2775
+ // vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
2776
+ // vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
2777
+ // vc.amount = self.amount
2778
+ // vc.billingInfo = fieldSection.billing
2779
+ // vc.additionalInfo = fieldSection.additional
2780
+ // vc.visibility = fieldSection.visibility
2781
+ // vc.easyPayDelegate = self.easyPayDelegate
2782
+ // vc.userEmail = self.txtFieldEmailGrailPayView.text
2783
+ // self.navigationController?.pushViewController(vc, animated: true)
2784
+ // }
2785
+ // else {
2786
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2787
+ // vc.billingInfoData = billingInfoData
2788
+ // vc.request = self.request
2789
+ // vc.chosenPlan = self.txtFieldChosePlanGrailPayBankView.text
2790
+ // vc.startDate = self.txtFieldSelectDateGrailPayBankView.text
2791
+ // vc.selectedPaymentMethod = "GrailPay"
2792
+ // vc.isSavedForFuture = self.isSavedForFuture
2793
+ // vc.grailPayAccountID = self.grailPayAccountID
2794
+ // vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
2795
+ // vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
2796
+ // vc.amount = self.amount
2797
+ // vc.billingInfo = fieldSection.billing
2798
+ // vc.additionalInfo = fieldSection.additional
2799
+ // vc.visibility = fieldSection.visibility
2800
+ // vc.easyPayDelegate = self.easyPayDelegate
2801
+ // vc.userEmail = self.txtFieldEmailGrailPayView.text
2802
+ // self.navigationController?.pushViewController(vc, animated: true)
2803
+ // }
2804
+
2805
+ let showBilling = fieldSection.visibility.billing
2806
+ let showAdditional = fieldSection.visibility.additional
2807
+
2808
+ if !showBilling && !showAdditional {
2809
+ // Navigate directly to EmailVerificationVC
2810
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
2811
+ let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
2812
+ vc.easyPayDelegate = self.easyPayDelegate
2813
+ vc.grailPayAccountID = self.grailPayAccountID
2814
+ vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
2815
+ vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
2816
+ vc.chosenPlan = self.txtFieldChosePlanGrailPayBankView.text
2817
+ vc.startDate = self.txtFieldSelectDateGrailPayBankView.text
2818
+ vc.request = self.request
2819
+ vc.isSavedForFuture = self.isSavedForFuture
2820
+ vc.selectedPaymentMethod = "GrailPay"
2821
+ vc.userEmail = self.txtFieldEmailGrailPayView.text
2822
+ vc.billingInfoData = billingInfoData // Send the data even if not shown
2823
+ vc.billingInfo = fieldSection.billing
2824
+ vc.additionalInfo = fieldSection.additional
2825
+ vc.visibility = fieldSection.visibility
2826
+ vc.amount = self.amount
2827
+ vc.email = self.txtFieldEmailGrailPayView.text
2828
+ self.navigationController?.pushViewController(vc, animated: true)
2829
+ }
2830
+ else if showBilling {
2831
+ // Push to BillingInfoVC
2592
2832
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2593
2833
  vc.billingInfoData = billingInfoData
2594
2834
  vc.request = self.request
@@ -2604,9 +2844,11 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2604
2844
  vc.additionalInfo = fieldSection.additional
2605
2845
  vc.visibility = fieldSection.visibility
2606
2846
  vc.easyPayDelegate = self.easyPayDelegate
2847
+ vc.userEmail = self.txtFieldEmailGrailPayView.text
2607
2848
  self.navigationController?.pushViewController(vc, animated: true)
2608
2849
  }
2609
2850
  else {
2851
+ // Push to AdditionalInfoVC
2610
2852
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2611
2853
  vc.billingInfoData = billingInfoData
2612
2854
  vc.request = self.request
@@ -2622,8 +2864,10 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2622
2864
  vc.additionalInfo = fieldSection.additional
2623
2865
  vc.visibility = fieldSection.visibility
2624
2866
  vc.easyPayDelegate = self.easyPayDelegate
2867
+ vc.userEmail = self.txtFieldEmailGrailPayView.text
2625
2868
  self.navigationController?.pushViewController(vc, animated: true)
2626
2869
  }
2870
+
2627
2871
  }
2628
2872
  }
2629
2873
  }
@@ -2634,7 +2878,8 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2634
2878
  else {
2635
2879
  //If billing info is nil
2636
2880
  // Navigate to EmailVerificationVC directly
2637
- let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
2881
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
2882
+ let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
2638
2883
  vc.easyPayDelegate = self.easyPayDelegate
2639
2884
  vc.grailPayAccountID = self.grailPayAccountID
2640
2885
  vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
@@ -2644,6 +2889,8 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2644
2889
  vc.request = self.request
2645
2890
  vc.isSavedForFuture = self.isSavedForFuture
2646
2891
  vc.selectedPaymentMethod = "GrailPay"
2892
+ vc.email = self.txtFieldEmailGrailPayView.text
2893
+ vc.amount = self.amount
2647
2894
  self.navigationController?.pushViewController(vc, animated: true)
2648
2895
  }
2649
2896
  } else {
@@ -2660,7 +2907,54 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2660
2907
  print("Billing Info Data: \(jsonDict)")
2661
2908
 
2662
2909
  // Redirect based on billing visibility
2663
- if fieldSection.visibility.billing {
2910
+ // if fieldSection.visibility.billing {
2911
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2912
+ // vc.billingInfoData = billingInfoData
2913
+ // vc.request = self.request
2914
+ // vc.chosenPlan = self.txtFieldChosePlanGrailPayBankView.text
2915
+ // vc.startDate = self.txtFieldSelectDateGrailPayBankView.text
2916
+ // vc.selectedPaymentMethod = "GrailPay"
2917
+ // vc.isSavedForFuture = self.isSavedForFuture
2918
+ // vc.grailPayAccountID = self.grailPayAccountID
2919
+ // vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
2920
+ // vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
2921
+ // vc.amount = self.amount
2922
+ // vc.billingInfo = fieldSection.billing
2923
+ // vc.additionalInfo = fieldSection.additional
2924
+ // vc.visibility = fieldSection.visibility
2925
+ // vc.easyPayDelegate = self.easyPayDelegate
2926
+ // vc.userEmail = self.txtFieldEmailGrailPayView.text
2927
+ // self.navigationController?.pushViewController(vc, animated: true)
2928
+ // }
2929
+ // else {
2930
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2931
+ // vc.billingInfoData = billingInfoData
2932
+ // vc.request = self.request
2933
+ // vc.chosenPlan = self.txtFieldChosePlanGrailPayBankView.text
2934
+ // vc.startDate = self.txtFieldSelectDateGrailPayBankView.text
2935
+ // vc.selectedPaymentMethod = "GrailPay"
2936
+ // vc.isSavedForFuture = self.isSavedForFuture
2937
+ // vc.grailPayAccountID = self.grailPayAccountID
2938
+ // vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
2939
+ // vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
2940
+ // vc.amount = self.amount
2941
+ // vc.billingInfo = fieldSection.billing
2942
+ // vc.additionalInfo = fieldSection.additional
2943
+ // vc.visibility = fieldSection.visibility
2944
+ // vc.easyPayDelegate = self.easyPayDelegate
2945
+ // vc.userEmail = self.txtFieldEmailGrailPayView.text
2946
+ // self.navigationController?.pushViewController(vc, animated: true)
2947
+ // }
2948
+
2949
+
2950
+ let showBilling = fieldSection.visibility.billing
2951
+ let showAdditional = fieldSection.visibility.additional
2952
+
2953
+ if !showBilling && !showAdditional {
2954
+ self.grailPayAccountChargeApi()
2955
+ }
2956
+ else if showBilling {
2957
+ // Push to BillingInfoVC
2664
2958
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2665
2959
  vc.billingInfoData = billingInfoData
2666
2960
  vc.request = self.request
@@ -2676,9 +2970,11 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2676
2970
  vc.additionalInfo = fieldSection.additional
2677
2971
  vc.visibility = fieldSection.visibility
2678
2972
  vc.easyPayDelegate = self.easyPayDelegate
2973
+ vc.userEmail = self.txtFieldEmailGrailPayView.text
2679
2974
  self.navigationController?.pushViewController(vc, animated: true)
2680
2975
  }
2681
2976
  else {
2977
+ // Push to AdditionalInfoVC
2682
2978
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2683
2979
  vc.billingInfoData = billingInfoData
2684
2980
  vc.request = self.request
@@ -2694,6 +2990,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2694
2990
  vc.additionalInfo = fieldSection.additional
2695
2991
  vc.visibility = fieldSection.visibility
2696
2992
  vc.easyPayDelegate = self.easyPayDelegate
2993
+ vc.userEmail = self.txtFieldEmailGrailPayView.text
2697
2994
  self.navigationController?.pushViewController(vc, animated: true)
2698
2995
  }
2699
2996
  }
@@ -2751,7 +3048,52 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2751
3048
  print("Billing Info Data: \(jsonDict)")
2752
3049
 
2753
3050
  // Redirect based on billing visibility
2754
- if fieldSection.visibility.billing {
3051
+ // if fieldSection.visibility.billing {
3052
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
3053
+ // vc.billingInfoData = billingInfoData
3054
+ // vc.request = self.request
3055
+ // vc.chosenPlan = self.txtFieldChosePlanNewGrailPayBankView.text
3056
+ // vc.startDate = self.txtFieldSelectDateNewGrailPayBankView.text
3057
+ // vc.selectedPaymentMethod = "NewGrailPayAccount"
3058
+ // vc.isSavedForFuture = self.isSavedForFuture
3059
+ // vc.grailPayAccountID = self.newGrailPayAccountID
3060
+ // vc.selectedGrailPayAccountType = self.selectedNewGrailPayAccountType
3061
+ // vc.selectedGrailPayAccountName = self.selectedNewGrailPayAccountName
3062
+ // vc.amount = self.amount
3063
+ // vc.billingInfo = fieldSection.billing
3064
+ // vc.additionalInfo = fieldSection.additional
3065
+ // vc.visibility = fieldSection.visibility
3066
+ // vc.easyPayDelegate = self.easyPayDelegate
3067
+ // self.navigationController?.pushViewController(vc, animated: true)
3068
+ // }
3069
+ // else {
3070
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
3071
+ // vc.billingInfoData = billingInfoData
3072
+ // vc.request = self.request
3073
+ // vc.chosenPlan = self.txtFieldChosePlanNewGrailPayBankView.text
3074
+ // vc.startDate = self.txtFieldSelectDateNewGrailPayBankView.text
3075
+ // vc.selectedPaymentMethod = "NewGrailPayAccount"
3076
+ // vc.isSavedForFuture = self.isSavedForFuture
3077
+ // vc.grailPayAccountID = self.newGrailPayAccountID
3078
+ // vc.selectedGrailPayAccountType = self.selectedNewGrailPayAccountType
3079
+ // vc.selectedGrailPayAccountName = self.selectedNewGrailPayAccountName
3080
+ // vc.amount = self.amount
3081
+ // vc.billingInfo = fieldSection.billing
3082
+ // vc.additionalInfo = fieldSection.additional
3083
+ // vc.visibility = fieldSection.visibility
3084
+ // vc.easyPayDelegate = self.easyPayDelegate
3085
+ // self.navigationController?.pushViewController(vc, animated: true)
3086
+ // }
3087
+
3088
+
3089
+ let showBilling = fieldSection.visibility.billing
3090
+ let showAdditional = fieldSection.visibility.additional
3091
+
3092
+ if !showBilling && !showAdditional {
3093
+ self.grailPayNewAccountChargeApi()
3094
+ }
3095
+ else if showBilling {
3096
+ // Push to BillingInfoVC
2755
3097
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2756
3098
  vc.billingInfoData = billingInfoData
2757
3099
  vc.request = self.request
@@ -2770,6 +3112,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2770
3112
  self.navigationController?.pushViewController(vc, animated: true)
2771
3113
  }
2772
3114
  else {
3115
+ // Push to AdditionalInfoVC
2773
3116
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2774
3117
  vc.billingInfoData = billingInfoData
2775
3118
  vc.request = self.request
@@ -2787,6 +3130,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2787
3130
  vc.easyPayDelegate = self.easyPayDelegate
2788
3131
  self.navigationController?.pushViewController(vc, animated: true)
2789
3132
  }
3133
+
2790
3134
  }
2791
3135
  }
2792
3136
  }
@@ -2809,7 +3153,51 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2809
3153
  print("Billing Info Data: \(jsonDict)")
2810
3154
 
2811
3155
  // Redirect based on billing visibility
2812
- if fieldSection.visibility.billing {
3156
+ // if fieldSection.visibility.billing {
3157
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
3158
+ // vc.billingInfoData = billingInfoData
3159
+ // vc.request = self.request
3160
+ // vc.chosenPlan = self.txtFieldChosePlanNewGrailPayBankView.text
3161
+ // vc.startDate = self.txtFieldSelectDateNewGrailPayBankView.text
3162
+ // vc.selectedPaymentMethod = "NewGrailPayAccount"
3163
+ // vc.isSavedForFuture = self.isSavedForFuture
3164
+ // vc.grailPayAccountID = self.newGrailPayAccountID
3165
+ // vc.selectedGrailPayAccountType = self.selectedNewGrailPayAccountType
3166
+ // vc.selectedGrailPayAccountName = self.selectedNewGrailPayAccountName
3167
+ // vc.amount = self.amount
3168
+ // vc.billingInfo = fieldSection.billing
3169
+ // vc.additionalInfo = fieldSection.additional
3170
+ // vc.visibility = fieldSection.visibility
3171
+ // vc.easyPayDelegate = self.easyPayDelegate
3172
+ // self.navigationController?.pushViewController(vc, animated: true)
3173
+ // }
3174
+ // else {
3175
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
3176
+ // vc.billingInfoData = billingInfoData
3177
+ // vc.request = self.request
3178
+ // vc.chosenPlan = self.txtFieldChosePlanNewGrailPayBankView.text
3179
+ // vc.startDate = self.txtFieldSelectDateNewGrailPayBankView.text
3180
+ // vc.selectedPaymentMethod = "NewGrailPayAccount"
3181
+ // vc.isSavedForFuture = self.isSavedForFuture
3182
+ // vc.grailPayAccountID = self.newGrailPayAccountID
3183
+ // vc.selectedGrailPayAccountType = self.selectedNewGrailPayAccountType
3184
+ // vc.selectedGrailPayAccountName = self.selectedNewGrailPayAccountName
3185
+ // vc.amount = self.amount
3186
+ // vc.billingInfo = fieldSection.billing
3187
+ // vc.additionalInfo = fieldSection.additional
3188
+ // vc.visibility = fieldSection.visibility
3189
+ // vc.easyPayDelegate = self.easyPayDelegate
3190
+ // self.navigationController?.pushViewController(vc, animated: true)
3191
+ // }
3192
+
3193
+ let showBilling = fieldSection.visibility.billing
3194
+ let showAdditional = fieldSection.visibility.additional
3195
+
3196
+ if !showBilling && !showAdditional {
3197
+ self.grailPayNewAccountChargeApi()
3198
+ }
3199
+ else if showBilling {
3200
+ // Push to BillingInfoVC
2813
3201
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
2814
3202
  vc.billingInfoData = billingInfoData
2815
3203
  vc.request = self.request
@@ -2828,6 +3216,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2828
3216
  self.navigationController?.pushViewController(vc, animated: true)
2829
3217
  }
2830
3218
  else {
3219
+ // Push to AdditionalInfoVC
2831
3220
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
2832
3221
  vc.billingInfoData = billingInfoData
2833
3222
  vc.request = self.request
@@ -2845,6 +3234,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2845
3234
  vc.easyPayDelegate = self.easyPayDelegate
2846
3235
  self.navigationController?.pushViewController(vc, animated: true)
2847
3236
  }
3237
+
2848
3238
  }
2849
3239
  }
2850
3240
  }
@@ -2982,6 +3372,120 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
2982
3372
  "email": UserStoreSingleton.shared.merchantEmail ?? ""
2983
3373
  ]
2984
3374
 
3375
+ // if let billingInfoData = request.billingInfoData {
3376
+ // do {
3377
+ // let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
3378
+ //
3379
+ // // Process Billing Info if available and contains any non-empty value
3380
+ // let billing = fieldSection.billing.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
3381
+ // if !billing.isEmpty {
3382
+ // var billingDict: [String: Any] = [:]
3383
+ // billing.forEach { billingDict[$0.name] = $0.value }
3384
+ //
3385
+ // if let address = billingDict["address"] as? String { params["address"] = address }
3386
+ // if let country = billingDict["country"] as? String { params["country"] = country }
3387
+ // if let state = billingDict["state"] as? String { params["state"] = state }
3388
+ // if let city = billingDict["city"] as? String { params["city"] = city }
3389
+ // if let postalCode = billingDict["postal_code"] as? String { params["zip"] = postalCode }
3390
+ // }
3391
+ //
3392
+ // // Process Additional Info if available and contains any non-empty value
3393
+ // let additional = fieldSection.additional.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
3394
+ // if !additional.isEmpty {
3395
+ // var additionalDict: [String: Any] = [:]
3396
+ // additional.forEach { additionalDict[$0.name] = $0.value }
3397
+ //
3398
+ // if let desc = additionalDict["description"] as? String {
3399
+ // params["description"] = desc
3400
+ // }
3401
+ //
3402
+ // if let phone = additionalDict["phone_number"] as? String {
3403
+ // params["phone_number"] = phone
3404
+ // }
3405
+ // if let email = additionalDict["email"] as? String {
3406
+ // params["email"] = email
3407
+ // }
3408
+ // if let name = additionalDict["name"] as? String {
3409
+ // params["name"] = name
3410
+ // }
3411
+ // }
3412
+ //
3413
+ // // Set default description only if not already set
3414
+ // if params["description"] == nil {
3415
+ // params["description"] = "Hosted payment checkout"
3416
+ // }
3417
+ //
3418
+ // } catch {
3419
+ // print("Failed to decode FieldSection: \(error)")
3420
+ // params["description"] = "Hosted payment checkout"
3421
+ // }
3422
+ // } else {
3423
+ // params["description"] = "Hosted payment checkout"
3424
+ // }
3425
+
3426
+
3427
+ if let billingInfoData = request.billingInfoData {
3428
+ do {
3429
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
3430
+
3431
+ // Billing Info
3432
+ let billing = fieldSection.billing
3433
+ if !billing.isEmpty {
3434
+ var billingDict: [String: Any] = [:]
3435
+ billing.forEach { billingDict[$0.name] = $0.value }
3436
+
3437
+ if let address = billingDict["address"] as? String, !address.isEmpty {
3438
+ params["address"] = address
3439
+ }
3440
+ if let country = billingDict["country"] as? String, !country.isEmpty {
3441
+ params["country"] = country
3442
+ }
3443
+ if let state = billingDict["state"] as? String, !state.isEmpty {
3444
+ params["state"] = state
3445
+ }
3446
+ if let city = billingDict["city"] as? String, !city.isEmpty {
3447
+ params["city"] = city
3448
+ }
3449
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
3450
+ params["zip"] = postalCode
3451
+ }
3452
+ }
3453
+
3454
+ // Additional Info
3455
+ let additional = fieldSection.additional
3456
+ if !additional.isEmpty {
3457
+ var additionalDict: [String: Any] = [:]
3458
+ additional.forEach { additionalDict[$0.name] = $0.value }
3459
+
3460
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
3461
+ params["description"] = desc
3462
+ } else {
3463
+ params["description"] = "Hosted payment checkout"
3464
+ }
3465
+
3466
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
3467
+ params["phone_number"] = phone
3468
+ }
3469
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
3470
+ params["email"] = email
3471
+ }
3472
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
3473
+ params["name"] = name
3474
+ }
3475
+ } else {
3476
+ // If no description in additional info, set default
3477
+ params["description"] = "Hosted payment checkout"
3478
+ }
3479
+
3480
+ } catch {
3481
+ print("Failed to decode FieldSection: \(error)")
3482
+ params["description"] = "Hosted payment checkout"
3483
+ }
3484
+ } else {
3485
+ // Fallback if billingInfoData is missing
3486
+ params["description"] = "Hosted payment checkout"
3487
+ }
3488
+
2985
3489
  // Add these if recurring is enabled
2986
3490
  if let req = request, req.is_recurring == true {
2987
3491
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -3053,30 +3557,19 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3053
3557
  // Pass the selected payment method
3054
3558
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
3055
3559
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
3056
- // Pass billingInfo and additionalInfo
3057
- if let billingData = self.request.billingInfoData,
3058
- let billingInfoDict = try? JSONSerialization.jsonObject(with: billingData, options: []) as? [String: Any] {
3560
+ // Pass billing info and additional info if available
3561
+ if let billingInfoData = self.request.billingInfoData,
3562
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
3059
3563
 
3060
- // Extract main billing fields
3061
- let cleanBillingInfo: [String: Any] = [
3062
- "postal_code": billingInfoDict["postal_code"] ?? "",
3063
- "country": billingInfoDict["country"] ?? "",
3064
- "city": billingInfoDict["city"] ?? "",
3065
- "address": billingInfoDict["address"] ?? "",
3066
- "state": billingInfoDict["state"] ?? ""
3067
- ]
3068
- paymentDoneVC.billingInfo = cleanBillingInfo
3564
+ paymentDoneVC.billingInfoData = fieldSection.billing
3565
+ var billingDict: [String: Any] = [:]
3566
+ fieldSection.billing.forEach { billingDict[$0.name] = $0.value }
3567
+ paymentDoneVC.billingInfo = billingDict
3069
3568
 
3070
- // Extract additional_info
3071
- if let additional = billingInfoDict["additional_info"] as? [String: Any] {
3072
- let cleanAdditionalInfo: [String: Any] = [
3073
- "email": additional["email"] ?? "",
3074
- "phone_number": additional["phone_number"] ?? "",
3075
- "name": additional["name"] ?? "",
3076
- "country_code": additional["country_code"] ?? ""
3077
- ]
3078
- paymentDoneVC.additionalInfo = cleanAdditionalInfo
3079
- }
3569
+ paymentDoneVC.additionalInfoData = fieldSection.additional
3570
+ var additionalDict: [String: Any] = [:]
3571
+ fieldSection.additional.forEach { additionalDict[$0.name] = $0.value }
3572
+ paymentDoneVC.additionalInfo = additionalDict
3080
3573
  }
3081
3574
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
3082
3575
  }
@@ -3135,9 +3628,77 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3135
3628
  "account_type": self.selectedNewGrailPayAccountType ?? "",
3136
3629
  "name": self.selectedNewGrailPayAccountName ?? "",
3137
3630
  "description": "payment checkout",
3138
- "customer_id": self.grailPayNewAccountCustomerID ?? ""
3631
+ "customer_id": self.grailPayNewAccountCustomerID ?? "",
3632
+ "save_account": isSavedForFuture ? 1 : 0
3139
3633
  ]
3140
3634
 
3635
+ // Add is_default parameter if save_card is 1
3636
+ if isSavedForFuture {
3637
+ params["is_default"] = 1
3638
+ }
3639
+
3640
+ if let billingInfoData = request.billingInfoData {
3641
+ do {
3642
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
3643
+
3644
+ // Billing Info
3645
+ let billing = fieldSection.billing
3646
+ if !billing.isEmpty {
3647
+ var billingDict: [String: Any] = [:]
3648
+ billing.forEach { billingDict[$0.name] = $0.value }
3649
+
3650
+ if let address = billingDict["address"] as? String, !address.isEmpty {
3651
+ params["address"] = address
3652
+ }
3653
+ if let country = billingDict["country"] as? String, !country.isEmpty {
3654
+ params["country"] = country
3655
+ }
3656
+ if let state = billingDict["state"] as? String, !state.isEmpty {
3657
+ params["state"] = state
3658
+ }
3659
+ if let city = billingDict["city"] as? String, !city.isEmpty {
3660
+ params["city"] = city
3661
+ }
3662
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
3663
+ params["zip"] = postalCode
3664
+ }
3665
+ }
3666
+
3667
+ // Additional Info
3668
+ let additional = fieldSection.additional
3669
+ if !additional.isEmpty {
3670
+ var additionalDict: [String: Any] = [:]
3671
+ additional.forEach { additionalDict[$0.name] = $0.value }
3672
+
3673
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
3674
+ params["description"] = desc
3675
+ } else {
3676
+ params["description"] = "Hosted payment checkout"
3677
+ }
3678
+
3679
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
3680
+ params["phone_number"] = phone
3681
+ }
3682
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
3683
+ params["email"] = email
3684
+ }
3685
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
3686
+ params["name"] = name
3687
+ }
3688
+ } else {
3689
+ // If no description in additional info, set default
3690
+ params["description"] = "Hosted payment checkout"
3691
+ }
3692
+
3693
+ } catch {
3694
+ print("Failed to decode FieldSection: \(error)")
3695
+ params["description"] = "Hosted payment checkout"
3696
+ }
3697
+ } else {
3698
+ // Fallback if billingInfoData is missing
3699
+ params["description"] = "Hosted payment checkout"
3700
+ }
3701
+
3141
3702
  // Add these if recurring is enabled
3142
3703
  if let req = request, req.is_recurring == true {
3143
3704
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -3209,30 +3770,45 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3209
3770
  // Pass the selected payment method
3210
3771
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
3211
3772
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
3212
- // Pass billingInfo and additionalInfo
3213
- if let billingData = self.request.billingInfoData,
3214
- let billingInfoDict = try? JSONSerialization.jsonObject(with: billingData, options: []) as? [String: Any] {
3773
+ // // Pass billingInfo and additionalInfo
3774
+ // if let billingData = self.request.billingInfoData,
3775
+ // let billingInfoDict = try? JSONSerialization.jsonObject(with: billingData, options: []) as? [String: Any] {
3776
+ //
3777
+ // // Extract main billing fields
3778
+ // let cleanBillingInfo: [String: Any] = [
3779
+ // "postal_code": billingInfoDict["postal_code"] ?? "",
3780
+ // "country": billingInfoDict["country"] ?? "",
3781
+ // "city": billingInfoDict["city"] ?? "",
3782
+ // "address": billingInfoDict["address"] ?? "",
3783
+ // "state": billingInfoDict["state"] ?? ""
3784
+ // ]
3785
+ // paymentDoneVC.billingInfo = cleanBillingInfo
3786
+ //
3787
+ // // Extract additional_info
3788
+ // if let additional = billingInfoDict["additional_info"] as? [String: Any] {
3789
+ // let cleanAdditionalInfo: [String: Any] = [
3790
+ // "email": additional["email"] ?? "",
3791
+ // "phone_number": additional["phone_number"] ?? "",
3792
+ // "name": additional["name"] ?? "",
3793
+ // "country_code": additional["country_code"] ?? ""
3794
+ // ]
3795
+ // paymentDoneVC.additionalInfo = cleanAdditionalInfo
3796
+ // }
3797
+ // }
3798
+
3799
+ // Pass billing info and additional info if available
3800
+ if let billingInfoData = self.request.billingInfoData,
3801
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
3215
3802
 
3216
- // Extract main billing fields
3217
- let cleanBillingInfo: [String: Any] = [
3218
- "postal_code": billingInfoDict["postal_code"] ?? "",
3219
- "country": billingInfoDict["country"] ?? "",
3220
- "city": billingInfoDict["city"] ?? "",
3221
- "address": billingInfoDict["address"] ?? "",
3222
- "state": billingInfoDict["state"] ?? ""
3223
- ]
3224
- paymentDoneVC.billingInfo = cleanBillingInfo
3803
+ paymentDoneVC.billingInfoData = fieldSection.billing
3804
+ var billingDict: [String: Any] = [:]
3805
+ fieldSection.billing.forEach { billingDict[$0.name] = $0.value }
3806
+ paymentDoneVC.billingInfo = billingDict
3225
3807
 
3226
- // Extract additional_info
3227
- if let additional = billingInfoDict["additional_info"] as? [String: Any] {
3228
- let cleanAdditionalInfo: [String: Any] = [
3229
- "email": additional["email"] ?? "",
3230
- "phone_number": additional["phone_number"] ?? "",
3231
- "name": additional["name"] ?? "",
3232
- "country_code": additional["country_code"] ?? ""
3233
- ]
3234
- paymentDoneVC.additionalInfo = cleanAdditionalInfo
3235
- }
3808
+ paymentDoneVC.additionalInfoData = fieldSection.additional
3809
+ var additionalDict: [String: Any] = [:]
3810
+ fieldSection.additional.forEach { additionalDict[$0.name] = $0.value }
3811
+ paymentDoneVC.additionalInfo = additionalDict
3236
3812
  }
3237
3813
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
3238
3814
  }
@@ -3294,6 +3870,68 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3294
3870
  "currency": "usd",
3295
3871
  ]
3296
3872
 
3873
+ if let billingInfoData = request.billingInfoData {
3874
+ do {
3875
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
3876
+
3877
+ // Billing Info
3878
+ let billing = fieldSection.billing
3879
+ if !billing.isEmpty {
3880
+ var billingDict: [String: Any] = [:]
3881
+ billing.forEach { billingDict[$0.name] = $0.value }
3882
+
3883
+ if let address = billingDict["address"] as? String, !address.isEmpty {
3884
+ params["address"] = address
3885
+ }
3886
+ if let country = billingDict["country"] as? String, !country.isEmpty {
3887
+ params["country"] = country
3888
+ }
3889
+ if let state = billingDict["state"] as? String, !state.isEmpty {
3890
+ params["state"] = state
3891
+ }
3892
+ if let city = billingDict["city"] as? String, !city.isEmpty {
3893
+ params["city"] = city
3894
+ }
3895
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
3896
+ params["zip"] = postalCode
3897
+ }
3898
+ }
3899
+
3900
+ // Additional Info
3901
+ let additional = fieldSection.additional
3902
+ if !additional.isEmpty {
3903
+ var additionalDict: [String: Any] = [:]
3904
+ additional.forEach { additionalDict[$0.name] = $0.value }
3905
+
3906
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
3907
+ params["description"] = desc
3908
+ } else {
3909
+ params["description"] = "Hosted payment checkout"
3910
+ }
3911
+
3912
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
3913
+ params["phone_number"] = phone
3914
+ }
3915
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
3916
+ params["email"] = email
3917
+ }
3918
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
3919
+ params["name"] = name
3920
+ }
3921
+ } else {
3922
+ // If no description in additional info, set default
3923
+ params["description"] = "Hosted payment checkout"
3924
+ }
3925
+
3926
+ } catch {
3927
+ print("Failed to decode FieldSection: \(error)")
3928
+ params["description"] = "Hosted payment checkout"
3929
+ }
3930
+ } else {
3931
+ // Fallback if billingInfoData is missing
3932
+ params["description"] = "Hosted payment checkout"
3933
+ }
3934
+
3297
3935
  // Add these if recurring is enabled
3298
3936
  if let req = request, req.is_recurring == true {
3299
3937
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -3365,6 +4003,21 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3365
4003
  // Pass the selected payment method
3366
4004
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
3367
4005
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate // Pass the delegate
4006
+
4007
+ // Pass billing info and additional info if available
4008
+ if let billingInfoData = self.request.billingInfoData,
4009
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
4010
+
4011
+ paymentDoneVC.billingInfoData = fieldSection.billing
4012
+ var billingDict: [String: Any] = [:]
4013
+ fieldSection.billing.forEach { billingDict[$0.name] = $0.value }
4014
+ paymentDoneVC.billingInfo = billingDict
4015
+
4016
+ paymentDoneVC.additionalInfoData = fieldSection.additional
4017
+ var additionalDict: [String: Any] = [:]
4018
+ fieldSection.additional.forEach { additionalDict[$0.name] = $0.value }
4019
+ paymentDoneVC.additionalInfo = additionalDict
4020
+ }
3368
4021
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
3369
4022
  }
3370
4023
  }
@@ -3475,10 +4128,61 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3475
4128
  }
3476
4129
  }
3477
4130
 
3478
- // Redirect based on billing visibility
3479
- if fieldSection.visibility.billing {
4131
+ // // Redirect based on billing visibility
4132
+ // if fieldSection.visibility.billing {
4133
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
4134
+ // vc.cardNumber = cardNumber
4135
+ // vc.expiryDate = expiryDate
4136
+ // vc.cvv = cvv
4137
+ // vc.nameOnCard = cardName
4138
+ // vc.selectedPaymentMethod = self.selectedPaymentMethod
4139
+ // vc.isSavedForFuture = self.isSavedForFuture
4140
+ // vc.request = self.request
4141
+ // vc.chosenPlan = self.txtFieldChosePlanCard.text
4142
+ // vc.startDate = self.txtFieldStartDateCard.text
4143
+ // vc.userEmail = self.txtFieldEmailCardView.text
4144
+ // vc.amount = self.amount
4145
+ // vc.billingInfoData = billingInfoData
4146
+ // vc.billingInfo = fieldSection.billing
4147
+ // vc.additionalInfo = fieldSection.additional
4148
+ // vc.visibility = fieldSection.visibility
4149
+ // vc.easyPayDelegate = self.easyPayDelegate
4150
+ // self.navigationController?.pushViewController(vc, animated: true)
4151
+ // } else {
4152
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
4153
+ // vc.billingInfoData = billingInfoData
4154
+ // vc.cardNumber = cardNumber
4155
+ // vc.expiryDate = expiryDate
4156
+ // vc.cvv = cvv
4157
+ // vc.nameOnCard = cardName
4158
+ // vc.selectedPaymentMethod = self.selectedPaymentMethod
4159
+ // vc.isSavedForFuture = self.isSavedForFuture
4160
+ // vc.request = self.request
4161
+ // vc.chosenPlan = self.txtFieldChosePlanCard.text
4162
+ // vc.startDate = self.txtFieldStartDateCard.text
4163
+ // vc.userEmail = self.txtFieldEmailCardView.text
4164
+ // vc.billingInfo = fieldSection.billing
4165
+ // vc.additionalInfo = fieldSection.additional
4166
+ // vc.amount = self.amount
4167
+ // vc.visibility = fieldSection.visibility
4168
+ // vc.easyPayDelegate = self.easyPayDelegate
4169
+ // self.navigationController?.pushViewController(vc, animated: true)
4170
+ // }
4171
+
4172
+
4173
+ let showBilling = fieldSection.visibility.billing
4174
+ let showAdditional = fieldSection.visibility.additional
4175
+
4176
+ if !showBilling && !showAdditional {
4177
+ if self.isSavedForFuture {
4178
+ self.navigateCardDataToEmailVerificationVC()
4179
+ } else {
4180
+ self.threeDSecurePaymentApi()
4181
+ }
4182
+ }
4183
+ else if showBilling {
4184
+ // Push to BillingInfoVC
3480
4185
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
3481
- vc.billingInfoData = billingInfoData
3482
4186
  vc.cardNumber = cardNumber
3483
4187
  vc.expiryDate = expiryDate
3484
4188
  vc.cvv = cvv
@@ -3490,12 +4194,15 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3490
4194
  vc.startDate = self.txtFieldStartDateCard.text
3491
4195
  vc.userEmail = self.txtFieldEmailCardView.text
3492
4196
  vc.amount = self.amount
4197
+ vc.billingInfoData = billingInfoData
3493
4198
  vc.billingInfo = fieldSection.billing
3494
4199
  vc.additionalInfo = fieldSection.additional
3495
4200
  vc.visibility = fieldSection.visibility
3496
4201
  vc.easyPayDelegate = self.easyPayDelegate
3497
4202
  self.navigationController?.pushViewController(vc, animated: true)
3498
- } else {
4203
+ }
4204
+ else {
4205
+ // Push to AdditionalInfoVC
3499
4206
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
3500
4207
  vc.billingInfoData = billingInfoData
3501
4208
  vc.cardNumber = cardNumber
@@ -3802,33 +4509,65 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
3802
4509
 
3803
4510
  // Function to navigate to EmailVerificationVC
3804
4511
  func navigateCardDataToEmailVerificationVC() {
3805
- if let emailVerificationVC = storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
3806
- emailVerificationVC.cardNumber = self.cardNumberTextField.text
3807
- emailVerificationVC.expiryDate = self.cardExpiryTextField.text
3808
- emailVerificationVC.cvv = self.cardCvvTextField.text
3809
- emailVerificationVC.nameOnCard = self.cardNameTextField.text
3810
- emailVerificationVC.selectedPaymentMethod = self.selectedPaymentMethod
3811
- emailVerificationVC.isSavedForFuture = isSavedForFuture
3812
- emailVerificationVC.easyPayDelegate = self.easyPayDelegate // Pass delegate if needed
3813
- emailVerificationVC.request = self.request
3814
- emailVerificationVC.chosenPlan = self.txtFieldChosePlanCard.text
3815
- emailVerificationVC.startDate = self.txtFieldStartDateCard.text
4512
+ // if let emailVerificationVC = storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
4513
+ if let emailVerificationVC = storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
4514
+ if let billingInfoData = request.billingInfoData {
4515
+ do {
4516
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
4517
+ emailVerificationVC.billingInfoData = billingInfoData
4518
+ emailVerificationVC.billingInfo = fieldSection.billing
4519
+ emailVerificationVC.additionalInfo = fieldSection.additional
4520
+ emailVerificationVC.visibility = fieldSection.visibility
4521
+
4522
+ emailVerificationVC.cardNumber = self.cardNumberTextField.text
4523
+ emailVerificationVC.expiryDate = self.cardExpiryTextField.text
4524
+ emailVerificationVC.cvv = self.cardCvvTextField.text
4525
+ emailVerificationVC.nameOnCard = self.cardNameTextField.text
4526
+ emailVerificationVC.selectedPaymentMethod = self.selectedPaymentMethod
4527
+ emailVerificationVC.isSavedForFuture = isSavedForFuture
4528
+ emailVerificationVC.easyPayDelegate = self.easyPayDelegate // Pass delegate if needed
4529
+ emailVerificationVC.request = self.request
4530
+ emailVerificationVC.chosenPlan = self.txtFieldChosePlanCard.text
4531
+ emailVerificationVC.startDate = self.txtFieldStartDateCard.text
4532
+ emailVerificationVC.userEmail = self.txtFieldEmailCardView.text
4533
+ emailVerificationVC.email = self.txtFieldEmailCardView.text
4534
+ emailVerificationVC.amount = self.amount
4535
+ }
4536
+ catch {
4537
+ print("Failed to decode billingInfoData: \(error.localizedDescription)")
4538
+ }
4539
+ }
4540
+
3816
4541
  self.navigationController?.pushViewController(emailVerificationVC, animated: true)
3817
4542
  }
3818
4543
  }
3819
-
4544
+
3820
4545
  func navigateBankDataToEmailVerificationVC() {
3821
4546
  if let emailVerificationVC = storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
3822
- emailVerificationVC.accountName = txtFieldAccountName.text
3823
- emailVerificationVC.routingNumber = txtFieldRoutingNumber.text
3824
- emailVerificationVC.accountType = txtFieldAccountType.text
3825
- emailVerificationVC.accountNumber = txtFieldAccountNumber.text
3826
- emailVerificationVC.selectedPaymentMethod = self.selectedPaymentMethod
3827
- emailVerificationVC.isSavedForFuture = isSavedForFuture
3828
- emailVerificationVC.easyPayDelegate = self.easyPayDelegate // Pass delegate if needed
3829
- emailVerificationVC.chosenPlan = self.txtFieldSelectPlanViewBankFields.text
3830
- emailVerificationVC.startDate = self.txtFieldSelectDateViewBankFields.text
3831
- emailVerificationVC.request = self.request
4547
+ if let billingInfoData = request.billingInfoData {
4548
+ do {
4549
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
4550
+ emailVerificationVC.billingInfoData = billingInfoData
4551
+ emailVerificationVC.billingInfo = fieldSection.billing
4552
+ emailVerificationVC.additionalInfo = fieldSection.additional
4553
+ emailVerificationVC.visibility = fieldSection.visibility
4554
+
4555
+ emailVerificationVC.accountName = txtFieldAccountName.text
4556
+ emailVerificationVC.routingNumber = txtFieldRoutingNumber.text
4557
+ emailVerificationVC.accountType = txtFieldAccountType.text
4558
+ emailVerificationVC.accountNumber = txtFieldAccountNumber.text
4559
+ emailVerificationVC.selectedPaymentMethod = self.selectedPaymentMethod
4560
+ emailVerificationVC.isSavedForFuture = isSavedForFuture
4561
+ emailVerificationVC.easyPayDelegate = self.easyPayDelegate // Pass delegate if needed
4562
+ emailVerificationVC.chosenPlan = self.txtFieldSelectPlanViewBankFields.text
4563
+ emailVerificationVC.startDate = self.txtFieldSelectDateViewBankFields.text
4564
+ emailVerificationVC.request = self.request
4565
+ emailVerificationVC.userEmail = self.txtFieldEmailAccountView.text
4566
+ }
4567
+ catch {
4568
+ print("Failed to decode billingInfoData: \(error.localizedDescription)")
4569
+ }
4570
+ }
3832
4571
  self.navigationController?.pushViewController(emailVerificationVC, animated: true)
3833
4572
  }
3834
4573
  }
@@ -4076,11 +4815,54 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
4076
4815
  return
4077
4816
  }
4078
4817
 
4079
- // Redirect based on billing visibility
4080
- if fieldSection.visibility.billing {
4081
- // Proceed with the Pay Now action
4818
+ // // Redirect based on billing visibility
4819
+ // if fieldSection.visibility.billing {
4820
+ // // Proceed with the Pay Now action
4821
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
4822
+ // // Pass the customer_id and account_id to BillingInfoVC
4823
+ // vc.customerID = self.selectedbankAccounts?.customer_id
4824
+ // vc.accountID = self.selectedbankAccounts?.account_id
4825
+ // vc.billingInfoData = billingInfoData
4826
+ // vc.isFrom = "SavedBank"
4827
+ // vc.selectedPaymentMethod = "Bank"
4828
+ // vc.chosenPlan = self.txtFieldSelectPlanSingleSavedBankView.text
4829
+ // vc.startDate = self.txtFieldSelectDateSingleSavedBankView.text
4830
+ // vc.request = self.request
4831
+ // vc.amount = self.amount
4832
+ // vc.billingInfo = fieldSection.billing
4833
+ // vc.additionalInfo = fieldSection.additional
4834
+ // vc.visibility = fieldSection.visibility
4835
+ // vc.easyPayDelegate = self.easyPayDelegate
4836
+ // self.navigationController?.pushViewController(vc, animated: true)
4837
+ // }
4838
+ // else {
4839
+ // let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
4840
+ // vc.customerID = self.selectedbankAccounts?.customer_id
4841
+ // vc.accountID = self.selectedbankAccounts?.account_id
4842
+ // vc.billingInfoData = billingInfoData
4843
+ // vc.isFrom = "SavedBank"
4844
+ // vc.selectedPaymentMethod = "Bank"
4845
+ // vc.chosenPlan = self.txtFieldSelectPlanSingleSavedBankView.text
4846
+ // vc.startDate = self.txtFieldSelectDateSingleSavedBankView.text
4847
+ // vc.request = self.request
4848
+ // vc.amount = self.amount
4849
+ // vc.billingInfo = fieldSection.billing
4850
+ // vc.additionalInfo = fieldSection.additional
4851
+ // vc.visibility = fieldSection.visibility
4852
+ // vc.easyPayDelegate = self.easyPayDelegate
4853
+ // self.navigationController?.pushViewController(vc, animated: true)
4854
+ // }
4855
+
4856
+
4857
+ let showBilling = fieldSection.visibility.billing
4858
+ let showAdditional = fieldSection.visibility.additional
4859
+
4860
+ if !showBilling && !showAdditional {
4861
+ self.grailPayAaccountChargeSingleSavedAccountApi()
4862
+ }
4863
+ else if showBilling {
4864
+ // Push to BillingInfoVC
4082
4865
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "BillingInfoVC") as! BillingInfoVC
4083
- // Pass the customer_id and account_id to BillingInfoVC
4084
4866
  vc.customerID = self.selectedbankAccounts?.customer_id
4085
4867
  vc.accountID = self.selectedbankAccounts?.account_id
4086
4868
  vc.billingInfoData = billingInfoData
@@ -4097,6 +4879,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
4097
4879
  self.navigationController?.pushViewController(vc, animated: true)
4098
4880
  }
4099
4881
  else {
4882
+ // Push to AdditionalInfoVC
4100
4883
  let vc = easymerchantsdk.instantiateViewController(withIdentifier: "AdditionalInfoVC") as! AdditionalInfoVC
4101
4884
  vc.customerID = self.selectedbankAccounts?.customer_id
4102
4885
  vc.accountID = self.selectedbankAccounts?.account_id
@@ -4113,6 +4896,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
4113
4896
  vc.easyPayDelegate = self.easyPayDelegate
4114
4897
  self.navigationController?.pushViewController(vc, animated: true)
4115
4898
  }
4899
+
4116
4900
  }
4117
4901
  }
4118
4902
  }
@@ -4452,13 +5236,44 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
4452
5236
 
4453
5237
  //MARK: - Card Scan Button Action
4454
5238
  @IBAction func actionButtonScanCard(_ sender: UIButton) {
4455
-
4456
- }
4457
-
4458
- private func showLicenseErrorAlert(message: String) {
4459
- let alert = UIAlertController(title: "License Error", message: message, preferredStyle: .alert)
4460
- alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
4461
- self.present(alert, animated: true, completion: nil)
5239
+ // // Validate BlinkCard License
5240
+ // let licenseErrorMessage = BlinkCardHelper.setupLicense()
5241
+ // if !licenseErrorMessage.isEmpty {
5242
+ // // Show alert if the license is invalid or expired
5243
+ // showLicenseErrorAlert(message: licenseErrorMessage)
5244
+ // return
5245
+ // }
5246
+ //
5247
+ // // Proceed with card scanning if the license is valid
5248
+ // blinkCardRecognizer = MBCBlinkCardRecognizer()
5249
+ // blinkCardRecognizer.returnFullDocumentImage = true
5250
+ //
5251
+ // let recognizerList = [blinkCardRecognizer!]
5252
+ // let recognizerCollection = MBCRecognizerCollection(recognizers: recognizerList)
5253
+ //
5254
+ // let customOverlayViewController: CustomOverlay = CustomOverlay.initFromStoryboard()
5255
+ //
5256
+ // // Reconfigure recognizers with the overlay
5257
+ // customOverlayViewController.reconfigureRecognizers(recognizerCollection)
5258
+ //
5259
+ // // Create the recognizer runner view controller with custom overlay
5260
+ // guard let recognizerRunnerViewController =
5261
+ // MBCViewControllerFactory.recognizerRunnerViewController(withOverlayViewController: customOverlayViewController) else {
5262
+ // showLicenseErrorAlert(message: "Failed to initialize the recognizer view controller.")
5263
+ // return
5264
+ // }
5265
+ //
5266
+ // customOverlayViewController.delegate = self
5267
+ // recognizerRunnerViewController.modalPresentationStyle = .fullScreen
5268
+ //
5269
+ // // Present the recognizer runner view controller
5270
+ // self.present(recognizerRunnerViewController, animated: true, completion: nil)
5271
+ }
5272
+
5273
+ private func showLicenseErrorAlert(message: String) {
5274
+ let alert = UIAlertController(title: "License Error", message: message, preferredStyle: .alert)
5275
+ alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
5276
+ self.present(alert, animated: true, completion: nil)
4462
5277
  }
4463
5278
 
4464
5279
  //MARK: - Send OTP Email Verification Api
@@ -5170,6 +5985,210 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
5170
5985
  task.resume()
5171
5986
  }
5172
5987
 
5988
+ //MARK: - Credit Card Charge Api from Saved cards if Billing info exist but not go to billing and additonal page
5989
+ func paymentIntentFromShowCardApi() {
5990
+ showLoadingIndicator()
5991
+
5992
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.charges.path()
5993
+
5994
+ guard let serviceURL = URL(string: fullURL) else {
5995
+ print("Invalid URL")
5996
+ hideLoadingIndicator()
5997
+ return
5998
+ }
5999
+
6000
+ var uRLRequest = URLRequest(url: serviceURL)
6001
+ uRLRequest.httpMethod = "POST"
6002
+ uRLRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
6003
+
6004
+ let token = UserStoreSingleton.shared.clientToken
6005
+ print("Setting clientToken header: \(token ?? "None")")
6006
+ uRLRequest.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
6007
+
6008
+ var params: [String: Any] = [
6009
+ "currency": "usd",
6010
+ "payment_method": "card",
6011
+ "save_card": 0,
6012
+ "customer" : selectedCard?.customerId ?? "",
6013
+ "customer_id" : selectedCard?.customerId ?? "",
6014
+ "card_id" : selectedCard?.cardId ?? "",
6015
+ "cvc" : txtFieldCVVSingleSavedCard.text?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "",
6016
+ ]
6017
+
6018
+ if let billingInfoData = request.billingInfoData {
6019
+ do {
6020
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
6021
+
6022
+ // Billing Info
6023
+ let billing = fieldSection.billing
6024
+ if !billing.isEmpty {
6025
+ var billingDict: [String: Any] = [:]
6026
+ billing.forEach { billingDict[$0.name] = $0.value }
6027
+
6028
+ if let address = billingDict["address"] as? String, !address.isEmpty {
6029
+ params["address"] = address
6030
+ }
6031
+ if let country = billingDict["country"] as? String, !country.isEmpty {
6032
+ params["country"] = country
6033
+ }
6034
+ if let state = billingDict["state"] as? String, !state.isEmpty {
6035
+ params["state"] = state
6036
+ }
6037
+ if let city = billingDict["city"] as? String, !city.isEmpty {
6038
+ params["city"] = city
6039
+ }
6040
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
6041
+ params["zip"] = postalCode
6042
+ }
6043
+ }
6044
+
6045
+ // Additional Info
6046
+ let additional = fieldSection.additional
6047
+ if !additional.isEmpty {
6048
+ var additionalDict: [String: Any] = [:]
6049
+ additional.forEach { additionalDict[$0.name] = $0.value }
6050
+
6051
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
6052
+ params["description"] = desc
6053
+ } else {
6054
+ params["description"] = "Hosted payment checkout"
6055
+ }
6056
+
6057
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
6058
+ params["phone_number"] = phone
6059
+ }
6060
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
6061
+ params["email"] = email
6062
+ }
6063
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
6064
+ params["name"] = name
6065
+ }
6066
+ } else {
6067
+ // If no description in additional info, set default
6068
+ params["description"] = "Hosted payment checkout"
6069
+ }
6070
+
6071
+ } catch {
6072
+ print("Failed to decode FieldSection: \(error)")
6073
+ params["description"] = "Hosted payment checkout"
6074
+ }
6075
+ } else {
6076
+ // Fallback if billingInfoData is missing
6077
+ params["description"] = "Hosted payment checkout"
6078
+ }
6079
+
6080
+ // Add these if recurring is enabled
6081
+ if let req = request, req.is_recurring == true {
6082
+ if let recurringType = req.recurringStartDateType, recurringType == .custom {
6083
+ // Only send start_date if type is .custom and field is not empty
6084
+ if let startDateText = txtFieldSelectDateSingleSavedCard?.text, !startDateText.isEmpty {
6085
+ let inputFormatter = DateFormatter()
6086
+ inputFormatter.dateFormat = "dd/MM/yyyy"
6087
+
6088
+ let outputFormatter = DateFormatter()
6089
+ outputFormatter.dateFormat = "MM/dd/yyyy"
6090
+
6091
+ if let date = inputFormatter.date(from: startDateText) {
6092
+ let apiFormattedDate = outputFormatter.string(from: date)
6093
+ params["start_date"] = apiFormattedDate
6094
+ } else {
6095
+ print("Invalid date format in startDateText")
6096
+ }
6097
+ }
6098
+ }
6099
+
6100
+ params["interval"] = txtFieldSelectPlanSingleSavedCard.text.lowercased()
6101
+ }
6102
+
6103
+ do {
6104
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
6105
+ uRLRequest.httpBody = jsonData
6106
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
6107
+ print("JSON Payload: \(jsonString)")
6108
+ }
6109
+ } catch let error {
6110
+ print("Error creating JSON data: \(error)")
6111
+ hideLoadingIndicator()
6112
+ return
6113
+ }
6114
+
6115
+ let session = URLSession.shared
6116
+ let task = session.dataTask(with: uRLRequest) { (serviceData, serviceResponse, error) in
6117
+
6118
+ DispatchQueue.main.async {
6119
+ self.hideLoadingIndicator() // Stop loader when response is received
6120
+ }
6121
+
6122
+ if let error = error {
6123
+ print("Error: \(error.localizedDescription)")
6124
+ return
6125
+ }
6126
+
6127
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
6128
+ print("Invalid response")
6129
+ return
6130
+ }
6131
+
6132
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
6133
+ if let data = serviceData {
6134
+ do {
6135
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
6136
+ print("Response Data: \(responseObject)")
6137
+
6138
+ // Check if status is 0 and handle the error
6139
+ if let status = responseObject["status"] as? Int, status == 0 {
6140
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
6141
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
6142
+ } else {
6143
+ DispatchQueue.main.async {
6144
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
6145
+ paymentDoneVC.chargeData = responseObject
6146
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
6147
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate
6148
+ // Pass billing info and additional info if available
6149
+ if let billingInfoData = self.request.billingInfoData,
6150
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
6151
+
6152
+ // Filter billing info: only include non-empty values
6153
+ let filteredBilling = fieldSection.billing.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
6154
+ paymentDoneVC.billingInfoData = filteredBilling
6155
+ var billingDict: [String: Any] = [:]
6156
+ filteredBilling.forEach { billingDict[$0.name] = $0.value }
6157
+ paymentDoneVC.billingInfo = billingDict
6158
+
6159
+ // Filter additional info: only include non-empty values
6160
+ let filteredAdditional = fieldSection.additional.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
6161
+ paymentDoneVC.additionalInfoData = filteredAdditional
6162
+ var additionalDict: [String: Any] = [:]
6163
+ filteredAdditional.forEach { additionalDict[$0.name] = $0.value }
6164
+ paymentDoneVC.additionalInfo = additionalDict
6165
+ }
6166
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
6167
+ }
6168
+ }
6169
+ }
6170
+ } else {
6171
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
6172
+ }
6173
+ } catch let jsonError {
6174
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
6175
+ }
6176
+ } else {
6177
+ self.presentPaymentErrorVC(errorMessage: "No data received")
6178
+ }
6179
+ } else {
6180
+ if let data = serviceData,
6181
+ let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
6182
+ let message = responseObj["message"] as? String {
6183
+ self.presentPaymentErrorVC(errorMessage: message)
6184
+ } else {
6185
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
6186
+ }
6187
+ }
6188
+ }
6189
+ task.resume()
6190
+ }
6191
+
5173
6192
  //MARK: - Credit Card Charge Api from Add new cards If Billing info is nil and Logged in.
5174
6193
  func paymentIntentFromAddNewCardApi(customerId: String?) {
5175
6194
  // Get the text fields from the selected cell and trim whitespace
@@ -6811,6 +7830,68 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
6811
7830
  "tokenize": request.tokenOnly ?? false,
6812
7831
  ]
6813
7832
 
7833
+ if let billingInfoData = request.billingInfoData {
7834
+ do {
7835
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
7836
+
7837
+ // Billing Info
7838
+ let billing = fieldSection.billing
7839
+ if !billing.isEmpty {
7840
+ var billingDict: [String: Any] = [:]
7841
+ billing.forEach { billingDict[$0.name] = $0.value }
7842
+
7843
+ if let address = billingDict["address"] as? String, !address.isEmpty {
7844
+ params["address"] = address
7845
+ }
7846
+ if let country = billingDict["country"] as? String, !country.isEmpty {
7847
+ params["country"] = country
7848
+ }
7849
+ if let state = billingDict["state"] as? String, !state.isEmpty {
7850
+ params["state"] = state
7851
+ }
7852
+ if let city = billingDict["city"] as? String, !city.isEmpty {
7853
+ params["city"] = city
7854
+ }
7855
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
7856
+ params["zip"] = postalCode
7857
+ }
7858
+ }
7859
+
7860
+ // Additional Info
7861
+ let additional = fieldSection.additional
7862
+ if !additional.isEmpty {
7863
+ var additionalDict: [String: Any] = [:]
7864
+ additional.forEach { additionalDict[$0.name] = $0.value }
7865
+
7866
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
7867
+ params["description"] = desc
7868
+ } else {
7869
+ params["description"] = "Hosted payment checkout"
7870
+ }
7871
+
7872
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
7873
+ params["phone_number"] = phone
7874
+ }
7875
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
7876
+ params["email"] = email
7877
+ }
7878
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
7879
+ params["name"] = name
7880
+ }
7881
+ } else {
7882
+ // If no description in additional info, set default
7883
+ params["description"] = "Hosted payment checkout"
7884
+ }
7885
+
7886
+ } catch {
7887
+ print("Failed to decode FieldSection: \(error)")
7888
+ params["description"] = "Hosted payment checkout"
7889
+ }
7890
+ } else {
7891
+ // Fallback if billingInfoData is missing
7892
+ params["description"] = "Hosted payment checkout"
7893
+ }
7894
+
6814
7895
  // Add these if recurring is enabled
6815
7896
  if let req = request, req.is_recurring == true {
6816
7897
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -6884,30 +7965,23 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
6884
7965
  paymentDoneVC.chargeData = responseObject
6885
7966
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
6886
7967
  paymentDoneVC.amount = self.amount
6887
- // Pass billingInfo and additionalInfo
6888
- if let billingData = self.request.billingInfoData,
6889
- let billingInfoDict = try? JSONSerialization.jsonObject(with: billingData, options: []) as? [String: Any] {
7968
+ // Pass billing info and additional info if available
7969
+ if let billingInfoData = self.request.billingInfoData,
7970
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
6890
7971
 
6891
- // Extract main billing fields
6892
- let cleanBillingInfo: [String: Any] = [
6893
- "postal_code": billingInfoDict["postal_code"] ?? "",
6894
- "country": billingInfoDict["country"] ?? "",
6895
- "city": billingInfoDict["city"] ?? "",
6896
- "address": billingInfoDict["address"] ?? "",
6897
- "state": billingInfoDict["state"] ?? ""
6898
- ]
6899
- paymentDoneVC.billingInfo = cleanBillingInfo
6900
-
6901
- // Extract additional_info
6902
- if let additional = billingInfoDict["additional_info"] as? [String: Any] {
6903
- let cleanAdditionalInfo: [String: Any] = [
6904
- "email": additional["email"] ?? "",
6905
- "phone_number": additional["phone_number"] ?? "",
6906
- "name": additional["name"] ?? "",
6907
- "country_code": additional["country_code"] ?? ""
6908
- ]
6909
- paymentDoneVC.additionalInfo = cleanAdditionalInfo
6910
- }
7972
+ // Filter billing info: only include non-empty values
7973
+ let filteredBilling = fieldSection.billing.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
7974
+ paymentDoneVC.billingInfoData = filteredBilling
7975
+ var billingDict: [String: Any] = [:]
7976
+ filteredBilling.forEach { billingDict[$0.name] = $0.value }
7977
+ paymentDoneVC.billingInfo = billingDict
7978
+
7979
+ // Filter additional info: only include non-empty values
7980
+ let filteredAdditional = fieldSection.additional.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
7981
+ paymentDoneVC.additionalInfoData = filteredAdditional
7982
+ var additionalDict: [String: Any] = [:]
7983
+ filteredAdditional.forEach { additionalDict[$0.name] = $0.value }
7984
+ paymentDoneVC.additionalInfo = additionalDict
6911
7985
  }
6912
7986
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
6913
7987
  }
@@ -7048,6 +8122,68 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
7048
8122
  params["is_default"] = "1"
7049
8123
  }
7050
8124
 
8125
+ if let billingInfoData = request.billingInfoData {
8126
+ do {
8127
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
8128
+
8129
+ // Billing Info
8130
+ let billing = fieldSection.billing
8131
+ if !billing.isEmpty {
8132
+ var billingDict: [String: Any] = [:]
8133
+ billing.forEach { billingDict[$0.name] = $0.value }
8134
+
8135
+ if let address = billingDict["address"] as? String, !address.isEmpty {
8136
+ params["address"] = address
8137
+ }
8138
+ if let country = billingDict["country"] as? String, !country.isEmpty {
8139
+ params["country"] = country
8140
+ }
8141
+ if let state = billingDict["state"] as? String, !state.isEmpty {
8142
+ params["state"] = state
8143
+ }
8144
+ if let city = billingDict["city"] as? String, !city.isEmpty {
8145
+ params["city"] = city
8146
+ }
8147
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
8148
+ params["zip"] = postalCode
8149
+ }
8150
+ }
8151
+
8152
+ // Additional Info
8153
+ let additional = fieldSection.additional
8154
+ if !additional.isEmpty {
8155
+ var additionalDict: [String: Any] = [:]
8156
+ additional.forEach { additionalDict[$0.name] = $0.value }
8157
+
8158
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
8159
+ params["description"] = desc
8160
+ } else {
8161
+ params["description"] = "Hosted payment checkout"
8162
+ }
8163
+
8164
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
8165
+ params["phone_number"] = phone
8166
+ }
8167
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
8168
+ params["email"] = email
8169
+ }
8170
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
8171
+ params["name"] = name
8172
+ }
8173
+ } else {
8174
+ // If no description in additional info, set default
8175
+ params["description"] = "Hosted payment checkout"
8176
+ }
8177
+
8178
+ } catch {
8179
+ print("Failed to decode FieldSection: \(error)")
8180
+ params["description"] = "Hosted payment checkout"
8181
+ }
8182
+ } else {
8183
+ // Fallback if billingInfoData is missing
8184
+ params["description"] = "Hosted payment checkout"
8185
+ }
8186
+
7051
8187
  // Add these if recurring is enabled
7052
8188
  if let req = request, req.is_recurring == true {
7053
8189
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -7119,30 +8255,23 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
7119
8255
  paymentDoneVC.chargeData = responseObject
7120
8256
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
7121
8257
  paymentDoneVC.amount = self.amount
7122
- // Pass billingInfo and additionalInfo
7123
- if let billingData = self.request.billingInfoData,
7124
- let billingInfoDict = try? JSONSerialization.jsonObject(with: billingData, options: []) as? [String: Any] {
8258
+ // Pass billing info and additional info if available
8259
+ if let billingInfoData = self.request.billingInfoData,
8260
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
7125
8261
 
7126
- // Extract main billing fields
7127
- let cleanBillingInfo: [String: Any] = [
7128
- "postal_code": billingInfoDict["postal_code"] ?? "",
7129
- "country": billingInfoDict["country"] ?? "",
7130
- "city": billingInfoDict["city"] ?? "",
7131
- "address": billingInfoDict["address"] ?? "",
7132
- "state": billingInfoDict["state"] ?? ""
7133
- ]
7134
- paymentDoneVC.billingInfo = cleanBillingInfo
7135
-
7136
- // Extract additional_info
7137
- if let additional = billingInfoDict["additional_info"] as? [String: Any] {
7138
- let cleanAdditionalInfo: [String: Any] = [
7139
- "email": additional["email"] ?? "",
7140
- "phone_number": additional["phone_number"] ?? "",
7141
- "name": additional["name"] ?? "",
7142
- "country_code": additional["country_code"] ?? ""
7143
- ]
7144
- paymentDoneVC.additionalInfo = cleanAdditionalInfo
7145
- }
8262
+ // Filter billing info: only include non-empty values
8263
+ let filteredBilling = fieldSection.billing.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
8264
+ paymentDoneVC.billingInfoData = filteredBilling
8265
+ var billingDict: [String: Any] = [:]
8266
+ filteredBilling.forEach { billingDict[$0.name] = $0.value }
8267
+ paymentDoneVC.billingInfo = billingDict
8268
+
8269
+ // Filter additional info: only include non-empty values
8270
+ let filteredAdditional = fieldSection.additional.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
8271
+ paymentDoneVC.additionalInfoData = filteredAdditional
8272
+ var additionalDict: [String: Any] = [:]
8273
+ filteredAdditional.forEach { additionalDict[$0.name] = $0.value }
8274
+ paymentDoneVC.additionalInfo = additionalDict
7146
8275
  }
7147
8276
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
7148
8277
  }
@@ -8354,6 +9483,15 @@ extension PaymentInfoVC: UITextFieldDelegate {
8354
9483
  viewTxtFieldConfirmNewAccountView.layer.borderColor = UIColor._1757D9.withAlphaComponent(1).cgColor
8355
9484
  }
8356
9485
  }
9486
+ else if textField == txtFieldEmailGrailPayView.textField {
9487
+ if let primaryBtnFontColor = UserStoreSingleton.shared.primary_btn_bg_col,
9488
+ let uiColor = UIColor(hex: primaryBtnFontColor) {
9489
+ viewTxtFieldEmailGrailPayView.layer.borderColor = uiColor.cgColor
9490
+ } else {
9491
+ viewTxtFieldEmailGrailPayView.layer.borderColor = UIColor._1757D9.withAlphaComponent(1).cgColor
9492
+ }
9493
+ }
9494
+
8357
9495
  }
8358
9496
 
8359
9497
  func textFieldDidEndEditing(_ textField: UITextField) {
@@ -8561,6 +9699,14 @@ extension PaymentInfoVC: UITextFieldDelegate {
8561
9699
  viewTxtFieldConfirmNewAccountView.layer.borderColor = UIColor.systemGray.cgColor
8562
9700
  }
8563
9701
  }
9702
+ else if textField == txtFieldEmailGrailPayView.textField {
9703
+ if let bodyBackgroundColor = UserStoreSingleton.shared.secondary_font_col,
9704
+ let borderColor = UIColor(hex: bodyBackgroundColor) {
9705
+ viewTxtFieldEmailGrailPayView.layer.borderColor = borderColor.cgColor
9706
+ } else {
9707
+ viewTxtFieldEmailGrailPayView.layer.borderColor = UIColor.systemGray.cgColor
9708
+ }
9709
+ }
8564
9710
  }
8565
9711
 
8566
9712
  }