@jimrising/easymerchantsdk-react-native 1.4.5 → 1.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,7 +7,7 @@ To add the path of sdk in your project. Open your `package.json` file and inside
7
7
 
8
8
  ```json
9
9
  "dependencies": {
10
- "@jimrising/easymerchantsdk-react-native": "^1.4.5"
10
+ "@jimrising/easymerchantsdk-react-native": "^1.4.6"
11
11
  },
12
12
  ```
13
13
 
@@ -137,8 +137,8 @@ const App = () => {
137
137
  await EasyMerchantSdk.setViewController();
138
138
  await EasyMerchantSdk.configureEnvironment(
139
139
  'staging',
140
- 'mobilesdk1980IUuCzwWl',
141
- 'mobilesdk1980LVHnN0Oh'
140
+ 'c4dd6319f905ee4d17f202e3d',
141
+ '615e339659f2657ae01452561'
142
142
  );
143
143
  }
144
144
  } catch (err) {
@@ -167,11 +167,11 @@ const App = () => {
167
167
  const billingInfo = {
168
168
  visibility: { billing: false, additional: false },
169
169
  billing: {
170
- address: 'Mohali, Punjab',
171
- country: 'India',
172
- state: 'Punjab',
173
- city: 'Anandpur Sahib',
174
- postal_code: '140118',
170
+ address: 'San Fran, Punjab',
171
+ country: 'USA',
172
+ state: 'California',
173
+ city: 'Paris',
174
+ postal_code: '234234',
175
175
  },
176
176
  billingRequired: {
177
177
  address: true,
@@ -183,7 +183,7 @@ const App = () => {
183
183
  additional: {
184
184
  name: 'Test User',
185
185
  email_address: 'test@gmail.com',
186
- phone_number: '9465351125',
186
+ phone_number: '21408713290',
187
187
  description: 'Test',
188
188
  },
189
189
  additionalRequired: {
@@ -212,8 +212,8 @@ const App = () => {
212
212
  };
213
213
 
214
214
  const authConfig = {
215
- accessToken: '251|uTijpDGfrS88UR2V1cZNMQ8S4hUJA0sVzsnsoUZF',
216
- vendorId: '251',
215
+ // accessToken: '251|uTijpDGfrS88UR2V1cZNMQ8S4hUJA0sVzsnsoUZF',
216
+ // vendorId: '251',
217
217
  role: 'business',
218
218
  timeout: 10,
219
219
  isSandbox: true,
@@ -246,7 +246,9 @@ const authConfig = {
246
246
  true, // secureAuthentication
247
247
  true, // showReceipt
248
248
  true, // showTotal
249
- true // showSubmitButton
249
+ true,// showSubmitButton
250
+ "davindersingh@gmail.com",
251
+ "Davinder Singh"
250
252
  );
251
253
 
252
254
  console.log('Billing success (full response):', JSON.stringify(result, null, 2));
@@ -355,7 +357,6 @@ const styles = StyleSheet.create({
355
357
  },
356
358
  });
357
359
 
358
-
359
360
  ```
360
361
 
361
362
  You can send `null` if billing info not available.
@@ -48,6 +48,8 @@ RCT_EXPORT_METHOD(
48
48
  showReceipt:(BOOL)showReceipt
49
49
  showTotal:(BOOL)showTotal
50
50
  showSubmitButton:(BOOL)showSubmitButton
51
+ email:(NSString *)email
52
+ name:(NSString *)name
51
53
  resolver:(RCTPromiseResolveBlock)resolve
52
54
  rejecter:(RCTPromiseRejectBlock)reject
53
55
  )
@@ -76,6 +78,8 @@ RCT_EXPORT_METHOD(
76
78
  showReceipt:showReceipt
77
79
  showTotal:showTotal
78
80
  showSubmitButton:showSubmitButton
81
+ email:email
82
+ name:name
79
83
  enable3DS:secureAuthentication
80
84
  resolver:^(id result) {
81
85
  resolve(result);
@@ -77,6 +77,8 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
77
77
  showReceipt: Bool,
78
78
  showTotal: Bool,
79
79
  showSubmitButton: Bool,
80
+ email: String?,
81
+ name: String?,
80
82
  enable3DS: Bool,
81
83
  resolver: @escaping RCTPromiseResolveBlock,
82
84
  rejecter: @escaping RCTPromiseRejectBlock
@@ -152,8 +154,8 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
152
154
  var grailParams: GrailPayRequest? = nil
153
155
  if authenticatedACH, let params = grailPayParams {
154
156
  grailParams = GrailPayRequest(
155
- accessToken: params["accessToken"] as? String ?? "251|uTijpDGfrS88UR2V1cZNMQ8S4hUJA0sVzsnsoUZF",
156
- vendorId: params["vendorId"] as? String ?? "251",
157
+ // accessToken: params["accessToken"] as? String ?? "251|uTijpDGfrS88UR2V1cZNMQ8S4hUJA0sVzsnsoUZF",
158
+ // vendorId: params["vendorId"] as? String ?? "251",
157
159
  role: params["role"] as? String ?? "business",
158
160
  timeout: params["timeout"] as? Int ?? 10,
159
161
  isSandbox: params["isSandbox"] as? Bool ?? true,
@@ -224,8 +226,11 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
224
226
  showReceipt: showReceipt,
225
227
  showTotal: showTotal,
226
228
  showSubmitButton: showSubmitButton,
229
+
227
230
  referenceID: enable3DS,
228
- referenceToken: nil
231
+ referenceToken: nil,
232
+ email:email,
233
+ name: name
229
234
  )
230
235
 
231
236
  // Store resolvers
@@ -57,8 +57,8 @@ public struct ThemeConfiguration: Codable {
57
57
  }
58
58
 
59
59
  public struct GrailPayRequest: Codable {
60
- public let accessToken: String
61
- public let vendorId: String
60
+ // public let accessToken: String
61
+ // public let vendorId: String
62
62
  public let role: String
63
63
  public let timeout: Int
64
64
  public let isSandbox: Bool
@@ -67,8 +67,8 @@ public struct GrailPayRequest: Codable {
67
67
  public let searchPlaceholder: String
68
68
 
69
69
  public init(
70
- accessToken: String,
71
- vendorId: String,
70
+ // accessToken: String,
71
+ // vendorId: String,
72
72
  role: String,
73
73
  timeout: Int,
74
74
  isSandbox: Bool,
@@ -76,8 +76,8 @@ public struct GrailPayRequest: Codable {
76
76
  finderSubtitle: String,
77
77
  searchPlaceholder: String
78
78
  ) {
79
- self.accessToken = accessToken
80
- self.vendorId = vendorId
79
+ // self.accessToken = accessToken
80
+ // self.vendorId = vendorId
81
81
  self.role = role
82
82
  self.timeout = timeout
83
83
  self.isSandbox = isSandbox
@@ -168,6 +168,8 @@ public final class Request: NSObject {
168
168
  public let showSubmitButton: Bool?
169
169
  public let referenceID: Bool?
170
170
  public let referenceToken: String?
171
+ public let email: String?
172
+ public let name: String?
171
173
 
172
174
  public init(
173
175
  amount: Double? = nil,
@@ -191,7 +193,9 @@ public final class Request: NSObject {
191
193
  showTotal: Bool = false,
192
194
  showSubmitButton: Bool = false,
193
195
  referenceID: Bool = false,
194
- referenceToken: String? = nil
196
+ referenceToken: String? = nil,
197
+ email: String? = nil,
198
+ name: String? = nil
195
199
  ) {
196
200
  // Validate if amount is provided, must be ≥ 0.50
197
201
  if let amt = amount, amt < 0.50 {
@@ -234,6 +238,8 @@ public final class Request: NSObject {
234
238
  self.showSubmitButton = showSubmitButton
235
239
  self.referenceID = referenceID
236
240
  self.referenceToken = referenceToken
241
+ self.email = email
242
+ self.name = name
237
243
 
238
244
  // Conditionally assign recurring fields only if is_recurring == true
239
245
  if is_recurring {
@@ -334,7 +340,7 @@ public final class Request: NSObject {
334
340
 
335
341
  let params: [String: Any] = [
336
342
  "amount": amount ?? 0,
337
- // "allowed_cycles": String(recurringIntervals?.count ?? 0),
343
+ // "allowed_cycles": String(recurringIntervals?.count ?? 0),
338
344
  "allowed_cycles": numOfCycle ?? 0,
339
345
  "intervals": recurringIntervals?.map { $0.rawValue } ?? [],
340
346
  "is_recurring": self.is_recurring ?? false,
@@ -468,6 +474,23 @@ public final class Request: NSObject {
468
474
  print("Saved merchantName: \(merchantName)")
469
475
  }
470
476
 
477
+ if let companyName = dataObject["company_name"] as? String {
478
+ UserStoreSingleton.shared.companyName = companyName
479
+ print("Saved company name: \(companyName)")
480
+ }
481
+
482
+ if let bankWidgetKey = dataObject["bank_widget_key"] as? String {
483
+ UserStoreSingleton.shared.bankWidgetKey = bankWidgetKey
484
+ print("Saved bank_widget_key: \(bankWidgetKey)")
485
+
486
+ // Extract vendor ID from bankWidgetKey
487
+ let components = bankWidgetKey.components(separatedBy: "|")
488
+ if let vendorID = components.first {
489
+ UserStoreSingleton.shared.vendorID = vendorID
490
+ print("Extracted and saved vendor_id: \(vendorID)")
491
+ }
492
+ }
493
+
471
494
  // Save payment methods (crypto payment account)
472
495
  if let paymentMethods = dataObject["payment_methods"] as? [String: Any],
473
496
  let cryptoSection = paymentMethods["crypto"] as? [String: Any],
@@ -110,6 +110,33 @@ class UserStoreSingleton: NSObject {
110
110
  }
111
111
  }
112
112
 
113
+ var companyName: String? {
114
+ get {
115
+ return UserDefaults.standard.string(forKey: "companyName")
116
+ }
117
+ set {
118
+ UserDefaults.standard.set(newValue, forKey: "companyName")
119
+ }
120
+ }
121
+
122
+ var bankWidgetKey: String? {
123
+ get {
124
+ return UserDefaults.standard.string(forKey: "bank_widget_key")
125
+ }
126
+ set {
127
+ UserDefaults.standard.set(newValue, forKey: "bank_widget_key")
128
+ }
129
+ }
130
+
131
+ var vendorID: String? {
132
+ get {
133
+ return UserDefaults.standard.string(forKey: "vendor_id")
134
+ }
135
+ set {
136
+ UserDefaults.standard.set(newValue, forKey: "vendor_id")
137
+ }
138
+ }
139
+
113
140
  //apperance_settings
114
141
  var body_bg_col : String? {
115
142
  get {
@@ -212,22 +239,21 @@ class UserStoreSingleton: NSObject {
212
239
  // UserDefaults.standard.set(value, forKey: key)
213
240
  // }
214
241
  // }
215
-
216
-
242
+
217
243
  func updateThemeConfiguration(with themeConfiguration: ThemeConfiguration) {
218
- self.body_bg_col = themeConfiguration.bodyBackgroundColor
219
- self.container_bg_col = themeConfiguration.containerBackgroundColor
220
- self.primary_font_col = themeConfiguration.primaryFontColor
221
- self.secondary_font_col = themeConfiguration.secondaryFontColor
222
- self.primary_btn_bg_col = themeConfiguration.primaryButtonBackgroundColor
223
- self.primary_btn_hover_col = themeConfiguration.primaryButtonHoverColor
224
- self.primary_btn_font_col = themeConfiguration.primaryButtonFontColor
225
- self.secondary_btn_bg_col = themeConfiguration.secondaryButtonBackgroundColor
226
- self.secondary_btn_hover_col = themeConfiguration.secondaryButtonHoverColor
227
- self.secondary_btn_font_col = themeConfiguration.secondaryFontColor
228
- self.border_radious = themeConfiguration.borderRadius
229
- self.fontSize = themeConfiguration.fontSize
230
- }
244
+ self.body_bg_col = themeConfiguration.bodyBackgroundColor
245
+ self.container_bg_col = themeConfiguration.containerBackgroundColor
246
+ self.primary_font_col = themeConfiguration.primaryFontColor
247
+ self.secondary_font_col = themeConfiguration.secondaryFontColor
248
+ self.primary_btn_bg_col = themeConfiguration.primaryButtonBackgroundColor
249
+ self.primary_btn_hover_col = themeConfiguration.primaryButtonHoverColor
250
+ self.primary_btn_font_col = themeConfiguration.primaryButtonFontColor
251
+ self.secondary_btn_bg_col = themeConfiguration.secondaryButtonBackgroundColor
252
+ self.secondary_btn_hover_col = themeConfiguration.secondaryButtonHoverColor
253
+ self.secondary_btn_font_col = themeConfiguration.secondaryFontColor
254
+ self.border_radious = themeConfiguration.borderRadius
255
+ self.fontSize = themeConfiguration.fontSize
256
+ }
231
257
 
232
258
  // Method to clear user data from UserDefaults
233
259
  func clearUserData() {
@@ -90,8 +90,8 @@ public class GrailPayVC: UIViewController {
90
90
  }
91
91
 
92
92
  window.grailpay.init({
93
- token: '\(request.accessToken)',
94
- vendorId: '\(request.vendorId)',
93
+ token: '\(UserStoreSingleton.shared.bankWidgetKey ?? "")',
94
+ vendorId: '\(UserStoreSingleton.shared.vendorID ?? "")',
95
95
  role: '\(request.role)',
96
96
  timeout: \(request.timeout),
97
97
  theme: {
@@ -570,36 +570,67 @@ class OTPVerificationVC: BaseVC {
570
570
  // params["email"] = userEmail ?? ""
571
571
  // }
572
572
 
573
- // Billing Info
574
- if let visibility = visibility, visibility.billing == true,
575
- let billing = billingInfo, !billing.isEmpty {
576
- var billingDict: [String: Any] = [:]
577
- billing.forEach { billingDict[$0.name] = $0.value }
578
-
579
- params["address"] = billingDict["address"] as? String ?? ""
580
- params["country"] = billingDict["country"] as? String ?? ""
581
- params["state"] = billingDict["state"] as? String ?? ""
582
- params["city"] = billingDict["city"] as? String ?? ""
583
- params["zip"] = billingDict["postal_code"] as? String ?? ""
584
- }
585
-
586
- // Additional Info or default description
587
- var descriptionValue: String = "Hosted payment checkout" // default
588
- if let visibility = visibility, visibility.additional == true,
589
- let additional = additionalInfo, !additional.isEmpty {
590
-
591
- var additionalDict: [String: Any] = [:]
592
- additional.forEach { additionalDict[$0.name] = $0.value }
593
-
594
- if let desc = additionalDict["description"] as? String, !desc.isEmpty {
595
- descriptionValue = desc
596
- }
597
-
598
- if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
599
- params["phone_number"] = phone
573
+ if let billingInfoData = request.billingInfoData {
574
+ do {
575
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
576
+
577
+ // Billing Info
578
+ let billing = fieldSection.billing
579
+ if !billing.isEmpty {
580
+ var billingDict: [String: Any] = [:]
581
+ billing.forEach { billingDict[$0.name] = $0.value }
582
+
583
+ if let address = billingDict["address"] as? String, !address.isEmpty {
584
+ params["address"] = address
585
+ }
586
+ if let country = billingDict["country"] as? String, !country.isEmpty {
587
+ params["country"] = country
588
+ }
589
+ if let state = billingDict["state"] as? String, !state.isEmpty {
590
+ params["state"] = state
591
+ }
592
+ if let city = billingDict["city"] as? String, !city.isEmpty {
593
+ params["city"] = city
594
+ }
595
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
596
+ params["zip"] = postalCode
597
+ }
598
+ }
599
+
600
+ // Additional Info
601
+ let additional = fieldSection.additional
602
+ if !additional.isEmpty {
603
+ var additionalDict: [String: Any] = [:]
604
+ additional.forEach { additionalDict[$0.name] = $0.value }
605
+
606
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
607
+ params["description"] = desc
608
+ } else {
609
+ params["description"] = "Hosted payment checkout"
610
+ }
611
+
612
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
613
+ params["phone_number"] = phone
614
+ }
615
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
616
+ params["email"] = email
617
+ }
618
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
619
+ params["name"] = name
620
+ }
621
+ } else {
622
+ // If no description in additional info, set default
623
+ params["description"] = "Hosted payment checkout"
624
+ }
625
+
626
+ } catch {
627
+ print("Failed to decode FieldSection: \(error)")
628
+ params["description"] = "Hosted payment checkout"
600
629
  }
630
+ } else {
631
+ // Fallback if billingInfoData is missing
632
+ params["description"] = "Hosted payment checkout"
601
633
  }
602
- params["description"] = descriptionValue
603
634
 
604
635
  // Add these if recurring is enabled
605
636
  if let req = request, req.is_recurring == true {
@@ -671,21 +702,22 @@ class OTPVerificationVC: BaseVC {
671
702
  paymentDoneVC.chargeData = responseObject
672
703
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
673
704
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
674
- // Pass billing and additional info
675
- // Conditionally pass raw FieldItem array
676
- paymentDoneVC.visibility = self.visibility
677
-
678
- if self.visibility?.billing == true {
679
- paymentDoneVC.billingInfoData = self.billingInfo
705
+ // Pass billing info and additional info if available
706
+ if let billingInfoData = self.request.billingInfoData,
707
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
708
+
709
+ // Filter billing info: only include non-empty values
710
+ let filteredBilling = fieldSection.billing.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
711
+ paymentDoneVC.billingInfoData = filteredBilling
680
712
  var billingDict: [String: Any] = [:]
681
- self.billingInfo?.forEach { billingDict[$0.name] = $0.value }
713
+ filteredBilling.forEach { billingDict[$0.name] = $0.value }
682
714
  paymentDoneVC.billingInfo = billingDict
683
- }
684
-
685
- if self.visibility?.additional == true {
686
- paymentDoneVC.additionalInfoData = self.additionalInfo
715
+
716
+ // Filter additional info: only include non-empty values
717
+ let filteredAdditional = fieldSection.additional.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
718
+ paymentDoneVC.additionalInfoData = filteredAdditional
687
719
  var additionalDict: [String: Any] = [:]
688
- self.additionalInfo?.forEach { additionalDict[$0.name] = $0.value }
720
+ filteredAdditional.forEach { additionalDict[$0.name] = $0.value }
689
721
  paymentDoneVC.additionalInfo = additionalDict
690
722
  }
691
723
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
@@ -920,36 +952,67 @@ class OTPVerificationVC: BaseVC {
920
952
  params["username"] = emailPrefix
921
953
  }
922
954
 
923
- // Billing Info
924
- if let visibility = visibility, visibility.billing == true,
925
- let billing = billingInfo, !billing.isEmpty {
926
- var billingDict: [String: Any] = [:]
927
- billing.forEach { billingDict[$0.name] = $0.value }
928
-
929
- params["address"] = billingDict["address"] as? String ?? ""
930
- params["country"] = billingDict["country"] as? String ?? ""
931
- params["state"] = billingDict["state"] as? String ?? ""
932
- params["city"] = billingDict["city"] as? String ?? ""
933
- params["zip"] = billingDict["postal_code"] as? String ?? ""
934
- }
935
-
936
- // Additional Info or default description
937
- var descriptionValue: String = "Hosted payment checkout" // default
938
- if let visibility = visibility, visibility.additional == true,
939
- let additional = additionalInfo, !additional.isEmpty {
940
-
941
- var additionalDict: [String: Any] = [:]
942
- additional.forEach { additionalDict[$0.name] = $0.value }
943
-
944
- if let desc = additionalDict["description"] as? String, !desc.isEmpty {
945
- descriptionValue = desc
946
- }
947
-
948
- if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
949
- params["phone_number"] = phone
955
+ if let billingInfoData = request.billingInfoData {
956
+ do {
957
+ let fieldSection = try JSONDecoder().decode(FieldSection.self, from: billingInfoData)
958
+
959
+ // Billing Info
960
+ let billing = fieldSection.billing
961
+ if !billing.isEmpty {
962
+ var billingDict: [String: Any] = [:]
963
+ billing.forEach { billingDict[$0.name] = $0.value }
964
+
965
+ if let address = billingDict["address"] as? String, !address.isEmpty {
966
+ params["address"] = address
967
+ }
968
+ if let country = billingDict["country"] as? String, !country.isEmpty {
969
+ params["country"] = country
970
+ }
971
+ if let state = billingDict["state"] as? String, !state.isEmpty {
972
+ params["state"] = state
973
+ }
974
+ if let city = billingDict["city"] as? String, !city.isEmpty {
975
+ params["city"] = city
976
+ }
977
+ if let postalCode = billingDict["postal_code"] as? String, !postalCode.isEmpty {
978
+ params["zip"] = postalCode
979
+ }
980
+ }
981
+
982
+ // Additional Info
983
+ let additional = fieldSection.additional
984
+ if !additional.isEmpty {
985
+ var additionalDict: [String: Any] = [:]
986
+ additional.forEach { additionalDict[$0.name] = $0.value }
987
+
988
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
989
+ params["description"] = desc
990
+ } else {
991
+ params["description"] = "Hosted payment checkout"
992
+ }
993
+
994
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
995
+ params["phone_number"] = phone
996
+ }
997
+ if let email = additionalDict["email"] as? String, !email.isEmpty {
998
+ params["email"] = email
999
+ }
1000
+ if let name = additionalDict["name"] as? String, !name.isEmpty {
1001
+ params["name"] = name
1002
+ }
1003
+ } else {
1004
+ // If no description in additional info, set default
1005
+ params["description"] = "Hosted payment checkout"
1006
+ }
1007
+
1008
+ } catch {
1009
+ print("Failed to decode FieldSection: \(error)")
1010
+ params["description"] = "Hosted payment checkout"
950
1011
  }
1012
+ } else {
1013
+ // Fallback if billingInfoData is missing
1014
+ params["description"] = "Hosted payment checkout"
951
1015
  }
952
- params["description"] = descriptionValue
953
1016
 
954
1017
  // Add these if recurring is enabled
955
1018
  if let req = request, req.is_recurring == true {
@@ -1021,21 +1084,22 @@ class OTPVerificationVC: BaseVC {
1021
1084
  paymentDoneVC.chargeData = responseObject
1022
1085
  paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
1023
1086
  paymentDoneVC.easyPayDelegate = self.easyPayDelegate
1024
- // Pass billing and additional info
1025
- // Conditionally pass raw FieldItem array
1026
- paymentDoneVC.visibility = self.visibility
1027
-
1028
- if self.visibility?.billing == true {
1029
- paymentDoneVC.billingInfoData = self.billingInfo
1087
+ // Pass billing info and additional info if available
1088
+ if let billingInfoData = self.request.billingInfoData,
1089
+ let fieldSection = try? JSONDecoder().decode(FieldSection.self, from: billingInfoData) {
1090
+
1091
+ // Filter billing info: only include non-empty values
1092
+ let filteredBilling = fieldSection.billing.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
1093
+ paymentDoneVC.billingInfoData = filteredBilling
1030
1094
  var billingDict: [String: Any] = [:]
1031
- self.billingInfo?.forEach { billingDict[$0.name] = $0.value }
1095
+ filteredBilling.forEach { billingDict[$0.name] = $0.value }
1032
1096
  paymentDoneVC.billingInfo = billingDict
1033
- }
1034
-
1035
- if self.visibility?.additional == true {
1036
- paymentDoneVC.additionalInfoData = self.additionalInfo
1097
+
1098
+ // Filter additional info: only include non-empty values
1099
+ let filteredAdditional = fieldSection.additional.filter { !($0.value.trimmingCharacters(in: .whitespaces).isEmpty) }
1100
+ paymentDoneVC.additionalInfoData = filteredAdditional
1037
1101
  var additionalDict: [String: Any] = [:]
1038
- self.additionalInfo?.forEach { additionalDict[$0.name] = $0.value }
1102
+ filteredAdditional.forEach { additionalDict[$0.name] = $0.value }
1039
1103
  paymentDoneVC.additionalInfo = additionalDict
1040
1104
  }
1041
1105
  self.navigationController?.pushViewController(paymentDoneVC, animated: true)
@@ -1613,37 +1677,6 @@ class OTPVerificationVC: BaseVC {
1613
1677
  "customer_id": customerId ?? ""
1614
1678
  ]
1615
1679
 
1616
- // // Billing Info
1617
- // if let visibility = visibility, visibility.billing == true,
1618
- // let billing = billingInfo, !billing.isEmpty {
1619
- // var billingDict: [String: Any] = [:]
1620
- // billing.forEach { billingDict[$0.name] = $0.value }
1621
- //
1622
- // params["address"] = billingDict["address"] as? String ?? ""
1623
- // params["country"] = billingDict["country"] as? String ?? ""
1624
- // params["state"] = billingDict["state"] as? String ?? ""
1625
- // params["city"] = billingDict["city"] as? String ?? ""
1626
- // params["zip"] = billingDict["postal_code"] as? String ?? ""
1627
- // }
1628
- //
1629
- // // Additional Info or default description
1630
- // var descriptionValue: String = "Hosted payment checkout" // default
1631
- // if let visibility = visibility, visibility.additional == true,
1632
- // let additional = additionalInfo, !additional.isEmpty {
1633
- //
1634
- // var additionalDict: [String: Any] = [:]
1635
- // additional.forEach { additionalDict[$0.name] = $0.value }
1636
- //
1637
- // if let desc = additionalDict["description"] as? String, !desc.isEmpty {
1638
- // descriptionValue = desc
1639
- // }
1640
- //
1641
- // if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
1642
- // params["phone_number"] = phone
1643
- // }
1644
- // }
1645
- // params["description"] = descriptionValue
1646
-
1647
1680
  // Always include Billing Info if available
1648
1681
  if let billing = billingInfo, !billing.isEmpty {
1649
1682
  var billingDict: [String: Any] = [:]