@jimrising/easymerchantsdk-react-native 1.4.3 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -862,24 +862,7 @@ class BillingInfoVC: BaseVC {
862
862
  navigationController?.pushViewController(vc, animated: true)
863
863
  }
864
864
  else if !isAdditionalVisible && isSavedForFuture {
865
- let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
866
- vc.billingInfoData = updatedBillingData
867
- vc.fieldSection = updatedFieldSection
868
- vc.billingInfo = updatedFieldSection.billing
869
- vc.additionalInfo = updatedFieldSection.additional
870
- vc.visibility = updatedFieldSection.visibility
871
- vc.selectedPaymentMethod = selectedPaymentMethod
872
- vc.isSavedForFuture = isSavedForFuture
873
- vc.isFrom = isFrom
874
- vc.isSavedNewAccount = isSavedNewAccount
875
- vc.amount = Int(request.amount ?? 0)
876
- vc.request = request
877
- vc.chosenPlan = chosenPlan
878
- vc.startDate = startDate
879
- vc.grailPayAccountID = grailPayAccountID
880
- vc.selectedGrailPayAccountType = selectedGrailPayAccountType
881
- vc.selectedGrailPayAccountName = selectedGrailPayAccountName
882
- navigationController?.pushViewController(vc, animated: true)
865
+ grailPayAccountChargeApi(customerId: UserStoreSingleton.shared.customerId)
883
866
  }
884
867
  else {
885
868
  grailPayAccountChargeApi()
@@ -2448,6 +2431,224 @@ class BillingInfoVC: BaseVC {
2448
2431
  task.resume()
2449
2432
  }
2450
2433
 
2434
+ //MARK: - GrailPay Account Charge Api if user saved account
2435
+ func grailPayAccountChargeApi(customerId: String?) {
2436
+ showLoadingIndicator()
2437
+
2438
+ let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.achCharge.path()
2439
+
2440
+ guard let serviceURL = URL(string: fullURL) else {
2441
+ print("Invalid URL")
2442
+ hideLoadingIndicator()
2443
+ return
2444
+ }
2445
+
2446
+ var uRLRequest = URLRequest(url: serviceURL)
2447
+ uRLRequest.httpMethod = "POST"
2448
+ uRLRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
2449
+
2450
+ let token = UserStoreSingleton.shared.clientToken
2451
+ print("Setting clientToken header: \(token ?? "None")")
2452
+ uRLRequest.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
2453
+
2454
+ if let apiKey = EnvironmentConfig.apiKey {
2455
+ uRLRequest.addValue(apiKey, forHTTPHeaderField: "X-Api-Key")
2456
+ }
2457
+ if let apiSecret = EnvironmentConfig.apiSecret {
2458
+ uRLRequest.addValue(apiSecret, forHTTPHeaderField: "X-Api-Secret")
2459
+ }
2460
+
2461
+ let emailPrefix = userEmail?.components(separatedBy: "@").first ?? ""
2462
+
2463
+ var params: [String: Any] = [
2464
+ "account_id": self.grailPayAccountID ?? "",
2465
+ "account_type": self.selectedGrailPayAccountType ?? "",
2466
+ "name": self.selectedGrailPayAccountName ?? "",
2467
+ "save_account": 1,
2468
+ "is_default": 1,
2469
+ "customer_id": customerId ?? "",
2470
+ "email": userEmail ?? "",
2471
+ "create_customer": "1",
2472
+ ]
2473
+
2474
+ if let customerId = customerId {
2475
+ params["customer"] = customerId
2476
+ } else {
2477
+ params["username"] = emailPrefix
2478
+ }
2479
+
2480
+ // // Billing Info
2481
+ // if let visibility = visibility, visibility.billing == true,
2482
+ // let billing = billingInfo, !billing.isEmpty {
2483
+ // var billingDict: [String: Any] = [:]
2484
+ // billing.forEach { billingDict[$0.name] = $0.value }
2485
+ //
2486
+ // params["address"] = billingDict["address"] as? String ?? ""
2487
+ // params["country"] = billingDict["country"] as? String ?? ""
2488
+ // params["state"] = billingDict["state"] as? String ?? ""
2489
+ // params["city"] = billingDict["city"] as? String ?? ""
2490
+ // params["zip"] = billingDict["postal_code"] as? String ?? ""
2491
+ // }
2492
+
2493
+ // Always include Billing Info if available
2494
+ if let billing = billingInfo, !billing.isEmpty {
2495
+ var billingDict: [String: Any] = [:]
2496
+ billing.forEach { billingDict[$0.name] = $0.value }
2497
+
2498
+ params["address"] = billingDict["address"] as? String ?? ""
2499
+ params["country"] = billingDict["country"] as? String ?? ""
2500
+ params["state"] = billingDict["state"] as? String ?? ""
2501
+ params["city"] = billingDict["city"] as? String ?? ""
2502
+ params["zip"] = billingDict["postal_code"] as? String ?? ""
2503
+ }
2504
+
2505
+ // // Additional Info or default description
2506
+ // var descriptionValue: String = "Hosted payment checkout" // default
2507
+ // if let visibility = visibility, visibility.additional == true,
2508
+ // let additional = additionalInfo, !additional.isEmpty {
2509
+ //
2510
+ // var additionalDict: [String: Any] = [:]
2511
+ // additional.forEach { additionalDict[$0.name] = $0.value }
2512
+ //
2513
+ // if let desc = additionalDict["description"] as? String, !desc.isEmpty {
2514
+ // descriptionValue = desc
2515
+ // }
2516
+ //
2517
+ // if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
2518
+ // params["phone_number"] = phone
2519
+ // }
2520
+ // }
2521
+ // params["description"] = descriptionValue
2522
+
2523
+ // Always include Additional Info if available
2524
+ var descriptionValue: String = "Hosted payment checkout"
2525
+ if let additional = additionalInfo, !additional.isEmpty {
2526
+ var additionalDict: [String: Any] = [:]
2527
+ additional.forEach { additionalDict[$0.name] = $0.value }
2528
+
2529
+ if let desc = additionalDict["description"] as? String, !desc.isEmpty {
2530
+ descriptionValue = desc
2531
+ }
2532
+
2533
+ if let phone = additionalDict["phone_number"] as? String, !phone.isEmpty {
2534
+ params["phone_number"] = phone
2535
+ }
2536
+ }
2537
+ params["description"] = descriptionValue
2538
+
2539
+ // Add these if recurring is enabled
2540
+ if let req = request, req.is_recurring == true {
2541
+ if let recurringType = req.recurringStartDateType, recurringType == .custom {
2542
+ // Only send start_date if type is .custom and field is not empty
2543
+ if let startDateText = startDate, !startDateText.isEmpty {
2544
+ let inputFormatter = DateFormatter()
2545
+ inputFormatter.dateFormat = "dd/MM/yyyy"
2546
+
2547
+ let outputFormatter = DateFormatter()
2548
+ outputFormatter.dateFormat = "MM/dd/yyyy"
2549
+
2550
+ if let date = inputFormatter.date(from: startDateText) {
2551
+ let apiFormattedDate = outputFormatter.string(from: date)
2552
+ params["start_date"] = apiFormattedDate
2553
+ } else {
2554
+ print("Invalid date format in startDateText")
2555
+ }
2556
+ }
2557
+ }
2558
+
2559
+ params["interval"] = chosenPlan?.lowercased()
2560
+ }
2561
+
2562
+ print(params)
2563
+
2564
+ do {
2565
+ let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
2566
+ uRLRequest.httpBody = jsonData
2567
+ if let jsonString = String(data: jsonData, encoding: .utf8) {
2568
+ print("JSON Payload: \(jsonString)")
2569
+ }
2570
+ } catch let error {
2571
+ print("Error creating JSON data: \(error)")
2572
+ hideLoadingIndicator()
2573
+ return
2574
+ }
2575
+
2576
+ let session = URLSession.shared
2577
+ let task = session.dataTask(with: uRLRequest) { (serviceData, serviceResponse, error) in
2578
+
2579
+ DispatchQueue.main.async {
2580
+ self.hideLoadingIndicator() // Stop loader when response is received
2581
+ }
2582
+
2583
+ if let error = error {
2584
+ self.presentPaymentErrorVC(errorMessage: error.localizedDescription)
2585
+ return
2586
+ }
2587
+
2588
+ guard let httpResponse = serviceResponse as? HTTPURLResponse else {
2589
+ self.presentPaymentErrorVC(errorMessage: "Invalid response")
2590
+ return
2591
+ }
2592
+
2593
+ if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
2594
+ if let data = serviceData {
2595
+ do {
2596
+ if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
2597
+ print("Response Data: \(responseObject)")
2598
+
2599
+ // Check if status is 0 and handle the error
2600
+ if let status = responseObject["status"] as? Int, status == 0 {
2601
+ let errorMessage = responseObject["message"] as? String ?? "Unknown error"
2602
+ self.presentPaymentErrorVC(errorMessage: errorMessage)
2603
+ } else {
2604
+ DispatchQueue.main.async {
2605
+ if let paymentDoneVC = self.storyboard?.instantiateViewController(withIdentifier: "PaymentDoneVC") as? PaymentDoneVC {
2606
+ paymentDoneVC.chargeData = responseObject
2607
+ paymentDoneVC.selectedPaymentMethod = self.selectedPaymentMethod
2608
+ paymentDoneVC.easyPayDelegate = self.easyPayDelegate
2609
+ // Pass billing and additional info
2610
+ // Conditionally pass raw FieldItem array
2611
+ paymentDoneVC.visibility = self.visibility
2612
+
2613
+ // if self.visibility?.billing == true {
2614
+ paymentDoneVC.billingInfoData = self.billingInfo
2615
+ var billingDict: [String: Any] = [:]
2616
+ self.billingInfo?.forEach { billingDict[$0.name] = $0.value }
2617
+ paymentDoneVC.billingInfo = billingDict
2618
+ // }
2619
+
2620
+ // if self.visibility?.additional == true {
2621
+ paymentDoneVC.additionalInfoData = self.additionalInfo
2622
+ var additionalDict: [String: Any] = [:]
2623
+ self.additionalInfo?.forEach { additionalDict[$0.name] = $0.value }
2624
+ paymentDoneVC.additionalInfo = additionalDict
2625
+ // }
2626
+ self.navigationController?.pushViewController(paymentDoneVC, animated: true)
2627
+ }
2628
+ }
2629
+ }
2630
+ } else {
2631
+ self.presentPaymentErrorVC(errorMessage: "Invalid JSON format")
2632
+ }
2633
+ } catch let jsonError {
2634
+ self.presentPaymentErrorVC(errorMessage: "Error parsing JSON: \(jsonError)")
2635
+ }
2636
+ } else {
2637
+ self.presentPaymentErrorVC(errorMessage: "No data received")
2638
+ }
2639
+ } else {
2640
+ if let data = serviceData,
2641
+ let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
2642
+ let message = responseObj["message"] as? String {
2643
+ self.presentPaymentErrorVC(errorMessage: message)
2644
+ } else {
2645
+ self.presentPaymentErrorVC(errorMessage: "HTTP Status Code: \(httpResponse.statusCode)")
2646
+ }
2647
+ }
2648
+ }
2649
+ task.resume()
2650
+ }
2651
+
2451
2652
  }
2452
2653
 
2453
2654
  //MARK: - Table View
@@ -53,6 +53,8 @@ class EmailVerificationVC: BaseVC {
53
53
  var isSavedNewAccount: Bool?
54
54
  var isFrom = String()
55
55
 
56
+ var isSavedNewCard: Bool = false
57
+
56
58
  override func viewDidLoad() {
57
59
  super.viewDidLoad()
58
60
 
@@ -139,35 +141,35 @@ class EmailVerificationVC: BaseVC {
139
141
  // MARK: - Send OTP Email Verification Api
140
142
  func emailVerificationApi() {
141
143
  showLoadingIndicator()
142
-
144
+
143
145
  let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.emailVerification.path()
144
-
146
+
145
147
  guard let serviceURL = URL(string: fullURL) else {
146
148
  print("Invalid URL")
147
149
  hideLoadingIndicator()
148
150
  return
149
151
  }
150
-
152
+
151
153
  var request = URLRequest(url: serviceURL)
152
154
  request.httpMethod = "POST"
153
155
  request.addValue("application/json", forHTTPHeaderField: "Content-Type")
154
-
156
+
155
157
  let token = UserStoreSingleton.shared.clientToken
156
158
  print("Setting clientToken header: \(token ?? "None")")
157
159
  request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
158
-
160
+
159
161
  // Add API headers
160
162
  if let apiKey = EnvironmentConfig.apiKey,
161
163
  let apiSecret = EnvironmentConfig.apiSecret {
162
164
  request.addValue(apiKey, forHTTPHeaderField: "x-api-key")
163
165
  request.addValue(apiSecret, forHTTPHeaderField: "x-api-secret")
164
166
  }
165
-
167
+
166
168
  let params: [String: Any] = [
167
169
  "card_search_value": txtFieldEmail.text ?? "",
168
170
  "card_search_key": "email"
169
171
  ]
170
-
172
+
171
173
  do {
172
174
  let jsonData = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
173
175
  request.httpBody = jsonData
@@ -179,115 +181,68 @@ class EmailVerificationVC: BaseVC {
179
181
  hideLoadingIndicator()
180
182
  return
181
183
  }
182
-
184
+
183
185
  let session = URLSession.shared
184
186
  let task = session.dataTask(with: request) { (serviceData, serviceResponse, error) in
185
-
187
+
186
188
  DispatchQueue.main.async {
187
- self.hideLoadingIndicator() // Stop loader when response is received
189
+ self.hideLoadingIndicator()
188
190
  }
189
-
191
+
190
192
  if let error = error {
191
193
  print("Error: \(error.localizedDescription)")
192
194
  return
193
195
  }
194
-
196
+
195
197
  guard let httpResponse = serviceResponse as? HTTPURLResponse else {
196
198
  print("Invalid response")
197
199
  return
198
200
  }
199
-
201
+
200
202
  if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
201
203
  if let data = serviceData {
202
204
  do {
203
205
  if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
204
206
  print("Response Data: \(responseObject)")
205
-
206
- // Navigate to PaymentDoneVC and pass the response data
207
+
207
208
  DispatchQueue.main.async {
208
- if self.selectedPaymentMethod == "Card" {
209
- if let vc = self.storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
210
- // Pass any necessary data to OTP VerfificationVC
209
+ if let vc = self.storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
210
+ vc.selectedPaymentMethod = self.selectedPaymentMethod
211
+ vc.easyPayDelegate = self.easyPayDelegate
212
+ vc.email = self.txtFieldEmail.text
213
+ vc.chosenPlan = self.chosenPlan
214
+ vc.startDate = self.startDate
215
+ vc.request = self.request
216
+ vc.billingInfoData = self.billingInfoData
217
+ vc.userEmail = self.userEmail
218
+ vc.billingInfo = self.fieldSection?.billing
219
+ vc.additionalInfo = self.fieldSection?.additional
220
+ vc.visibility = self.fieldSection?.visibility
221
+ vc.isSavedForFuture = self.isSavedForFuture
222
+
223
+ switch self.selectedPaymentMethod {
224
+ case "Card":
211
225
  vc.cardNumber = self.cardNumber
212
226
  vc.expiryDate = self.expiryDate
213
227
  vc.cvv = self.cvv
214
228
  vc.nameOnCard = self.nameOnCard
215
- vc.billingInfoData = self.billingInfoData
216
- vc.billingInfo = self.billingInfo
217
- vc.selectedPaymentMethod = self.selectedPaymentMethod
218
- vc.easyPayDelegate = self.easyPayDelegate
219
- vc.email = self.txtFieldEmail.text
220
- vc.isSavedForFuture = self.isSavedForFuture
221
- vc.request = self.request
222
- vc.chosenPlan = self.chosenPlan
223
- vc.startDate = self.startDate
224
- vc.userEmail = self.userEmail
225
- vc.billingInfo = self.billingInfo
226
- vc.additionalInfo = self.additionalInfo
227
- vc.visibility = self.visibility
228
- self.navigationController?.pushViewController(vc, animated: true)
229
- }
230
- }
231
- else if self.selectedPaymentMethod == "Bank" {
232
- if let vc = self.storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
229
+
230
+ case "Bank":
233
231
  vc.accountName = self.accountName
234
232
  vc.routingNumber = self.routingNumber
235
233
  vc.accountType = self.accountType
236
234
  vc.accountNumber = self.accountNumber
237
- vc.billingInfoData = self.billingInfoData
238
- vc.billingInfo = self.billingInfo
239
- vc.selectedPaymentMethod = self.selectedPaymentMethod
240
- vc.easyPayDelegate = self.easyPayDelegate
241
- vc.email = self.txtFieldEmail.text
242
- vc.chosenPlan = self.chosenPlan
243
- vc.startDate = self.startDate
244
- vc.request = self.request
245
- vc.userEmail = self.userEmail
246
- vc.billingInfo = self.fieldSection?.billing
247
- vc.additionalInfo = self.fieldSection?.additional
248
- vc.visibility = self.fieldSection?.visibility
249
- self.navigationController?.pushViewController(vc, animated: true)
250
- }
251
- }
252
- else if self.selectedPaymentMethod == "GrailPay" {
253
- if let vc = self.storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
254
- vc.selectedPaymentMethod = self.selectedPaymentMethod
255
- vc.easyPayDelegate = self.easyPayDelegate
256
- vc.grailPayAccountID = self.grailPayAccountID
257
- vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
258
- vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
259
- vc.email = self.txtFieldEmail.text
260
- vc.chosenPlan = self.chosenPlan
261
- vc.startDate = self.startDate
262
- vc.request = self.request
263
- vc.billingInfoData = self.billingInfoData
264
- vc.billingInfo = self.billingInfo
265
- vc.userEmail = self.userEmail
266
- vc.billingInfo = self.fieldSection?.billing
267
- vc.additionalInfo = self.fieldSection?.additional
268
- vc.visibility = self.fieldSection?.visibility
269
- self.navigationController?.pushViewController(vc, animated: true)
270
- }
271
- }
272
- else if self.selectedPaymentMethod == "NewGrailPayAccount" {
273
- if let vc = self.storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
274
- vc.selectedPaymentMethod = self.selectedPaymentMethod
275
- vc.easyPayDelegate = self.easyPayDelegate
235
+
236
+ case "GrailPay":
276
237
  vc.grailPayAccountID = self.grailPayAccountID
277
238
  vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
278
239
  vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
279
- vc.email = self.txtFieldEmail.text
280
- vc.chosenPlan = self.chosenPlan
281
- vc.startDate = self.startDate
282
- vc.request = self.request
283
- vc.billingInfoData = self.billingInfoData
284
- vc.billingInfo = self.billingInfo
285
- vc.userEmail = self.userEmail
286
- vc.billingInfo = self.fieldSection?.billing
287
- vc.additionalInfo = self.fieldSection?.additional
288
- vc.visibility = self.fieldSection?.visibility
289
- self.navigationController?.pushViewController(vc, animated: true)
240
+
241
+ default:
242
+ break
290
243
  }
244
+
245
+ self.navigationController?.pushViewController(vc, animated: true)
291
246
  }
292
247
  }
293
248
  } else {