@jimrising/easymerchantsdk-react-native 1.3.9 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.idea/caches/deviceStreaming.xml +77 -0
  2. package/README.md +140 -81
  3. package/android/.gradle/8.10/checksums/checksums.lock +0 -0
  4. package/android/.gradle/8.10/checksums/md5-checksums.bin +0 -0
  5. package/android/.gradle/8.10/checksums/sha1-checksums.bin +0 -0
  6. package/android/.gradle/8.10/fileHashes/fileHashes.lock +0 -0
  7. package/android/.gradle/8.9/checksums/checksums.lock +0 -0
  8. package/android/.gradle/8.9/checksums/md5-checksums.bin +0 -0
  9. package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
  10. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  11. package/android/.gradle/buildOutputCleanup/cache.properties +1 -1
  12. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/results.bin +1 -0
  13. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/BuildConfig.dex +0 -0
  14. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$1.dex +0 -0
  15. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  16. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  17. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkPackage.dex +0 -0
  18. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  19. package/android/build/.transforms/e9a664a11ce12edf79cd87b1e07aa243/results.bin +1 -0
  20. package/android/build/.transforms/e9a664a11ce12edf79cd87b1e07aa243/transformed/classes/classes_dex/classes.dex +0 -0
  21. package/android/build/generated/source/buildConfig/debug/com/reactlibrary/BuildConfig.java +10 -0
  22. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +7 -0
  23. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +18 -0
  24. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +6 -0
  25. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +1 -0
  26. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  27. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  28. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
  29. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -0
  30. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +2 -0
  31. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +2 -0
  32. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +2 -0
  33. package/android/build/intermediates/incremental/packageDebugAssets/merger.xml +2 -0
  34. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/BuildConfig.class +0 -0
  35. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  36. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  37. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  38. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkPackage.class +0 -0
  39. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +2 -0
  40. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +7 -0
  41. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +7 -0
  42. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +1 -0
  43. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +1 -0
  44. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/BuildConfig.class +0 -0
  45. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  46. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  47. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  48. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkPackage.class +0 -0
  49. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  50. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +1 -0
  51. package/android/build/outputs/logs/manifest-merger-debug-report.txt +17 -0
  52. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1.class.uniqueId2 +0 -0
  53. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$2.class.uniqueId0 +0 -0
  54. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule.class.uniqueId3 +0 -0
  55. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkPackage.class.uniqueId1 +0 -0
  56. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  57. package/android/build.gradle +4 -1
  58. package/android/src/main/java/com/reactlibrary/RNEasymerchantsdkModule.java +158 -36
  59. package/android/src/main/java/com/reactlibrary/RNEasymerchantsdkPackage.java +45 -13
  60. package/ios/Classes/EasyMerchantSdk.m +106 -55
  61. package/ios/Classes/EasyMerchantSdk.swift +199 -77
  62. package/ios/Classes/EasyPayViewController.swift +1 -1
  63. package/ios/CustomComponents/DatePickerHandler.swift +15 -4
  64. package/ios/EnvironmentConfig.swift +32 -30
  65. package/ios/Models/Request.swift +176 -14
  66. package/ios/Models/Result.swift +12 -5
  67. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +855 -366
  68. package/ios/Pods/ViewControllers/BaseVC.swift +51 -36
  69. package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +1985 -178
  70. package/ios/Pods/ViewControllers/CountryListVC.swift +20 -1
  71. package/ios/Pods/ViewControllers/CustomOverlay.swift +199 -0
  72. package/ios/Pods/ViewControllers/EmailVerificationVC.swift +74 -5
  73. package/ios/Pods/ViewControllers/GrailPayVC.swift +131 -107
  74. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +296 -106
  75. package/ios/Pods/ViewControllers/PaymentDoneVC.swift +35 -26
  76. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +1276 -545
  77. package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +607 -24
  78. package/ios/easymerchantsdk.podspec +1 -1
  79. package/ios/easymerchantsdk.storyboard +1388 -1165
  80. package/package.json +1 -1
@@ -34,7 +34,7 @@ class OTPVerificationVC: BaseVC {
34
34
  var expiryDate: String?
35
35
  var cvv: String?
36
36
  var nameOnCard: String?
37
- var billingInfoData: [String: Any]?
37
+ var billingInfoData: Data?
38
38
 
39
39
  var email: String?
40
40
 
@@ -65,6 +65,13 @@ class OTPVerificationVC: BaseVC {
65
65
  var chosenPlan: String?
66
66
  var startDate: String?
67
67
 
68
+ var userEmail: String?
69
+
70
+ var fieldSection: FieldSection?
71
+ var additionalInfo: [FieldItem]?
72
+ var billingInfo: [FieldItem]?
73
+ var visibility: FieldsVisibility?
74
+
68
75
  override func viewDidLoad() {
69
76
  super.viewDidLoad()
70
77
 
@@ -77,6 +84,25 @@ class OTPVerificationVC: BaseVC {
77
84
  setupTextFields()
78
85
 
79
86
  btnResendOTP.isHidden = true
87
+
88
+ print(fieldSection ?? "")
89
+ print(additionalInfo ?? "")
90
+ print(billingInfo ?? "")
91
+ print(visibility ?? "")
92
+
93
+ // Decode request.billingInfoData
94
+ if let billingData = request?.billingInfoData {
95
+ do {
96
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingData)
97
+ self.visibility = fieldSection.visibility
98
+ self.billingInfo = fieldSection.billing
99
+ self.additionalInfo = fieldSection.additional
100
+ } catch {
101
+ print("Failed to decode billing info: \(error)")
102
+ }
103
+ }
104
+
105
+ decodeBillingInfo()
80
106
  }
81
107
 
82
108
  override func viewWillAppear(_ animated: Bool) {
@@ -84,6 +110,26 @@ class OTPVerificationVC: BaseVC {
84
110
  uiFinishingTouchElements()
85
111
  }
86
112
 
113
+ // MARK: - Decode billingInfoData
114
+ private func decodeBillingInfo() {
115
+ guard let data = billingInfoData else {
116
+ print("No billingInfoData found")
117
+ return
118
+ }
119
+
120
+ do {
121
+ let decodedSection = try JSONDecoder().decode(FieldSection.self, from: data)
122
+ self.fieldSection = decodedSection
123
+ self.billingInfo = decodedSection.billing
124
+ self.additionalInfo = decodedSection.additional
125
+ self.visibility = decodedSection.visibility
126
+
127
+ print("Decoded billingInfo: \(billingInfo ?? [])")
128
+ } catch {
129
+ print("Failed to decode billing info data: \(error)")
130
+ }
131
+ }
132
+
87
133
  //MARK: - Ui Colors Setup.
88
134
  func uiFinishingTouchElements() {
89
135
  if let containerBGcolor = UserStoreSingleton.shared.container_bg_col,
@@ -294,7 +340,7 @@ class OTPVerificationVC: BaseVC {
294
340
  let customerId = innerData["customer_id"] as? String {
295
341
  print("Extracted customer_id: \(customerId)")
296
342
  if self.billingInfoData == nil {
297
- if self.request.enable3DS == true {
343
+ if self.request.secureAuthentication == true {
298
344
  self.threeDSecurePaymentApi(customerId: customerId)
299
345
  }
300
346
  else {
@@ -304,7 +350,7 @@ class OTPVerificationVC: BaseVC {
304
350
  else {
305
351
  // self.paymentIntentApi(customerId: customerId)
306
352
  if let request = self.request {
307
- if request.enable3DS == true {
353
+ if request.secureAuthentication == true {
308
354
  self.threeDSecurePaymentSavedCardApi(customerId: customerId)
309
355
  } else {
310
356
  self.paymentIntentApi(customerId: customerId)
@@ -337,7 +383,6 @@ class OTPVerificationVC: BaseVC {
337
383
  self.accountChargeApi(customerId: nil)
338
384
  }
339
385
  }
340
-
341
386
  }
342
387
  else if self.selectedPaymentMethod == "GrailPay" {
343
388
  if let dataSection = responseObject["data"] as? [String: Any],
@@ -350,6 +395,17 @@ class OTPVerificationVC: BaseVC {
350
395
  self.grailPayAccountChargeApi(customerId: nil)
351
396
  }
352
397
  }
398
+ else if self.selectedPaymentMethod == "NewGrailPayAccount" {
399
+ if let dataSection = responseObject["data"] as? [String: Any],
400
+ let innerData = dataSection["data"] as? [String: Any],
401
+ let customerId = innerData["customer_id"] as? String {
402
+ print("Extracted customer_id: \(customerId)")
403
+ self.grailPayAccountChargeApi(customerId: customerId)
404
+ } else {
405
+ print("customer_id not found. Sending empty customerId.")
406
+ self.grailPayAccountChargeApi(customerId: nil)
407
+ }
408
+ }
353
409
  } else {
354
410
  print("Invalid JSON format")
355
411
  }
@@ -476,54 +532,63 @@ class OTPVerificationVC: BaseVC {
476
532
  uRLRequest.addValue(apiSecret, forHTTPHeaderField: "x-api-secret")
477
533
  }
478
534
 
479
- guard let billingInfoData = billingInfoData else {
480
- print("Billing info data is nil")
481
- return
482
- }
483
-
484
- let additionalInfoFromBilling = billingInfoData["additional_info"] as? [String: Any] ?? [:]
485
-
486
- let additionalInfo: [String: Any] = [
487
- "name": additionalInfoFromBilling["name"] as? String ?? "",
488
- "email": additionalInfoFromBilling["email"] as? String ?? "",
489
- "phone_number": additionalInfoFromBilling["phone_number"] as? String ?? "",
490
- "description": additionalInfoFromBilling["description"] as? String ?? ""
491
- ]
492
-
493
- let billingInfo: [String: Any] = [
494
- "address": billingInfoData["address"] as? String ?? "",
495
- "country": billingInfoData["country"] as? String ?? "",
496
- "state": billingInfoData["state"] as? String ?? "",
497
- "city": billingInfoData["city"] as? String ?? "",
498
- "postal_code": billingInfoData["postal_code"] as? String ?? ""
499
- ]
500
-
501
- let emailPrefix = email?.components(separatedBy: "@").first ?? ""
535
+ // let emailPrefix = email?.components(separatedBy: "@").first ?? ""
502
536
 
503
537
  var params: [String: Any] = [
504
- "name": additionalInfoFromBilling["name"] as? String ?? "",
538
+ "name": nameOnCard ?? "",
505
539
  "card_number": cardNumber?.replacingOccurrences(of: " ", with: "") ?? "",
506
540
  "cardholder_name": nameOnCard ?? "",
507
541
  "exp_month": expiryDate?.components(separatedBy: "/").first ?? "",
508
542
  "exp_year": expiryDate?.components(separatedBy: "/").last ?? "",
509
543
  "cvc": cvv ?? "",
510
- "description": additionalInfoFromBilling["description"] as? String ?? "",
511
544
  "currency": "usd",
512
- "billing_info": billingInfo,
513
- "additional_info": additionalInfo,
514
- "payment_method": selectedPaymentMethod ?? "",
545
+ // "payment_method": selectedPaymentMethod ?? "",
515
546
  "save_card": 1,
516
- "is_default": "1"
547
+ "is_default": "1",
548
+ // "create_customer": "1"
549
+ // "email": userEmail ?? ""
517
550
  ]
518
551
 
519
552
  if let customerId = customerId {
520
- params["customer"] = customerId
553
+ // params["customer"] = customerId
521
554
  params["customer_id"] = customerId
522
- } else {
523
- params["username"] = emailPrefix
524
- params["email"] = email ?? ""
555
+ }
556
+ // else {
557
+ // params["username"] = emailPrefix
558
+ // params["email"] = userEmail ?? ""
559
+ // }
560
+
561
+ // Billing Info
562
+ if let visibility = visibility, visibility.billing == true,
563
+ let billing = billingInfo, !billing.isEmpty {
564
+ var billingDict: [String: Any] = [:]
565
+ billing.forEach { billingDict[$0.name] = $0.value }
566
+
567
+ params["address"] = billingDict["address"] as? String ?? ""
568
+ params["country"] = billingDict["country"] as? String ?? ""
569
+ params["state"] = billingDict["state"] as? String ?? ""
570
+ params["city"] = billingDict["city"] as? String ?? ""
571
+ params["zip"] = billingDict["postal_code"] as? String ?? ""
525
572
  }
526
573
 
574
+ // Additional Info or default description
575
+ var descriptionValue: String = "Hosted payment checkout" // default
576
+ if let visibility = visibility, visibility.additional == true,
577
+ let additional = additionalInfo, !additional.isEmpty {
578
+
579
+ var additionalDict: [String: Any] = [:]
580
+ additional.forEach { additionalDict[$0.name] = $0.value }
581
+
582
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
583
+ descriptionValue = desc
584
+ }
585
+
586
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
587
+ params["phone_number"] = phone
588
+ }
589
+ }
590
+ params["description"] = descriptionValue
591
+
527
592
  // Add these if recurring is enabled
528
593
  if let req = request, req.is_recurring == true {
529
594
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -595,8 +660,22 @@ class OTPVerificationVC: BaseVC {
595
660
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
596
661
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
597
662
  // Pass billing and additional info
598
- paymentDoneVC.billingInfo = billingInfo
599
- paymentDoneVC.additionalInfo = additionalInfo
663
+ // Conditionally pass raw FieldItem array
664
+ paymentDoneVC.visibility = self.visibility
665
+
666
+ if self.visibility?.billing == true {
667
+ paymentDoneVC.billingInfoData = self.billingInfo
668
+ var billingDict: [String: Any] = [:]
669
+ self.billingInfo?.forEach { billingDict[$0.name] = $0.value }
670
+ paymentDoneVC.billingInfo = billingDict
671
+ }
672
+
673
+ if self.visibility?.additional == true {
674
+ paymentDoneVC.additionalInfoData = self.additionalInfo
675
+ var additionalDict: [String: Any] = [:]
676
+ self.additionalInfo?.forEach { additionalDict[$0.name] = $0.value }
677
+ paymentDoneVC.additionalInfo = additionalDict
678
+ }
600
679
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
601
680
  }
602
681
  }
@@ -807,37 +886,12 @@ class OTPVerificationVC: BaseVC {
807
886
  uRLRequest.addValue(apiSecret, forHTTPHeaderField: "x-api-secret")
808
887
  }
809
888
 
810
- guard let billingInfoData = billingInfoData else {
811
- print("Billing info data is nil")
812
- return
813
- }
814
-
815
- let additionalInfoFromBilling = billingInfoData["additional_info"] as? [String: Any] ?? [:]
816
-
817
- let additionalInfo: [String: Any] = [
818
- "name": additionalInfoFromBilling["name"] as? String ?? "",
819
- "email": additionalInfoFromBilling["email"] as? String ?? "",
820
- "phone_number": additionalInfoFromBilling["phone_number"] as? String ?? "",
821
- "description": additionalInfoFromBilling["description"] as? String ?? ""
822
- ]
823
-
824
- let billingInfo: [String: Any] = [
825
- "address": billingInfoData["address"] as? String ?? "",
826
- "country": billingInfoData["country"] as? String ?? "",
827
- "state": billingInfoData["state"] as? String ?? "",
828
- "city": billingInfoData["city"] as? String ?? "",
829
- "postal_code": billingInfoData["postal_code"] as? String ?? ""
830
- ]
831
-
832
889
  let emailPrefix = email?.components(separatedBy: "@").first ?? ""
833
890
 
834
891
  var params: [String: Any] = [
835
- "name": additionalInfoFromBilling["name"] as? String ?? "",
892
+ "name": accountName ?? "",
836
893
  "email": email ?? "",
837
- "description": additionalInfoFromBilling["description"] as? String ?? "",
838
894
  "currency": "usd",
839
- "billing_info": billingInfo,
840
- "additional_info": additionalInfo,
841
895
  "account_type": accountType?.lowercased() ?? "",
842
896
  "routing_number": routingNumber ?? "",
843
897
  "account_number": accountNumber ?? "",
@@ -854,6 +908,37 @@ class OTPVerificationVC: BaseVC {
854
908
  params["username"] = emailPrefix
855
909
  }
856
910
 
911
+ // Billing Info
912
+ if let visibility = visibility, visibility.billing == true,
913
+ let billing = billingInfo, !billing.isEmpty {
914
+ var billingDict: [String: Any] = [:]
915
+ billing.forEach { billingDict[$0.name] = $0.value }
916
+
917
+ params["address"] = billingDict["address"] as? String ?? ""
918
+ params["country"] = billingDict["country"] as? String ?? ""
919
+ params["state"] = billingDict["state"] as? String ?? ""
920
+ params["city"] = billingDict["city"] as? String ?? ""
921
+ params["zip"] = billingDict["postal_code"] as? String ?? ""
922
+ }
923
+
924
+ // Additional Info or default description
925
+ var descriptionValue: String = "Hosted payment checkout" // default
926
+ if let visibility = visibility, visibility.additional == true,
927
+ let additional = additionalInfo, !additional.isEmpty {
928
+
929
+ var additionalDict: [String: Any] = [:]
930
+ additional.forEach { additionalDict[$0.name] = $0.value }
931
+
932
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
933
+ descriptionValue = desc
934
+ }
935
+
936
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
937
+ params["phone_number"] = phone
938
+ }
939
+ }
940
+ params["description"] = descriptionValue
941
+
857
942
  // Add these if recurring is enabled
858
943
  if let req = request, req.is_recurring == true {
859
944
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -925,8 +1010,22 @@ class OTPVerificationVC: BaseVC {
925
1010
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
926
1011
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
927
1012
  // Pass billing and additional info
928
- paymentDoneVC.billingInfo = billingInfo
929
- paymentDoneVC.additionalInfo = additionalInfo
1013
+ // Conditionally pass raw FieldItem array
1014
+ paymentDoneVC.visibility = self.visibility
1015
+
1016
+ if self.visibility?.billing == true {
1017
+ paymentDoneVC.billingInfoData = self.billingInfo
1018
+ var billingDict: [String: Any] = [:]
1019
+ self.billingInfo?.forEach { billingDict[$0.name] = $0.value }
1020
+ paymentDoneVC.billingInfo = billingDict
1021
+ }
1022
+
1023
+ if self.visibility?.additional == true {
1024
+ paymentDoneVC.additionalInfoData = self.additionalInfo
1025
+ var additionalDict: [String: Any] = [:]
1026
+ self.additionalInfo?.forEach { additionalDict[$0.name] = $0.value }
1027
+ paymentDoneVC.additionalInfo = additionalDict
1028
+ }
930
1029
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
931
1030
  }
932
1031
  }
@@ -1111,36 +1210,91 @@ class OTPVerificationVC: BaseVC {
1111
1210
  return
1112
1211
  }
1113
1212
 
1114
- var request = URLRequest(url: serviceURL)
1115
- request.httpMethod = "POST"
1116
- request.addValue("application/json", forHTTPHeaderField: "Content-Type")
1213
+ var uRLRequest = URLRequest(url: serviceURL)
1214
+ uRLRequest.httpMethod = "POST"
1215
+ uRLRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
1117
1216
 
1118
1217
  let token = UserStoreSingleton.shared.clientToken
1119
1218
  print("Setting clientToken header: \(token ?? "None")")
1120
- request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
1219
+ uRLRequest.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
1121
1220
 
1122
1221
  if let apiKey = EnvironmentConfig.apiKey {
1123
- request.addValue(apiKey, forHTTPHeaderField: "X-Api-Key")
1222
+ uRLRequest.addValue(apiKey, forHTTPHeaderField: "X-Api-Key")
1124
1223
  }
1125
1224
  if let apiSecret = EnvironmentConfig.apiSecret {
1126
- request.addValue(apiSecret, forHTTPHeaderField: "X-Api-Secret")
1225
+ uRLRequest.addValue(apiSecret, forHTTPHeaderField: "X-Api-Secret")
1127
1226
  }
1128
1227
 
1129
- let params: [String: Any] = [
1228
+ var params: [String: Any] = [
1130
1229
  "account_id": self.grailPayAccountID ?? "",
1131
1230
  "account_type": self.selectedGrailPayAccountType ?? "",
1132
1231
  "name": self.selectedGrailPayAccountName ?? "",
1133
- "description": "payment checkout",
1232
+ // "description": "payment checkout",
1134
1233
  "save_account": 1,
1135
1234
  "is_default": 1,
1136
- "customer_id": customerId ?? ""
1235
+ "customer_id": customerId ?? "",
1236
+ "email": UserStoreSingleton.shared.merchantEmail ?? ""
1137
1237
  ]
1138
1238
 
1239
+ // Billing Info
1240
+ if let visibility = visibility, visibility.billing == true,
1241
+ let billing = billingInfo, !billing.isEmpty {
1242
+ var billingDict: [String: Any] = [:]
1243
+ billing.forEach { billingDict[$0.name] = $0.value }
1244
+
1245
+ params["address"] = billingDict["address"] as? String ?? ""
1246
+ params["country"] = billingDict["country"] as? String ?? ""
1247
+ params["state"] = billingDict["state"] as? String ?? ""
1248
+ params["city"] = billingDict["city"] as? String ?? ""
1249
+ params["zip"] = billingDict["postal_code"] as? String ?? ""
1250
+ }
1251
+
1252
+ // Additional Info or default description
1253
+ var descriptionValue: String = "Hosted payment checkout" // default
1254
+ if let visibility = visibility, visibility.additional == true,
1255
+ let additional = additionalInfo, !additional.isEmpty {
1256
+
1257
+ var additionalDict: [String: Any] = [:]
1258
+ additional.forEach { additionalDict[$0.name] = $0.value }
1259
+
1260
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
1261
+ descriptionValue = desc
1262
+ }
1263
+
1264
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
1265
+ params["phone_number"] = phone
1266
+ }
1267
+ }
1268
+ params["description"] = descriptionValue
1269
+
1270
+ // Add these if recurring is enabled
1271
+ if let req = request, req.is_recurring == true {
1272
+ if let recurringType = req.recurringStartDateType, recurringType == .custom {
1273
+ // Only send start_date if type is .custom and field is not empty
1274
+ if let startDateText = startDate, !startDateText.isEmpty {
1275
+ let inputFormatter = DateFormatter()
1276
+ inputFormatter.dateFormat = "dd/MM/yyyy"
1277
+
1278
+ let outputFormatter = DateFormatter()
1279
+ outputFormatter.dateFormat = "MM/dd/yyyy"
1280
+
1281
+ if let date = inputFormatter.date(from: startDateText) {
1282
+ let apiFormattedDate = outputFormatter.string(from: date)
1283
+ params["start_date"] = apiFormattedDate
1284
+ } else {
1285
+ print("Invalid date format in startDateText")
1286
+ }
1287
+ }
1288
+ }
1289
+
1290
+ params["interval"] = chosenPlan?.lowercased()
1291
+ }
1292
+
1139
1293
  print(params)
1140
1294
 
1141
1295
  do {
1142
1296
  let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
1143
- request.httpBody = jsonData
1297
+ uRLRequest.httpBody = jsonData
1144
1298
  if let jsonString = String(data: jsonData, encoding: .utf8) {
1145
1299
  print("JSON Payload: \(jsonString)")
1146
1300
  }
@@ -1151,7 +1305,7 @@ class OTPVerificationVC: BaseVC {
1151
1305
  }
1152
1306
 
1153
1307
  let session = URLSession.shared
1154
- let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
1308
+ let task = session.dataTask(with: uRLRequest) { (serviceData, serviceResponse, error) in
1155
1309
 
1156
1310
  DispatchQueue.main.async {
1157
1311
  self.hideLoadingIndicator() // Stop loader when response is received
@@ -1183,6 +1337,23 @@ class OTPVerificationVC: BaseVC {
1183
1337
  paymentDoneVC.chargeData = responseObject
1184
1338
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
1185
1339
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
1340
+ // Pass billing and additional info
1341
+ // Conditionally pass raw FieldItem array
1342
+ paymentDoneVC.visibility = self.visibility
1343
+
1344
+ if self.visibility?.billing == true {
1345
+ paymentDoneVC.billingInfoData = self.billingInfo
1346
+ var billingDict: [String: Any] = [:]
1347
+ self.billingInfo?.forEach { billingDict[$0.name] = $0.value }
1348
+ paymentDoneVC.billingInfo = billingDict
1349
+ }
1350
+
1351
+ if self.visibility?.additional == true {
1352
+ paymentDoneVC.additionalInfoData = self.additionalInfo
1353
+ var additionalDict: [String: Any] = [:]
1354
+ self.additionalInfo?.forEach { additionalDict[$0.name] = $0.value }
1355
+ paymentDoneVC.additionalInfo = additionalDict
1356
+ }
1186
1357
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
1187
1358
  }
1188
1359
  }
@@ -1379,28 +1550,6 @@ class OTPVerificationVC: BaseVC {
1379
1550
  uRLRequest.addValue(apiSecret, forHTTPHeaderField: "x-api-secret")
1380
1551
  }
1381
1552
 
1382
- guard let billingInfoData = billingInfoData else {
1383
- print("Billing info data is nil")
1384
- return
1385
- }
1386
-
1387
- let additionalInfoFromBilling = billingInfoData["additional_info"] as? [String: Any] ?? [:]
1388
-
1389
- let additionalInfo: [String: Any] = [
1390
- "name": additionalInfoFromBilling["name"] as? String ?? "",
1391
- "email": additionalInfoFromBilling["email"] as? String ?? "",
1392
- "phone_number": additionalInfoFromBilling["phone_number"] as? String ?? "",
1393
- "description": additionalInfoFromBilling["description"] as? String ?? ""
1394
- ]
1395
-
1396
- let billingInfo: [String: Any] = [
1397
- "address": billingInfoData["address"] as? String ?? "",
1398
- "country": billingInfoData["country"] as? String ?? "",
1399
- "state": billingInfoData["state"] as? String ?? "",
1400
- "city": billingInfoData["city"] as? String ?? "",
1401
- "postal_code": billingInfoData["postal_code"] as? String ?? ""
1402
- ]
1403
-
1404
1553
  var params: [String: Any] = [
1405
1554
  "name": nameOnCard ?? "",
1406
1555
  "email": email ?? "",
@@ -1409,17 +1558,44 @@ class OTPVerificationVC: BaseVC {
1409
1558
  "exp_month": expiryDate?.components(separatedBy: "/").first ?? "",
1410
1559
  "exp_year": expiryDate?.components(separatedBy: "/").last ?? "",
1411
1560
  "cvc": cvv ?? "",
1412
- "description": "Test",
1413
1561
  "currency": "usd",
1414
1562
  "tokenize": request.tokenOnly ?? false,
1415
- "address": billingInfoData["address"] as? String ?? "",
1416
- "billing_info": billingInfo,
1417
- "additional_info": additionalInfo,
1418
1563
  "save_card": "1",
1419
1564
  "is_default": "1",
1420
1565
  "customer_id": customerId ?? ""
1421
1566
  ]
1422
1567
 
1568
+ // Billing Info
1569
+ if let visibility = visibility, visibility.billing == true,
1570
+ let billing = billingInfo, !billing.isEmpty {
1571
+ var billingDict: [String: Any] = [:]
1572
+ billing.forEach { billingDict[$0.name] = $0.value }
1573
+
1574
+ params["address"] = billingDict["address"] as? String ?? ""
1575
+ params["country"] = billingDict["country"] as? String ?? ""
1576
+ params["state"] = billingDict["state"] as? String ?? ""
1577
+ params["city"] = billingDict["city"] as? String ?? ""
1578
+ params["zip"] = billingDict["postal_code"] as? String ?? ""
1579
+ }
1580
+
1581
+ // Additional Info or default description
1582
+ var descriptionValue: String = "Hosted payment checkout" // default
1583
+ if let visibility = visibility, visibility.additional == true,
1584
+ let additional = additionalInfo, !additional.isEmpty {
1585
+
1586
+ var additionalDict: [String: Any] = [:]
1587
+ additional.forEach { additionalDict[$0.name] = $0.value }
1588
+
1589
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
1590
+ descriptionValue = desc
1591
+ }
1592
+
1593
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
1594
+ params["phone_number"] = phone
1595
+ }
1596
+ }
1597
+ params["description"] = descriptionValue
1598
+
1423
1599
  // Add these if recurring is enabled
1424
1600
  if let req = request, req.is_recurring == true {
1425
1601
  if let recurringType = req.recurringStartDateType, recurringType == .custom {
@@ -1491,8 +1667,22 @@ class OTPVerificationVC: BaseVC {
1491
1667
  paymentDoneVC.chargeData = responseObject
1492
1668
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
1493
1669
  // Pass billing and additional info
1494
- paymentDoneVC.billingInfo = billingInfo
1495
- paymentDoneVC.additionalInfo = additionalInfo
1670
+ // Conditionally pass raw FieldItem array
1671
+ paymentDoneVC.visibility = self.visibility
1672
+
1673
+ if self.visibility?.billing == true {
1674
+ paymentDoneVC.billingInfoData = self.billingInfo
1675
+ var billingDict: [String: Any] = [:]
1676
+ self.billingInfo?.forEach { billingDict[$0.name] = $0.value }
1677
+ paymentDoneVC.billingInfo = billingDict
1678
+ }
1679
+
1680
+ if self.visibility?.additional == true {
1681
+ paymentDoneVC.additionalInfoData = self.additionalInfo
1682
+ var additionalDict: [String: Any] = [:]
1683
+ self.additionalInfo?.forEach { additionalDict[$0.name] = $0.value }
1684
+ paymentDoneVC.additionalInfo = additionalDict
1685
+ }
1496
1686
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
1497
1687
  }
1498
1688
  }
@@ -19,7 +19,7 @@ class PaymentDoneVC: UIViewController {
19
19
  @IBOutlet weak var lblHeadingDate: UILabel!
20
20
  @IBOutlet weak var lblHeadingTransactionID: UILabel!
21
21
  @IBOutlet weak var lbHeadingPaymentMethod: UILabel!
22
- @IBOutlet weak var lblHeadingTotal: UILabel!
22
+ @IBOutlet weak var lblHeadingTotal: UILabel!
23
23
 
24
24
  @IBOutlet weak var viewSubscriptionId: UIStackView!
25
25
  @IBOutlet weak var lblHeadingSubscriptionId: UILabel!
@@ -40,6 +40,10 @@ class PaymentDoneVC: UIViewController {
40
40
  var billingInfo: [String: Any]?
41
41
  var additionalInfo: [String: Any]?
42
42
 
43
+ var additionalInfoData: [FieldItem]?
44
+ var billingInfoData: [FieldItem]?
45
+ var visibility: FieldsVisibility?
46
+
43
47
  override func viewDidLoad() {
44
48
  super.viewDidLoad()
45
49
 
@@ -83,7 +87,7 @@ class PaymentDoneVC: UIViewController {
83
87
  showDateAndTime()
84
88
  }
85
89
 
86
- showBillingInfo()
90
+ // showBillingInfo()
87
91
  }
88
92
 
89
93
  override func viewWillAppear(_ animated: Bool) {
@@ -150,30 +154,35 @@ class PaymentDoneVC: UIViewController {
150
154
 
151
155
  }
152
156
 
153
- func showBillingInfo() {
154
- var displayText = ""
155
-
156
- if let billing = billingInfo {
157
- displayText += "Billing Info:\n"
158
- for (key, value) in billing {
159
- displayText += "\(key.capitalized): \(value)\n"
160
- }
161
-
162
- if let additional = additionalInfo {
163
- displayText += "\nAdditional Info:\n"
164
- for (key, value) in additional {
165
- displayText += "\(key.capitalized): \(value)\n"
166
- }
167
- }
168
-
169
- // Set text and make label visible
170
- lblBillingInfo.text = displayText.trimmingCharacters(in: .whitespacesAndNewlines)
171
- lblBillingInfo.isHidden = false
172
- } else {
173
- // Hide label if billing info is not available
174
- lblBillingInfo.isHidden = true
175
- }
176
- }
157
+ // func showBillingInfo() {
158
+ // var displayText = ""
159
+ //
160
+ // if let visibility = visibility {
161
+ // if visibility.billing, let billing = billingInfo {
162
+ // displayText += "Billing Info:-\n"
163
+ // for (key, value) in billing {
164
+ // displayText += "\(key.capitalized): \(value)\n"
165
+ // }
166
+ // }
167
+ //
168
+ // if visibility.additional, let additional = additionalInfo {
169
+ // if !displayText.isEmpty {
170
+ // displayText += "\n"
171
+ // }
172
+ // displayText += "Additional Info:-\n"
173
+ // for (key, value) in additional {
174
+ // displayText += "\(key.capitalized): \(value)\n"
175
+ // }
176
+ // }
177
+ // }
178
+ //
179
+ // if displayText.isEmpty {
180
+ // lblBillingInfo.isHidden = true
181
+ // } else {
182
+ // lblBillingInfo.text = displayText.trimmingCharacters(in: .whitespacesAndNewlines)
183
+ // lblBillingInfo.isHidden = false
184
+ // }
185
+ // }
177
186
 
178
187
  // Helper method to check if the date string is valid
179
188
  func isValidDate(_ dateString: String) -> Bool {