@jimrising/easymerchantsdk-react-native 1.2.0 → 1.2.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 (26) hide show
  1. package/.idea/caches/deviceStreaming.xml +209 -0
  2. package/.idea/workspace.xml +193 -0
  3. package/README.md +1 -1
  4. package/ios/Classes/EasyMerchantSdk.m +4 -4
  5. package/ios/Pods/UserDefaults/UserStoreSingleton.swift +233 -0
  6. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +1137 -0
  7. package/ios/Pods/ViewControllers/BaseVC.swift +126 -0
  8. package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +803 -0
  9. package/ios/Pods/ViewControllers/BillingInfoVC/Cells/CityListTVC.swift +46 -0
  10. package/ios/Pods/ViewControllers/BillingInfoVC/Cells/CountryListTVC.swift +47 -0
  11. package/ios/Pods/ViewControllers/BillingInfoVC/Cells/StateListTVC.swift +46 -0
  12. package/ios/Pods/ViewControllers/CountryListVC.swift +404 -0
  13. package/ios/Pods/ViewControllers/EmailVerificationVC.swift +239 -0
  14. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +1134 -0
  15. package/ios/Pods/ViewControllers/PaymentDoneVC.swift +159 -0
  16. package/ios/Pods/ViewControllers/PaymentErrorVC.swift +90 -0
  17. package/ios/Pods/ViewControllers/PaymentInformation/AccountTypeTVC.swift +41 -0
  18. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +5160 -0
  19. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInformationCVC.swift +35 -0
  20. package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.swift +77 -0
  21. package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.xib +163 -0
  22. package/ios/Pods/ViewControllers/PaymentInformation/SavedCardsTVC/SavedCardsTVC.swift +76 -0
  23. package/ios/Pods/ViewControllers/PaymentInformation/SavedCardsTVC/SavedCardsTVC.xib +184 -0
  24. package/ios/Pods/ViewControllers/TermAndConditionsVC.swift +63 -0
  25. package/ios/easymerchantsdk.podspec +1 -1
  26. package/package.json +1 -1
@@ -0,0 +1,1137 @@
1
+ //
2
+ // AdditionalInfoVC.swift
3
+ // EasyPay
4
+ //
5
+ // Created by Mony's Mac on 13/08/24.
6
+ //
7
+
8
+ import UIKit
9
+
10
+ // @available(iOS 16.0, *)
11
+ class AdditionalInfoVC: BaseVC {
12
+
13
+ @IBOutlet weak var viewAdditionalInfo: UIView!
14
+ @IBOutlet weak var txtFieldName: UITextField!
15
+ @IBOutlet weak var txtFieldEmail: UITextField!
16
+ @IBOutlet weak var txtFieldPhoneNumber: UITextField!
17
+ @IBOutlet weak var txtFieldDescription: UITextField!
18
+ @IBOutlet weak var lblCountryCode: UILabel!
19
+ @IBOutlet weak var btnPrevious: UIButton!
20
+ @IBOutlet weak var imgViewCountryFlag: UIImageView!
21
+
22
+ @IBOutlet weak var btnPayNow: UIButton!
23
+
24
+ @IBOutlet weak var lblAdditionalInfo: UILabel!
25
+ @IBOutlet weak var lblEasyMerchant: UILabel!
26
+ @IBOutlet weak var btnCountryCode: UIButton!
27
+
28
+ var cardNumber: String?
29
+ var expiryDate: String?
30
+ var cvv: String?
31
+ var nameOnCard: String?
32
+ var billingInfoData: [String: Any]?
33
+
34
+ var selectedPaymentMethod: String?
35
+
36
+ //Banking Params
37
+ var accountName: String?
38
+ var routingNumber: String?
39
+ var accountType: String?
40
+ var accountNumber: String?
41
+
42
+ var easyPayDelegate: EasyPayViewControllerDelegate?
43
+
44
+ var isSavedForFuture: Bool = false
45
+
46
+ var selectedCard: CardModel?
47
+ var amount: Int?
48
+ var cvvText: String?
49
+ var isFrom = String()
50
+
51
+ var isSavedNewCard: Bool = false
52
+
53
+ //From Regular Saved Bank Accounts
54
+ var customerID: String?
55
+ var accountID: String?
56
+
57
+ var isSavedNewAccount: Bool?
58
+
59
+ override func viewDidLoad() {
60
+ super.viewDidLoad()
61
+
62
+ uiFinishingTouchElements()
63
+
64
+ txtFieldName.delegate = self
65
+ txtFieldEmail.delegate = self
66
+ txtFieldDescription.delegate = self
67
+ txtFieldPhoneNumber.delegate = self
68
+
69
+ // Add tap gesture to hide the views and dismiss the keyboard
70
+ let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOutside))
71
+ tapGesture.cancelsTouchesInView = false
72
+ self.view.addGestureRecognizer(tapGesture)
73
+
74
+ if let billingInfoData = billingInfoData {
75
+ print("Billing Info Data: \(billingInfoData)")
76
+
77
+ // Extract the additional_info dictionary
78
+ if let additionalInfo = billingInfoData["additional_info"] as? [String: Any] {
79
+ // Set the name field
80
+ if let name = additionalInfo["name"] as? String {
81
+ txtFieldName.text = name
82
+ }
83
+
84
+ if let email = additionalInfo["email"] as? String {
85
+ txtFieldEmail.text = email
86
+ }
87
+
88
+ if let phoneNumber = additionalInfo["phone_number"] as? String {
89
+ txtFieldPhoneNumber.text = phoneNumber
90
+ }
91
+
92
+ if let description = additionalInfo["description"] as? String {
93
+ txtFieldDescription.text = description
94
+ }
95
+ }
96
+ }
97
+
98
+ //Show Default USA code in starting.
99
+ let usaCountry = Country()
100
+ usaCountry.name = "United States"
101
+ usaCountry.countryCode = "US"
102
+ usaCountry.extensionCode = "1"
103
+ usaCountry.flag = String.flag(for: "US")
104
+ lblCountryCode.text = "\(usaCountry.flag ?? "") +\(usaCountry.extensionCode ?? "")"
105
+
106
+ // print(amount ?? "")
107
+ // let am = Int(amount ?? "0")
108
+ // btnPayNow.setTitle("Pay Now ($\(am ?? 0))", for: .normal)
109
+ //
110
+ // print("Received customerID: \(customerID ?? "nil")")
111
+ // print("Received accountID: \(accountID ?? "nil")")
112
+ // print(billingInfoData ?? "")
113
+ // print(isFrom)
114
+ // print(selectedPaymentMethod ?? "")
115
+ }
116
+
117
+ override func viewWillAppear(_ animated: Bool) {
118
+ uiFinishingTouchElements()
119
+ }
120
+
121
+ func uiFinishingTouchElements() {
122
+ // Set background color for the main view
123
+ if let containerBGcolor = UserStoreSingleton.shared.container_bg_col,
124
+ let uiColor = UIColor(hex: containerBGcolor) {
125
+ self.view.backgroundColor = uiColor
126
+ }
127
+
128
+ if let primaryBtnBackGroundColor = UserStoreSingleton.shared.primary_btn_bg_col,
129
+ let uiColor = UIColor(hex: primaryBtnBackGroundColor) {
130
+ btnPayNow.backgroundColor = uiColor
131
+ btnPrevious.setTitleColor(uiColor, for: .normal)
132
+ btnPrevious.layer.borderColor = uiColor.cgColor
133
+ }
134
+
135
+ if let primaryBtnFontColor = UserStoreSingleton.shared.primary_btn_font_col,
136
+ let secondaryUIColor = UIColor(hex: primaryBtnFontColor) {
137
+ btnPayNow.setTitleColor(secondaryUIColor, for: .normal)
138
+ }
139
+
140
+ if let secondaryFontColor = UserStoreSingleton.shared.secondary_font_col,
141
+ let placeholderColor = UIColor(hex: secondaryFontColor) {
142
+ lblEasyMerchant.textColor = placeholderColor
143
+ viewAdditionalInfo.layer.borderColor = placeholderColor.cgColor
144
+ }
145
+ else {
146
+ viewAdditionalInfo.layer.borderColor = UIColor.systemGray.cgColor
147
+ }
148
+
149
+ if let borderRadiusString = UserStoreSingleton.shared.border_radious,
150
+ let borderRadius = Double(borderRadiusString) { // Convert String to Double
151
+ btnPayNow.layer.cornerRadius = CGFloat(borderRadius) // Set corner radius
152
+ btnPrevious.layer.cornerRadius = CGFloat(borderRadius)
153
+ btnPrevious.layer.borderWidth = 1
154
+ viewAdditionalInfo.layer.cornerRadius = CGFloat(borderRadius)
155
+ viewAdditionalInfo.layer.borderWidth = 1
156
+ } else {
157
+ btnPayNow.layer.cornerRadius = 8 // Default value
158
+ btnPrevious.layer.cornerRadius = 8
159
+ viewAdditionalInfo.layer.borderWidth = 1
160
+ viewAdditionalInfo.layer.cornerRadius = 8
161
+ }
162
+ btnPayNow.layer.masksToBounds = true // Ensure the corners are clipped properly
163
+ btnPrevious.layer.masksToBounds = true
164
+ viewAdditionalInfo.layer.masksToBounds = true
165
+
166
+ if let primaryFontColor = UserStoreSingleton.shared.primary_font_col,
167
+ let uiColor = UIColor(hex: primaryFontColor) {
168
+ lblAdditionalInfo.textColor = uiColor
169
+ lblCountryCode.textColor = uiColor
170
+ }
171
+
172
+ if let fontSizeString = UserStoreSingleton.shared.fontSize,
173
+ let fontSizeDouble = Double(fontSizeString) { // Convert String to Double
174
+ let fontSize = CGFloat(fontSizeDouble) // Convert Double to CGFloat
175
+ lblEasyMerchant.font = UIFont.systemFont(ofSize: fontSize)
176
+ lblCountryCode.font = UIFont.systemFont(ofSize: fontSize)
177
+ btnPayNow.titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
178
+ btnPrevious.titleLabel?.font = UIFont.systemFont(ofSize: fontSize)
179
+ }
180
+
181
+ }
182
+
183
+ @objc func didTapOutside() {
184
+ // Dismiss the keyboard
185
+ self.view.endEditing(true)
186
+ }
187
+
188
+ @IBAction func actionBtnSelectCountryCode(_ sender: UIButton) {
189
+ let vc = EasyPaySdk.instantiateViewController(withIdentifier: "CountryListVC") as! CountryListVC
190
+ vc.delegate = self
191
+ self.navigationController?.pushViewController(vc, animated: true)
192
+ }
193
+
194
+ @IBAction func actionBtnPrevious(_ sender: UIButton) {
195
+ self.navigationController?.popViewController(animated: true)
196
+ }
197
+
198
+ @IBAction func actionBtnPayNow(_ sender: UIButton) {
199
+ if isSavedNewCard {
200
+ if isFrom == "AddNewCard" {
201
+ self.paymentIntentAddNewCardApi(customerId: UserStoreSingleton.shared.customerId)
202
+ }
203
+ }
204
+ else {
205
+ if isSavedForFuture {
206
+ // Navigate to EmailVerificationVC based on the selected payment method
207
+ if selectedPaymentMethod == "Card" {
208
+ if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
209
+ // Pass any necessary data to EmailVerificationVC
210
+ emailVerificationVC.cardNumber = cardNumber
211
+ emailVerificationVC.expiryDate = expiryDate
212
+ emailVerificationVC.cvv = cvv
213
+ emailVerificationVC.nameOnCard = nameOnCard
214
+ emailVerificationVC.billingInfoData = billingInfoData
215
+ emailVerificationVC.selectedPaymentMethod = selectedPaymentMethod
216
+ emailVerificationVC.easyPayDelegate = self.easyPayDelegate
217
+ self.navigationController?.pushViewController(emailVerificationVC, animated: true)
218
+ }
219
+ } else if selectedPaymentMethod == "Bank" {
220
+ if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
221
+ // Pass any necessary data to EmailVerificationVC
222
+ emailVerificationVC.accountName = accountName
223
+ emailVerificationVC.routingNumber = routingNumber
224
+ emailVerificationVC.accountType = accountType
225
+ emailVerificationVC.accountNumber = accountNumber
226
+ emailVerificationVC.billingInfoData = billingInfoData
227
+ emailVerificationVC.selectedPaymentMethod = selectedPaymentMethod
228
+ emailVerificationVC.easyPayDelegate = self.easyPayDelegate
229
+ self.navigationController?.pushViewController(emailVerificationVC, animated: true)
230
+ }
231
+ }
232
+ } else {
233
+ // Proceed with the normal flow
234
+ if selectedPaymentMethod == "Card" {
235
+ if isFrom == "SavedCards" {
236
+ paymentIntentFromShowCardApi()
237
+ }
238
+ else {
239
+ paymentIntentApi()
240
+ }
241
+ }
242
+ else if selectedPaymentMethod == "Bank" {
243
+ if isFrom == "SavedBank" {
244
+ accountChargeSavedBankAccountApi()
245
+ }
246
+ else if isFrom == "NormalBankPayWithoutSave" {
247
+ accountChargeApi()
248
+ }
249
+ else if isFrom == "AddNewAccountWithoutSave" {
250
+ accountChargeApi()
251
+ }
252
+ else if isFrom == "AddNewAccountWithSave" {
253
+ accountChargeApi(customerId: UserStoreSingleton.shared.customerId)
254
+ }
255
+ }
256
+ }
257
+ }
258
+
259
+ }
260
+
261
+ func presentPaymentErrorVC(errorMessage: String) {
262
+ DispatchQueue.main.async {
263
+ if let paymentErrorVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentErrorVC") as? PaymentErrorVC {
264
+ paymentErrorVC.errorMessage = errorMessage
265
+ paymentErrorVC.easyPayDelegate = self.easyPayDelegate // Pass the reference here
266
+ self.navigationController?.pushViewController(paymentErrorVC, animated: true)
267
+ }
268
+ }
269
+ }
270
+
271
+ // MARK: - Credit Card Charge Api
272
+ func paymentIntentApi() {
273
+ showLoadingIndicator()
274
+
275
+ // var components = URLComponents()
276
+ // components.scheme = "https"
277
+ // components.host = "stage-api.stage-easymerchant.io"
278
+ // components.path = "/api/v1/charges"
279
+ //
280
+ // guard let serviceURL = components.url else {
281
+ // print("Invalid URL")
282
+ // self.hideLoadingIndicator()
283
+ // return
284
+ // }
285
+
286
+ // Construct the full URL using baseURL from EnvironmentConfig and path from the endpoint
287
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.charges.path()
288
+
289
+ guard let serviceURL = URL(string: fullURL) else {
290
+ print("Invalid URL")
291
+ hideLoadingIndicator()
292
+ return
293
+ }
294
+
295
+ var request = URLRequest(url: serviceURL)
296
+ request.httpMethod = "POST"
297
+ request.addValue("application/json", forHTTPHeaderField: "Content-Type")
298
+
299
+ let token = UserStoreSingleton.shared.clientToken
300
+ print("Setting clientToken header: \(token ?? "None")")
301
+ request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
302
+
303
+ guard let billingInfoData = billingInfoData else {
304
+ print("Billing info data is nil")
305
+ return
306
+ }
307
+
308
+ // Remove the flag and "+" sign from lblCountryCode.text
309
+ let countryCode = lblCountryCode.text ?? ""
310
+ let cleanedCountryCode = countryCode.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
311
+ // Format phone number parameter by combining cleaned country code and phone number
312
+ let phoneNumber = "\(cleanedCountryCode)\(txtFieldPhoneNumber.text ?? "")"
313
+
314
+ let additionalInfo: [String: Any] = [
315
+ "name": txtFieldName.text ?? "",
316
+ "email": txtFieldEmail.text ?? "",
317
+ // "phone_number": "\("1") \(txtFieldPhoneNumber.text ?? "")",
318
+ "phone_number": phoneNumber,
319
+ "description": txtFieldDescription.text ?? ""
320
+ ]
321
+
322
+ let billingInfo: [String: Any] = [
323
+ "address": billingInfoData["address"] as? String ?? "",
324
+ "country": billingInfoData["country"] as? String ?? "",
325
+ "state": billingInfoData["state"] as? String ?? "",
326
+ "city": billingInfoData["city"] as? String ?? "",
327
+ "postal_code": billingInfoData["postal_code"] as? String ?? ""
328
+ ]
329
+
330
+ let params: [String: Any] = [
331
+ "name": txtFieldName.text ?? "",
332
+ "email": txtFieldEmail.text ?? "",
333
+ "card_number": cardNumber?.replacingOccurrences(of: " ", with: "") ?? "",
334
+ "cardholder_name": nameOnCard ?? "",
335
+ "exp_month": expiryDate?.components(separatedBy: "/").first ?? "",
336
+ "exp_year": expiryDate?.components(separatedBy: "/").last ?? "",
337
+ "cvc": cvv ?? "",
338
+ "description": txtFieldDescription.text ?? "",
339
+ "currency": "usd",
340
+ "billing_info": billingInfo,
341
+ "additional_info": additionalInfo,
342
+ "payment_method": "card",
343
+ "save_card": 0,
344
+ ]
345
+
346
+ do {
347
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
348
+ request.httpBody = jsonData
349
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
350
+ print("JSON Payload: \(jsonString)")
351
+ }
352
+ } catch let error {
353
+ print("Error creating JSON data: \(error)")
354
+ self.hideLoadingIndicator()
355
+ return
356
+ }
357
+
358
+ let session = URLSession.shared
359
+ let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
360
+
361
+ DispatchQueue.main.async {
362
+ self.hideLoadingIndicator() // Stop loader when response is received
363
+ }
364
+
365
+ if let error = error {
366
+ print("Error: \(error.localizedDescription)")
367
+ return
368
+ }
369
+
370
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
371
+ print("Invalid response")
372
+ return
373
+ }
374
+
375
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
376
+ if let data = serviceData {
377
+ do {
378
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
379
+ print("Response Data: \(responseObject)")
380
+
381
+ // Check if status is 0 and handle the error
382
+ if let status = responseObject["status"] as? Int, status == 0 {
383
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
384
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
385
+ } else {
386
+ DispatchQueue.main.async {
387
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
388
+ paymentDoneVC.chargeData = responseObject
389
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
390
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate
391
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
392
+ }
393
+ }
394
+ }
395
+ } else {
396
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
397
+ }
398
+ } catch let jsonError {
399
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
400
+ }
401
+ } else {
402
+ self.presentPaymentErrorVC(errorMessage: "No data received")
403
+ }
404
+ } else {
405
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
406
+ }
407
+ }
408
+ task.resume()
409
+ }
410
+
411
+ //MARK: - Credit Card Charge Api from Saved cards
412
+ func paymentIntentFromShowCardApi() {
413
+ showLoadingIndicator()
414
+ // var components = URLComponents()
415
+ // components.scheme = "https"
416
+ // components.host = "stage-api.stage-easymerchant.io"
417
+ // components.path = "/api/v1/charges"
418
+ //
419
+ // guard let serviceURL = components.url else {
420
+ // print("Invalid URL")
421
+ // hideLoadingIndicator()
422
+ // return
423
+ // }
424
+
425
+ // Construct the full URL using baseURL from EnvironmentConfig and path from the endpoint
426
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.charges.path()
427
+
428
+ guard let serviceURL = URL(string: fullURL) else {
429
+ print("Invalid URL")
430
+ hideLoadingIndicator()
431
+ return
432
+ }
433
+
434
+ var request = URLRequest(url: serviceURL)
435
+ request.httpMethod = "POST"
436
+ request.addValue("application/json", forHTTPHeaderField: "Content-Type")
437
+
438
+ let token = UserStoreSingleton.shared.clientToken
439
+ print("Setting clientToken header: \(token ?? "None")")
440
+ request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
441
+
442
+ guard let billingInfoData = billingInfoData else {
443
+ print("Billing info data is nil")
444
+ return
445
+ }
446
+
447
+ // Remove the flag and "+" sign from lblCountryCode.text
448
+ let countryCode = lblCountryCode.text ?? ""
449
+ let cleanedCountryCode = countryCode.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
450
+ // Format phone number parameter by combining cleaned country code and phone number
451
+ let phoneNumber = "\(cleanedCountryCode)\(txtFieldPhoneNumber.text ?? "")"
452
+
453
+ let additionalInfo: [String: Any] = [
454
+ "name": txtFieldName.text ?? "",
455
+ "email": txtFieldEmail.text ?? "",
456
+ // "phone_number": "\("1") \(txtFieldPhoneNumber.text ?? "")",
457
+ "phone_number": phoneNumber,
458
+ "description": txtFieldDescription.text ?? ""
459
+ ]
460
+
461
+ let billingInfo: [String: Any] = [
462
+ "address": billingInfoData["address"] as? String ?? "",
463
+ "country": billingInfoData["country"] as? String ?? "",
464
+ "state": billingInfoData["state"] as? String ?? "",
465
+ "city": billingInfoData["city"] as? String ?? "",
466
+ "postal_code": billingInfoData["postal_code"] as? String ?? ""
467
+ ]
468
+
469
+ let params: [String: Any] = [
470
+ "name": txtFieldName.text ?? "",
471
+ "email": txtFieldEmail.text ?? "",
472
+ "description": txtFieldDescription.text ?? "",
473
+ "currency": "usd",
474
+ "billing_info": billingInfo,
475
+ "additional_info": additionalInfo,
476
+ "payment_method": "card",
477
+ "save_card": 0,
478
+ "customer" : selectedCard?.customerId ?? "",
479
+ "customer_id" : selectedCard?.customerId ?? "",
480
+ "card_id" : selectedCard?.cardId ?? "",
481
+ "cvc" : cvvText ?? ""
482
+ ]
483
+
484
+ do {
485
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
486
+ request.httpBody = jsonData
487
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
488
+ print("JSON Payload: \(jsonString)")
489
+ }
490
+ } catch let error {
491
+ print("Error creating JSON data: \(error)")
492
+ hideLoadingIndicator()
493
+ return
494
+ }
495
+
496
+ let session = URLSession.shared
497
+ let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
498
+
499
+ DispatchQueue.main.async {
500
+ self.hideLoadingIndicator() // Stop loader when response is received
501
+ }
502
+
503
+ if let error = error {
504
+ print("Error: \(error.localizedDescription)")
505
+ return
506
+ }
507
+
508
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
509
+ print("Invalid response")
510
+ return
511
+ }
512
+
513
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
514
+ if let data = serviceData {
515
+ do {
516
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
517
+ print("Response Data: \(responseObject)")
518
+
519
+ // Check if status is 0 and handle the error
520
+ if let status = responseObject["status"] as? Int, status == 0 {
521
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
522
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
523
+ } else {
524
+ DispatchQueue.main.async {
525
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
526
+ paymentDoneVC.chargeData = responseObject
527
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
528
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate
529
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
530
+ }
531
+ }
532
+ }
533
+ } else {
534
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
535
+ }
536
+ } catch let jsonError {
537
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
538
+ }
539
+ } else {
540
+ self.presentPaymentErrorVC(errorMessage: "No data received")
541
+ }
542
+ } else {
543
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
544
+ }
545
+ }
546
+ task.resume()
547
+ }
548
+
549
+ //MARK: - Credit Card Charge Api from Add new card from saved cards.
550
+ func paymentIntentAddNewCardApi(customerId: String?) {
551
+ showLoadingIndicator()
552
+
553
+ // var components = URLComponents()
554
+ // components.scheme = "https"
555
+ // components.host = "stage-api.stage-easymerchant.io"
556
+ // components.path = "/api/v1/charges"
557
+ //
558
+ // guard let serviceURL = components.url else {
559
+ // print("Invalid URL")
560
+ // hideLoadingIndicator()
561
+ // return
562
+ // }
563
+
564
+ // Construct the full URL using baseURL from EnvironmentConfig and path from the endpoint
565
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.charges.path()
566
+
567
+ guard let serviceURL = URL(string: fullURL) else {
568
+ print("Invalid URL")
569
+ hideLoadingIndicator()
570
+ return
571
+ }
572
+
573
+ var request = URLRequest(url: serviceURL)
574
+ request.httpMethod = "POST"
575
+ request.addValue("application/json", forHTTPHeaderField: "Content-Type")
576
+
577
+ let token = UserStoreSingleton.shared.clientToken
578
+ print("Setting clientToken header: \(token ?? "None")")
579
+ request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
580
+
581
+ guard let billingInfoData = billingInfoData else {
582
+ print("Billing info data is nil")
583
+ return
584
+ }
585
+
586
+ let additionalInfoFromBilling = billingInfoData["additional_info"] as? [String: Any] ?? [:]
587
+
588
+ let additionalInfo: [String: Any] = [
589
+ "name": additionalInfoFromBilling["name"] as? String ?? "",
590
+ "email": additionalInfoFromBilling["email"] as? String ?? "",
591
+ "phone_number": additionalInfoFromBilling["phone_number"] as? String ?? "",
592
+ "description": additionalInfoFromBilling["description"] as? String ?? ""
593
+ ]
594
+
595
+ let billingInfo: [String: Any] = [
596
+ "address": billingInfoData["address"] as? String ?? "",
597
+ "country": billingInfoData["country"] as? String ?? "",
598
+ "state": billingInfoData["state"] as? String ?? "",
599
+ "city": billingInfoData["city"] as? String ?? "",
600
+ "postal_code": billingInfoData["postal_code"] as? String ?? ""
601
+ ]
602
+
603
+ let emailPrefix = UserStoreSingleton.shared.verificationEmail?.components(separatedBy: "@").first ?? ""
604
+
605
+ var params: [String: Any] = [
606
+ "name": additionalInfoFromBilling["name"] as? String ?? "",
607
+ "card_number": cardNumber?.replacingOccurrences(of: " ", with: "") ?? "",
608
+ "cardholder_name": nameOnCard ?? "",
609
+ "exp_month": expiryDate?.components(separatedBy: "/").first ?? "",
610
+ "exp_year": expiryDate?.components(separatedBy: "/").last ?? "",
611
+ "cvc": cvv ?? "",
612
+ "description": additionalInfoFromBilling["description"] as? String ?? "",
613
+ "currency": "usd",
614
+ "billing_info": billingInfo,
615
+ "additional_info": additionalInfo,
616
+ "payment_method": selectedPaymentMethod ?? "",
617
+ "save_card": isSavedNewCard ? 1 : 0
618
+ ]
619
+
620
+ // Add is_default parameter if save_card is 1
621
+ if isSavedNewCard {
622
+ params["is_default"] = "1"
623
+ }
624
+
625
+ if let customerId = customerId {
626
+ params["customer"] = customerId
627
+ params["customer_id"] = customerId
628
+ } else {
629
+ params["username"] = emailPrefix
630
+ params["email"] = UserStoreSingleton.shared.verificationEmail
631
+ }
632
+
633
+ print(params)
634
+
635
+ do {
636
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
637
+ request.httpBody = jsonData
638
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
639
+ print("JSON Payload: \(jsonString)")
640
+ }
641
+ } catch let error {
642
+ print("Error creating JSON data: \(error)")
643
+ hideLoadingIndicator()
644
+ return
645
+ }
646
+
647
+ let session = URLSession.shared
648
+ let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
649
+
650
+ DispatchQueue.main.async {
651
+ self.hideLoadingIndicator() // Stop loader when response is received
652
+ }
653
+
654
+ if let error = error {
655
+ self.presentPaymentErrorVC(errorMessage: error.localizedDescription)
656
+ return
657
+ }
658
+
659
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
660
+ self.presentPaymentErrorVC(errorMessage: "Invalid response")
661
+ return
662
+ }
663
+
664
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
665
+ if let data = serviceData {
666
+ do {
667
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
668
+ print("Response Data: \(responseObject)")
669
+
670
+ // Check if status is 0 and handle the error
671
+ if let status = responseObject["status"] as? Int, status == 0 {
672
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
673
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
674
+ } else {
675
+ DispatchQueue.main.async {
676
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
677
+ paymentDoneVC.chargeData = responseObject
678
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
679
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate
680
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
681
+ }
682
+ }
683
+ }
684
+ } else {
685
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
686
+ }
687
+ } catch let jsonError {
688
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
689
+ }
690
+ } else {
691
+ self.presentPaymentErrorVC(errorMessage: "No data received")
692
+ }
693
+ } else {
694
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
695
+ }
696
+ }
697
+ task.resume()
698
+ }
699
+
700
+ //MARK: - Banking Account Charge Api
701
+ func accountChargeApi() {
702
+ showLoadingIndicator()
703
+
704
+ // var components = URLComponents()
705
+ // components.scheme = "https"
706
+ // components.host = "stage-api.stage-easymerchant.io"
707
+ // components.path = "/api/v1/ach/charge"
708
+ //
709
+ // guard let serviceURL = components.url else {
710
+ // print("Invalid URL")
711
+ // hideLoadingIndicator()
712
+ // return
713
+ // }
714
+
715
+ // Construct the full URL using baseURL from EnvironmentConfig and path from the endpoint
716
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.achCharge.path()
717
+
718
+ guard let serviceURL = URL(string: fullURL) else {
719
+ print("Invalid URL")
720
+ hideLoadingIndicator()
721
+ return
722
+ }
723
+
724
+ var request = URLRequest(url: serviceURL)
725
+ request.httpMethod = "POST"
726
+ request.addValue("application/json", forHTTPHeaderField: "Content-Type")
727
+
728
+ let token = UserStoreSingleton.shared.clientToken
729
+ print("Setting clientToken header: \(token ?? "None")")
730
+ request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
731
+
732
+ guard let billingInfoData = billingInfoData else {
733
+ print("Billing info data is nil")
734
+ return
735
+ }
736
+
737
+ // Remove the flag and "+" sign from lblCountryCode.text
738
+ let countryCode = lblCountryCode.text ?? ""
739
+ let cleanedCountryCode = countryCode.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
740
+ // Format phone number parameter by combining cleaned country code and phone number
741
+ let phoneNumber = "\(cleanedCountryCode)\(txtFieldPhoneNumber.text ?? "")"
742
+
743
+ let additionalInfo: [String: Any] = [
744
+ "name": txtFieldName.text ?? "",
745
+ "email": txtFieldEmail.text ?? "",
746
+ // "phone_number": "\("1") \(txtFieldPhoneNumber.text ?? "")",
747
+ "phone_number": phoneNumber,
748
+ "description": txtFieldDescription.text ?? ""
749
+ ]
750
+
751
+ let billingInfo: [String: Any] = [
752
+ "address": billingInfoData["address"] as? String ?? "",
753
+ "country": billingInfoData["country"] as? String ?? "",
754
+ "state": billingInfoData["state"] as? String ?? "",
755
+ "city": billingInfoData["city"] as? String ?? "",
756
+ "postal_code": billingInfoData["postal_code"] as? String ?? ""
757
+ ]
758
+
759
+ let params: [String: Any] = [
760
+ "name": txtFieldName.text ?? "",
761
+ "email": txtFieldEmail.text ?? "",
762
+ "description": txtFieldDescription.text ?? "",
763
+ "currency": "usd",
764
+ "billing_info": billingInfo,
765
+ "additional_info": additionalInfo,
766
+ "account_type": accountType?.lowercased() ?? "",
767
+ "routing_number": routingNumber ?? "",
768
+ "account_number": accountNumber ?? "",
769
+ "payment_mode": "auth_and_capture",
770
+ "payment_intent": UserStoreSingleton.shared.paymentIntent ?? "",
771
+ "levelIndicator": 1,
772
+ ]
773
+
774
+ print(params)
775
+
776
+ do {
777
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
778
+ request.httpBody = jsonData
779
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
780
+ print("JSON Payload: \(jsonString)")
781
+ }
782
+ } catch let error {
783
+ print("Error creating JSON data: \(error)")
784
+ hideLoadingIndicator()
785
+ return
786
+ }
787
+
788
+ let session = URLSession.shared
789
+ let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
790
+
791
+ DispatchQueue.main.async {
792
+ self.hideLoadingIndicator() // Stop loader when response is received
793
+ }
794
+
795
+ if let error = error {
796
+ print("Error: \(error.localizedDescription)")
797
+ return
798
+ }
799
+
800
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
801
+ print("Invalid response")
802
+ return
803
+ }
804
+
805
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
806
+ if let data = serviceData {
807
+ do {
808
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
809
+ print("Response Data: \(responseObject)")
810
+
811
+ // Check if status is 0 and handle the error
812
+ if let status = responseObject["status"] as? Int, status == 0 {
813
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
814
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
815
+ } else {
816
+ DispatchQueue.main.async {
817
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
818
+ paymentDoneVC.chargeData = responseObject
819
+ // Pass the selected payment method
820
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
821
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate // Pass the delegate
822
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
823
+ }
824
+ }
825
+ }
826
+ } else {
827
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
828
+ }
829
+ } catch let jsonError {
830
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
831
+ }
832
+ } else {
833
+ self.presentPaymentErrorVC(errorMessage: "No data received")
834
+ }
835
+ } else {
836
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
837
+ }
838
+ }
839
+ task.resume()
840
+ }
841
+
842
+ //MARK: - Banking Account Charge Api from Regular saved bank account
843
+ func accountChargeSavedBankAccountApi() {
844
+ showLoadingIndicator()
845
+
846
+ // var components = URLComponents()
847
+ // components.scheme = "https"
848
+ // components.host = "stage-api.stage-easymerchant.io"
849
+ // components.path = "/api/v1/ach/charge"
850
+ //
851
+ // guard let serviceURL = components.url else {
852
+ // print("Invalid URL")
853
+ // hideLoadingIndicator()
854
+ // return
855
+ // }
856
+
857
+ // Construct the full URL using baseURL from EnvironmentConfig and path from the endpoint
858
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.achCharge.path()
859
+
860
+ guard let serviceURL = URL(string: fullURL) else {
861
+ print("Invalid URL")
862
+ hideLoadingIndicator()
863
+ return
864
+ }
865
+
866
+ var request = URLRequest(url: serviceURL)
867
+ request.httpMethod = "POST"
868
+ request.addValue("application/json", forHTTPHeaderField: "Content-Type")
869
+
870
+ let token = UserStoreSingleton.shared.clientToken
871
+ print("Setting clientToken header: \(token ?? "None")")
872
+ request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
873
+
874
+ guard let billingInfoData = billingInfoData else {
875
+ print("Billing info data is nil")
876
+ return
877
+ }
878
+
879
+ // Remove the flag and "+" sign from lblCountryCode.text
880
+ let countryCode = lblCountryCode.text ?? ""
881
+ let cleanedCountryCode = countryCode.replacingOccurrences(of: "[^0-9]", with: "", options: .regularExpression)
882
+ // Format phone number parameter by combining cleaned country code and phone number
883
+ let phoneNumber = "\(cleanedCountryCode)\(txtFieldPhoneNumber.text ?? "")"
884
+
885
+ let additionalInfo: [String: Any] = [
886
+ "name": txtFieldName.text ?? "",
887
+ "email": txtFieldEmail.text ?? "",
888
+ // "phone_number": "\("1") \(txtFieldPhoneNumber.text ?? "")",
889
+ "phone_number": phoneNumber,
890
+ "description": txtFieldDescription.text ?? ""
891
+ ]
892
+
893
+ let billingInfo: [String: Any] = [
894
+ "address": billingInfoData["address"] as? String ?? "",
895
+ "country": billingInfoData["country"] as? String ?? "",
896
+ "state": billingInfoData["state"] as? String ?? "",
897
+ "city": billingInfoData["city"] as? String ?? "",
898
+ "postal_code": billingInfoData["postal_code"] as? String ?? ""
899
+ ]
900
+
901
+ let params: [String: Any] = [
902
+ "name": UserStoreSingleton.shared.merchantName ?? "",
903
+ "account_id": accountID ?? "",
904
+ "payment_method": "ach",
905
+ "customer": customerID ?? "",
906
+ "address": billingInfoData["address"] as? String ?? "",
907
+ "description": txtFieldDescription.text ?? "",
908
+ "currency": "usd",
909
+ "billing_info": billingInfo,
910
+ "additional_info": additionalInfo
911
+ ]
912
+
913
+ print(params)
914
+
915
+ do {
916
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
917
+ request.httpBody = jsonData
918
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
919
+ print("JSON Payload: \(jsonString)")
920
+ }
921
+ } catch let error {
922
+ print("Error creating JSON data: \(error)")
923
+ hideLoadingIndicator()
924
+ return
925
+ }
926
+
927
+ let session = URLSession.shared
928
+ let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
929
+
930
+ DispatchQueue.main.async {
931
+ self.hideLoadingIndicator() // Stop loader when response is received
932
+ }
933
+
934
+ if let error = error {
935
+ print("Error: \(error.localizedDescription)")
936
+ return
937
+ }
938
+
939
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
940
+ print("Invalid response")
941
+ return
942
+ }
943
+
944
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
945
+ if let data = serviceData {
946
+ do {
947
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
948
+ print("Response Data: \(responseObject)")
949
+
950
+ // Check if status is 0 and handle the error
951
+ if let status = responseObject["status"] as? Int, status == 0 {
952
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
953
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
954
+ } else {
955
+ DispatchQueue.main.async {
956
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
957
+ paymentDoneVC.chargeData = responseObject
958
+ // Pass the selected payment method
959
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
960
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate // Pass the delegate
961
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
962
+ }
963
+ }
964
+ }
965
+ } else {
966
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
967
+ }
968
+ } catch let jsonError {
969
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
970
+ }
971
+ } else {
972
+ self.presentPaymentErrorVC(errorMessage: "No data received")
973
+ }
974
+ } else {
975
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
976
+ }
977
+ }
978
+ task.resume()
979
+ }
980
+
981
+ //MARK: - Account Charge Api if user saved the account.
982
+ func accountChargeApi(customerId: String?) {
983
+ showLoadingIndicator()
984
+
985
+ // var components = URLComponents()
986
+ // components.scheme = "https"
987
+ // components.host = "stage-api.stage-easymerchant.io"
988
+ // components.path = "/api/v1/ach/charge"
989
+ //
990
+ // guard let serviceURL = components.url else {
991
+ // print("Invalid URL")
992
+ // hideLoadingIndicator()
993
+ // return
994
+ // }
995
+
996
+ // Construct the full URL using baseURL from EnvironmentConfig and path from the endpoint
997
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.achCharge.path()
998
+
999
+ guard let serviceURL = URL(string: fullURL) else {
1000
+ print("Invalid URL")
1001
+ hideLoadingIndicator()
1002
+ return
1003
+ }
1004
+
1005
+ var request = URLRequest(url: serviceURL)
1006
+ request.httpMethod = "POST"
1007
+ request.addValue("application/json", forHTTPHeaderField: "Content-Type")
1008
+
1009
+ let token = UserStoreSingleton.shared.clientToken
1010
+ print("Setting clientToken header: \(token ?? "None")")
1011
+ request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
1012
+
1013
+ guard let billingInfoData = billingInfoData else {
1014
+ print("Billing info data is nil")
1015
+ return
1016
+ }
1017
+
1018
+ let additionalInfoFromBilling = billingInfoData["additional_info"] as? [String: Any] ?? [:]
1019
+
1020
+ let additionalInfo: [String: Any] = [
1021
+ "name": additionalInfoFromBilling["name"] as? String ?? "",
1022
+ "email": additionalInfoFromBilling["email"] as? String ?? "",
1023
+ "phone_number": additionalInfoFromBilling["phone_number"] as? String ?? "",
1024
+ "description": additionalInfoFromBilling["description"] as? String ?? ""
1025
+ ]
1026
+
1027
+ let billingInfo: [String: Any] = [
1028
+ "address": billingInfoData["address"] as? String ?? "",
1029
+ "country": billingInfoData["country"] as? String ?? "",
1030
+ "state": billingInfoData["state"] as? String ?? "",
1031
+ "city": billingInfoData["city"] as? String ?? "",
1032
+ "postal_code": billingInfoData["postal_code"] as? String ?? ""
1033
+ ]
1034
+
1035
+ let emailPrefix = UserStoreSingleton.shared.verificationEmail?.components(separatedBy: "@").first ?? ""
1036
+
1037
+ var params: [String: Any] = [
1038
+ "name": additionalInfoFromBilling["name"] as? String ?? "",
1039
+ "email": UserStoreSingleton.shared.verificationEmail ?? "",
1040
+ "description": additionalInfoFromBilling["description"] as? String ?? "",
1041
+ "currency": "usd",
1042
+ "billing_info": billingInfo,
1043
+ "additional_info": additionalInfo,
1044
+ "account_type": accountType?.lowercased() ?? "",
1045
+ "routing_number": routingNumber ?? "",
1046
+ "account_number": accountNumber ?? "",
1047
+ "payment_mode": "auth_and_capture",
1048
+ "payment_intent": UserStoreSingleton.shared.paymentIntent ?? "",
1049
+ "levelIndicator": 1,
1050
+ "save_account": 1,
1051
+ "payment_method": "ach"
1052
+ ]
1053
+
1054
+ if let customerId = customerId {
1055
+ params["customer"] = customerId
1056
+ } else {
1057
+ params["username"] = emailPrefix
1058
+ }
1059
+
1060
+ print(params)
1061
+
1062
+ do {
1063
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
1064
+ request.httpBody = jsonData
1065
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
1066
+ print("JSON Payload: \(jsonString)")
1067
+ }
1068
+ } catch let error {
1069
+ print("Error creating JSON data: \(error)")
1070
+ hideLoadingIndicator()
1071
+ return
1072
+ }
1073
+
1074
+ let session = URLSession.shared
1075
+ let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
1076
+
1077
+ DispatchQueue.main.async {
1078
+ self.hideLoadingIndicator() // Stop loader when response is received
1079
+ }
1080
+
1081
+ if let error = error {
1082
+ self.presentPaymentErrorVC(errorMessage: error.localizedDescription)
1083
+ return
1084
+ }
1085
+
1086
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
1087
+ self.presentPaymentErrorVC(errorMessage: "Invalid response")
1088
+ return
1089
+ }
1090
+
1091
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
1092
+ if let data = serviceData {
1093
+ do {
1094
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
1095
+ print("Response Data: \(responseObject)")
1096
+
1097
+ // Check if status is 0 and handle the error
1098
+ if let status = responseObject["status"] as? Int, status == 0 {
1099
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
1100
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
1101
+ } else {
1102
+ DispatchQueue.main.async {
1103
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
1104
+ paymentDoneVC.chargeData = responseObject
1105
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
1106
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate
1107
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
1108
+ }
1109
+ }
1110
+ }
1111
+ } else {
1112
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
1113
+ }
1114
+ } catch let jsonError {
1115
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
1116
+ }
1117
+ } else {
1118
+ self.presentPaymentErrorVC(errorMessage: "No data received")
1119
+ }
1120
+ } else {
1121
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
1122
+ }
1123
+ }
1124
+ task.resume()
1125
+ }
1126
+
1127
+ }
1128
+
1129
+ extension AdditionalInfoVC: UITextFieldDelegate {
1130
+
1131
+ }
1132
+
1133
+ extension AdditionalInfoVC: CountryListVCDelegate {
1134
+ func didSelectCountry(_ country: Country) {
1135
+ lblCountryCode.text = "\(country.flag ?? "") +\(country.extensionCode ?? "")"
1136
+ }
1137
+ }