@jimrising/easymerchantsdk-react-native 2.3.3 → 2.3.5
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 +1 -1
- package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
- package/android/build/.transforms/e9a664a11ce12edf79cd87b1e07aa243/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +1 -1
- package/ios/ApiManager/APIRequest.swift +1 -4
- package/ios/Bundle/EasyPayBundle.swift +1 -1
- package/ios/Classes/EasyMerchantSdk.m +2 -2
- package/ios/Classes/EasyMerchantSdk.swift +3 -3
- package/ios/CustomComponents/PlanSelector.swift +1 -1
- package/ios/Example/Base.lproj/Main.storyboard +183 -22
- package/ios/Example/ViewController.swift +208 -182
- package/ios/Helper/GrailPayHelper.swift +0 -1
- package/ios/Models/Request.swift +242 -51
- package/ios/Models/SDKResult.swift +32 -25
- package/ios/Pods/UserDefaults/UserStoreSingleton.swift +59 -60
- package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +360 -150
- package/ios/Pods/ViewControllers/BaseVC.swift +2 -1
- package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +401 -196
- package/ios/Pods/ViewControllers/Clean Runner_2025-07-23T14-58-05.txt +13 -0
- package/ios/Pods/ViewControllers/EmailVerificationVC.swift +0 -7
- package/ios/Pods/ViewControllers/GrailPayVC.swift +11 -3
- package/ios/Pods/ViewControllers/OTPVerificationVC.swift +252 -105
- package/ios/Pods/ViewControllers/PaymentDoneVC.swift +20 -5
- package/ios/Pods/ViewControllers/PaymentErrorVC.swift +2 -2
- package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +804 -347
- package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.swift +0 -1
- package/ios/Pods/ViewControllers/PaymentStatusWebViewVC.swift +1 -1
- package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +68 -66
- package/ios/Resources/Assets.xcassets/payment_done_icon.imageset/Contents.json +3 -0
- package/ios/easymerchantsdk.podspec +1 -1
- package/package.json +1 -1
- package/ios/CustomComponents/CheckboxButton.swift +0 -66
- package/ios/Models/AdditionalInfo.swift +0 -53
- package/ios/Models/BillingInfo.swift +0 -60
- package/ios/Pods/ViewControllers/CustomOverlay.swift +0 -199
- package/ios/Resources/Assets.xcassets/Card/Amex.imageset/206682_american_express_method_card_payment_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/Amex.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/Contents.json +0 -6
- package/ios/Resources/Assets.xcassets/Card/DinersClub.imageset/472318_card_club_diners_dinner_payment_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/DinersClub.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/Discover.imageset/206686_network_payment_discover_card_method_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/Discover.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/JCB.imageset/358102_card_jcb_payment_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/JCB.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/MasterCard.imageset/206680_master_method_card_payment_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/MasterCard.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/UnionPay.imageset/1468976_card_payment_unionpay_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/UnionPay.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/Visa.imageset/206684_visa_method_card_payment_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/Visa.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/maestro.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/maestro.imageset/maestro.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/paypal.imageset/206675_paypal_method_payment_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/paypal.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/rupay.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/rupay.imageset/rupay.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/unknown_card.imageset/4635000_card_credit_digital_money_icon.svg +0 -1
- package/ios/Resources/Assets.xcassets/Card/unknown_card.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/worldpay.imageset/Contents.json +0 -12
- package/ios/Resources/Assets.xcassets/Card/worldpay.imageset/worldpay.svg +0 -1
package/ios/Models/Request.swift
CHANGED
|
@@ -291,11 +291,11 @@ public final class Request: NSObject {
|
|
|
291
291
|
super.init()
|
|
292
292
|
|
|
293
293
|
// Environment must be set by host app
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
294
|
+
if EnvironmentConfig.isEnvironmentSet == false {
|
|
295
|
+
self.initializationErrorMessage = "environment not set"
|
|
296
|
+
Request.notifyValidationError(self.initializationErrorMessage!)
|
|
297
|
+
return
|
|
298
|
+
}
|
|
299
299
|
|
|
300
300
|
// ✅ Override amount if clientToken flow is used
|
|
301
301
|
if let token = clientToken, !token.isEmpty {
|
|
@@ -347,11 +347,14 @@ public final class Request: NSObject {
|
|
|
347
347
|
return
|
|
348
348
|
}
|
|
349
349
|
|
|
350
|
-
//
|
|
350
|
+
// Handle recurring setup differently for API keys vs clientToken flow
|
|
351
351
|
if let token = clientToken, !token.isEmpty {
|
|
352
|
+
// --- Client Token Flow ---
|
|
352
353
|
if let savedIsRecurring = UserStoreSingleton.shared.isRecurring,
|
|
353
|
-
savedIsRecurring == "1" {
|
|
354
|
+
savedIsRecurring == "1" {
|
|
355
|
+
|
|
354
356
|
self.is_recurring = true
|
|
357
|
+
print("Recurring enabled (clientToken flow) → is_recurring = \(self.is_recurring ?? false)")
|
|
355
358
|
|
|
356
359
|
if let cycles = UserStoreSingleton.shared.allowCycles,
|
|
357
360
|
let num = Int(cycles) {
|
|
@@ -359,7 +362,6 @@ public final class Request: NSObject {
|
|
|
359
362
|
}
|
|
360
363
|
|
|
361
364
|
if let intervals = UserStoreSingleton.shared.interval {
|
|
362
|
-
// API gives "daily,weekly,monthly" → split into array
|
|
363
365
|
let parts = intervals.split(separator: ",").map { String($0).trimmingCharacters(in: .whitespaces) }
|
|
364
366
|
self.recurringIntervals = parts.compactMap { RecurringIntervals(rawValue: $0) }
|
|
365
367
|
}
|
|
@@ -374,23 +376,29 @@ public final class Request: NSObject {
|
|
|
374
376
|
} else {
|
|
375
377
|
self.is_recurring = false
|
|
376
378
|
}
|
|
379
|
+
} else {
|
|
380
|
+
// --- API Keys Flow ---
|
|
381
|
+
// Keep whatever was passed from outside (don’t override)
|
|
382
|
+
print("Recurring setup (API keys flow) → is_recurring = \(self.is_recurring ?? false)")
|
|
377
383
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
384
|
+
|
|
385
|
+
if is_recurring == true {
|
|
386
|
+
// Validate recurring start date not in past
|
|
387
|
+
if let startDateString = recurringStartDate,
|
|
388
|
+
let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
|
|
389
|
+
let today = Calendar.current.startOfDay(for: Date())
|
|
390
|
+
let startDay = Calendar.current.startOfDay(for: startDate)
|
|
391
|
+
if startDay < today {
|
|
392
|
+
self.initializationErrorMessage = "The recurring start date cannot be in the past. Please select today or a future date."
|
|
393
|
+
Request.notifyValidationError(self.initializationErrorMessage!)
|
|
394
|
+
return
|
|
395
|
+
}
|
|
396
|
+
} else if recurringStartDate != nil {
|
|
397
|
+
// Provided but invalid format
|
|
398
|
+
self.initializationErrorMessage = "Recurring date format should be dd/MM/yyyy"
|
|
386
399
|
Request.notifyValidationError(self.initializationErrorMessage!)
|
|
387
400
|
return
|
|
388
401
|
}
|
|
389
|
-
} else if recurringStartDate != nil {
|
|
390
|
-
// Provided but invalid format
|
|
391
|
-
self.initializationErrorMessage = "Recurring date format should be dd/MM/yyyy"
|
|
392
|
-
Request.notifyValidationError(self.initializationErrorMessage!)
|
|
393
|
-
return
|
|
394
402
|
}
|
|
395
403
|
|
|
396
404
|
// Validate metadata limits
|
|
@@ -476,31 +484,31 @@ public final class Request: NSObject {
|
|
|
476
484
|
}
|
|
477
485
|
}
|
|
478
486
|
}
|
|
479
|
-
else {
|
|
480
|
-
if clientToken == nil {
|
|
481
|
-
// Proceed with normal payment flow for API key/secret case
|
|
482
|
-
self.paymentIntentApi { success in
|
|
483
|
-
if success {
|
|
484
|
-
print("Payment Intent API call succeeded")
|
|
485
|
-
UserStoreSingleton.shared.price = String(self.amount ?? 0)
|
|
486
|
-
print("Saved amount: \(UserStoreSingleton.shared.price ?? "No amount")")
|
|
487
|
-
} else {
|
|
488
|
-
print("Payment Intent API call failed")
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
} else {
|
|
492
|
-
// For clientToken case, directly call hostedCheckoutsApi
|
|
493
|
-
UserStoreSingleton.shared.clientToken = clientToken
|
|
494
|
-
self.hostedCheckoutsApi { success in
|
|
495
|
-
if success {
|
|
496
|
-
print("Hosted Checkout API call succeeded")
|
|
497
|
-
UserStoreSingleton.shared.price = String(self.amount ?? 0)
|
|
498
|
-
} else {
|
|
499
|
-
print("Hosted Checkout API call failed")
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
487
|
+
// else {
|
|
488
|
+
// if clientToken == nil {
|
|
489
|
+
// // Proceed with normal payment flow for API key/secret case
|
|
490
|
+
// self.paymentIntentApi { success in
|
|
491
|
+
// if success {
|
|
492
|
+
// print("Payment Intent API call succeeded")
|
|
493
|
+
// UserStoreSingleton.shared.price = String(self.amount ?? 0)
|
|
494
|
+
// print("Saved amount: \(UserStoreSingleton.shared.price ?? "No amount")")
|
|
495
|
+
// } else {
|
|
496
|
+
// print("Payment Intent API call failed")
|
|
497
|
+
// }
|
|
498
|
+
// }
|
|
499
|
+
// } else {
|
|
500
|
+
// // For clientToken case, directly call hostedCheckoutsApi
|
|
501
|
+
// UserStoreSingleton.shared.clientToken = clientToken
|
|
502
|
+
// self.hostedCheckoutsApi { success in
|
|
503
|
+
// if success {
|
|
504
|
+
// print("Hosted Checkout API call succeeded")
|
|
505
|
+
// UserStoreSingleton.shared.price = String(self.amount ?? 0)
|
|
506
|
+
// } else {
|
|
507
|
+
// print("Hosted Checkout API call failed")
|
|
508
|
+
// }
|
|
509
|
+
// }
|
|
510
|
+
// }
|
|
511
|
+
// }
|
|
504
512
|
|
|
505
513
|
if referenceID == true {
|
|
506
514
|
fetchReferenceData { response in
|
|
@@ -512,6 +520,136 @@ public final class Request: NSObject {
|
|
|
512
520
|
}
|
|
513
521
|
|
|
514
522
|
//MARK: - Payment Intent Api
|
|
523
|
+
// func paymentIntentApi(completion: @escaping (Bool) -> Void) {
|
|
524
|
+
// guard let serviceURL = URL(string: EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.paymentIntent.path()) else {
|
|
525
|
+
// Request.notifyValidationError("Invalid payment URL.")
|
|
526
|
+
// print("Invalid payment URL for Payment Intent API")
|
|
527
|
+
// completion(false)
|
|
528
|
+
// return
|
|
529
|
+
// }
|
|
530
|
+
//
|
|
531
|
+
// var request = URLRequest(url: serviceURL)
|
|
532
|
+
// request.httpMethod = "POST"
|
|
533
|
+
// request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
534
|
+
// request.addValue(EnvironmentConfig.apiKey ?? "", forHTTPHeaderField: "X-Api-Key")
|
|
535
|
+
// request.addValue(EnvironmentConfig.apiSecret ?? "", forHTTPHeaderField: "X-Api-Secret")
|
|
536
|
+
//
|
|
537
|
+
// // Recurring date validation
|
|
538
|
+
// if let startDateString = recurringStartDate,
|
|
539
|
+
// let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
|
|
540
|
+
// let today = Calendar.current.startOfDay(for: Date())
|
|
541
|
+
// let startDay = Calendar.current.startOfDay(for: startDate)
|
|
542
|
+
//
|
|
543
|
+
// if startDay < today {
|
|
544
|
+
// Request.notifyValidationError("The recurring start date cannot be in the past. Please select today or a future date.")
|
|
545
|
+
// print("Recurring start date validation failed")
|
|
546
|
+
// completion(false)
|
|
547
|
+
// return
|
|
548
|
+
// }
|
|
549
|
+
// } else if recurringStartDate != nil {
|
|
550
|
+
// Request.notifyValidationError("Recurring date format should be dd/MM/yyyy")
|
|
551
|
+
// print("Invalid recurring date format")
|
|
552
|
+
// completion(false)
|
|
553
|
+
// return
|
|
554
|
+
// }
|
|
555
|
+
//
|
|
556
|
+
// let params: [String: Any] = [
|
|
557
|
+
// "amount": ((amount ?? 0) * 100).rounded() / 100,
|
|
558
|
+
// "allowed_cycles": numOfCycle ?? 0,
|
|
559
|
+
// "intervals": recurringIntervals?.map { $0.rawValue } ?? [],
|
|
560
|
+
// "is_recurring": self.is_recurring ?? false,
|
|
561
|
+
// "recurring_start_date": recurringStartDate ?? "",
|
|
562
|
+
// "recurring_start_date_type": recurringStartDateType?.rawValue ?? ""
|
|
563
|
+
// ]
|
|
564
|
+
//
|
|
565
|
+
// print("Payment Intent API Request Params: \(params)")
|
|
566
|
+
//
|
|
567
|
+
// do {
|
|
568
|
+
// request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
|
|
569
|
+
// } catch {
|
|
570
|
+
// Request.notifyValidationError("Failed to encode Payment Intent API data: \(error.localizedDescription)")
|
|
571
|
+
// print("Error encoding Payment Intent API data: \(error)")
|
|
572
|
+
// completion(false)
|
|
573
|
+
// return
|
|
574
|
+
// }
|
|
575
|
+
//
|
|
576
|
+
// let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
577
|
+
// if let error = error {
|
|
578
|
+
// Request.notifyValidationError("Payment Intent API error: \(error.localizedDescription)")
|
|
579
|
+
// print("Payment Intent API error: \(error)")
|
|
580
|
+
// completion(false)
|
|
581
|
+
// return
|
|
582
|
+
// }
|
|
583
|
+
//
|
|
584
|
+
// guard let httpResponse = response as? HTTPURLResponse else {
|
|
585
|
+
// Request.notifyValidationError("Invalid response from Payment Intent API")
|
|
586
|
+
// print("Invalid response from Payment Intent API")
|
|
587
|
+
// completion(false)
|
|
588
|
+
// return
|
|
589
|
+
// }
|
|
590
|
+
//
|
|
591
|
+
// print("Payment Intent API Response Status Code: \(httpResponse.statusCode)")
|
|
592
|
+
//
|
|
593
|
+
// if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
|
|
594
|
+
// if let data = data {
|
|
595
|
+
// do {
|
|
596
|
+
// if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
|
597
|
+
// print("Payment Intent API Response: \(responseObject)")
|
|
598
|
+
// if let clientToken = responseObject["client_token"] as? String {
|
|
599
|
+
// UserStoreSingleton.shared.clientToken = clientToken
|
|
600
|
+
// print("Received clientToken: \(clientToken)")
|
|
601
|
+
// } else {
|
|
602
|
+
// Request.notifyValidationError("No client_token in Payment Intent API response")
|
|
603
|
+
// print("No client_token in Payment Intent API response")
|
|
604
|
+
// completion(false)
|
|
605
|
+
// return
|
|
606
|
+
// }
|
|
607
|
+
// if let paymentIntent = responseObject["payment_intent"] as? String {
|
|
608
|
+
// UserStoreSingleton.shared.paymentIntent = paymentIntent
|
|
609
|
+
// print("Received paymentIntent: \(paymentIntent)")
|
|
610
|
+
// }
|
|
611
|
+
// self.hostedCheckoutsApi { success in
|
|
612
|
+
// completion(success)
|
|
613
|
+
// }
|
|
614
|
+
// return
|
|
615
|
+
// } else {
|
|
616
|
+
// Request.notifyValidationError("Invalid response format from Payment Intent API")
|
|
617
|
+
// print("Invalid response format from Payment Intent API")
|
|
618
|
+
// completion(false)
|
|
619
|
+
// }
|
|
620
|
+
// } catch {
|
|
621
|
+
// Request.notifyValidationError("Failed to parse Payment Intent API response: \(error.localizedDescription)")
|
|
622
|
+
// print("Error parsing Payment Intent API response: \(error)")
|
|
623
|
+
// completion(false)
|
|
624
|
+
// }
|
|
625
|
+
// } else {
|
|
626
|
+
// Request.notifyValidationError("No response data received from Payment Intent API")
|
|
627
|
+
// print("No response data received from Payment Intent API")
|
|
628
|
+
// completion(false)
|
|
629
|
+
// }
|
|
630
|
+
// } else {
|
|
631
|
+
// // Default error message
|
|
632
|
+
// var message = "Payment Intent API failed with status code: \(httpResponse.statusCode)"
|
|
633
|
+
//
|
|
634
|
+
// if let data = data,
|
|
635
|
+
// let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
|
636
|
+
//
|
|
637
|
+
// // Prefer the "message" key from API response
|
|
638
|
+
// if let msg = responseObj["message"] as? String, !msg.isEmpty {
|
|
639
|
+
// message = "Payment Intent API error: \(msg)"
|
|
640
|
+
// }
|
|
641
|
+
// }
|
|
642
|
+
//
|
|
643
|
+
// // Send back the exact server error
|
|
644
|
+
// Request.notifyValidationError(message)
|
|
645
|
+
// print(message)
|
|
646
|
+
// completion(false)
|
|
647
|
+
// }
|
|
648
|
+
// }
|
|
649
|
+
// task.resume()
|
|
650
|
+
// }
|
|
651
|
+
|
|
652
|
+
// MARK: - Payment Intent Api
|
|
515
653
|
func paymentIntentApi(completion: @escaping (Bool) -> Void) {
|
|
516
654
|
guard let serviceURL = URL(string: EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.paymentIntent.path()) else {
|
|
517
655
|
Request.notifyValidationError("Invalid payment URL.")
|
|
@@ -527,8 +665,10 @@ public final class Request: NSObject {
|
|
|
527
665
|
request.addValue(EnvironmentConfig.apiSecret ?? "", forHTTPHeaderField: "X-Api-Secret")
|
|
528
666
|
|
|
529
667
|
// Recurring date validation
|
|
668
|
+
var apiStartDate = ""
|
|
530
669
|
if let startDateString = recurringStartDate,
|
|
531
670
|
let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
|
|
671
|
+
|
|
532
672
|
let today = Calendar.current.startOfDay(for: Date())
|
|
533
673
|
let startDay = Calendar.current.startOfDay(for: startDate)
|
|
534
674
|
|
|
@@ -538,6 +678,12 @@ public final class Request: NSObject {
|
|
|
538
678
|
completion(false)
|
|
539
679
|
return
|
|
540
680
|
}
|
|
681
|
+
|
|
682
|
+
// ✅ Convert dd/MM/yyyy -> MM/dd/yyyy for API
|
|
683
|
+
let apiFormatter = DateFormatter()
|
|
684
|
+
apiFormatter.dateFormat = "MM/dd/yyyy"
|
|
685
|
+
apiStartDate = apiFormatter.string(from: startDate)
|
|
686
|
+
|
|
541
687
|
} else if recurringStartDate != nil {
|
|
542
688
|
Request.notifyValidationError("Recurring date format should be dd/MM/yyyy")
|
|
543
689
|
print("Invalid recurring date format")
|
|
@@ -550,7 +696,7 @@ public final class Request: NSObject {
|
|
|
550
696
|
"allowed_cycles": numOfCycle ?? 0,
|
|
551
697
|
"intervals": recurringIntervals?.map { $0.rawValue } ?? [],
|
|
552
698
|
"is_recurring": self.is_recurring ?? false,
|
|
553
|
-
"recurring_start_date":
|
|
699
|
+
"recurring_start_date": apiStartDate, // ✅ Correct format for API
|
|
554
700
|
"recurring_start_date_type": recurringStartDateType?.rawValue ?? ""
|
|
555
701
|
]
|
|
556
702
|
|
|
@@ -587,6 +733,7 @@ public final class Request: NSObject {
|
|
|
587
733
|
do {
|
|
588
734
|
if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
|
589
735
|
print("Payment Intent API Response: \(responseObject)")
|
|
736
|
+
|
|
590
737
|
if let clientToken = responseObject["client_token"] as? String {
|
|
591
738
|
UserStoreSingleton.shared.clientToken = clientToken
|
|
592
739
|
print("Received clientToken: \(clientToken)")
|
|
@@ -596,10 +743,12 @@ public final class Request: NSObject {
|
|
|
596
743
|
completion(false)
|
|
597
744
|
return
|
|
598
745
|
}
|
|
746
|
+
|
|
599
747
|
if let paymentIntent = responseObject["payment_intent"] as? String {
|
|
600
748
|
UserStoreSingleton.shared.paymentIntent = paymentIntent
|
|
601
749
|
print("Received paymentIntent: \(paymentIntent)")
|
|
602
750
|
}
|
|
751
|
+
|
|
603
752
|
self.hostedCheckoutsApi { success in
|
|
604
753
|
completion(success)
|
|
605
754
|
}
|
|
@@ -620,14 +769,17 @@ public final class Request: NSObject {
|
|
|
620
769
|
completion(false)
|
|
621
770
|
}
|
|
622
771
|
} else {
|
|
772
|
+
// Default error message
|
|
623
773
|
var message = "Payment Intent API failed with status code: \(httpResponse.statusCode)"
|
|
774
|
+
|
|
624
775
|
if let data = data,
|
|
625
776
|
let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
|
|
626
777
|
let msg = responseObj["message"] as? String, !msg.isEmpty {
|
|
627
|
-
message = msg
|
|
778
|
+
message = "Payment Intent API error: \(msg)"
|
|
628
779
|
}
|
|
780
|
+
|
|
629
781
|
Request.notifyValidationError(message)
|
|
630
|
-
print(
|
|
782
|
+
print(message)
|
|
631
783
|
completion(false)
|
|
632
784
|
}
|
|
633
785
|
}
|
|
@@ -648,11 +800,22 @@ public final class Request: NSObject {
|
|
|
648
800
|
"status": false,
|
|
649
801
|
"message": message
|
|
650
802
|
]
|
|
651
|
-
let result = SDKResult(type: .error,
|
|
803
|
+
let result = SDKResult(type: .error, data: chargeData as NSDictionary)
|
|
652
804
|
NotificationCenter.default.post(name: NSNotification.Name("EasyPayResult"), object: result)
|
|
653
805
|
}
|
|
654
806
|
}
|
|
655
807
|
|
|
808
|
+
// MARK: - Clear cached values on token change
|
|
809
|
+
private func clearCachedValues() {
|
|
810
|
+
UserStoreSingleton.shared.amount = nil
|
|
811
|
+
UserStoreSingleton.shared.price = nil
|
|
812
|
+
UserStoreSingleton.shared.isRecurring = nil
|
|
813
|
+
UserStoreSingleton.shared.allowCycles = nil
|
|
814
|
+
UserStoreSingleton.shared.interval = nil
|
|
815
|
+
UserStoreSingleton.shared.startDateType = nil
|
|
816
|
+
UserStoreSingleton.shared.startDate = nil
|
|
817
|
+
}
|
|
818
|
+
|
|
656
819
|
// MARK: - Hosted Checkout API
|
|
657
820
|
func hostedCheckoutsApi(completion: @escaping (Bool) -> Void) {
|
|
658
821
|
// Build the URL using EnvironmentConfig
|
|
@@ -707,6 +870,18 @@ public final class Request: NSObject {
|
|
|
707
870
|
let dataObject = responseObject["data"] as? [String: Any] {
|
|
708
871
|
print("Hosted Checkout API Response: \(dataObject)")
|
|
709
872
|
|
|
873
|
+
if let paymentAmount = dataObject["payment_intent_amount"] as? Double {
|
|
874
|
+
// ✅ Update Request + Singleton with fresh value
|
|
875
|
+
self.amount = paymentAmount
|
|
876
|
+
UserStoreSingleton.shared.amount = String(paymentAmount)
|
|
877
|
+
UserStoreSingleton.shared.price = String(paymentAmount)
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
if let recurring = dataObject["is_recurring"] as? Bool {
|
|
881
|
+
self.is_recurring = recurring
|
|
882
|
+
UserStoreSingleton.shared.isRecurring = recurring ? "1" : "0"
|
|
883
|
+
}
|
|
884
|
+
|
|
710
885
|
// Persist the exact token used for the request (header value),
|
|
711
886
|
// not self.clientToken which may be nil on first-run flows.
|
|
712
887
|
UserStoreSingleton.shared.clientToken = token
|
|
@@ -790,7 +965,11 @@ public final class Request: NSObject {
|
|
|
790
965
|
if let isRecurring = recurringDetails["is_recurring"] {
|
|
791
966
|
UserStoreSingleton.shared.isRecurring = "\(isRecurring)"
|
|
792
967
|
print("Saved is_recurring: \(isRecurring)")
|
|
968
|
+
self.is_recurring = (UserStoreSingleton.shared.isRecurring == "1")
|
|
969
|
+
} else {
|
|
970
|
+
self.is_recurring = false
|
|
793
971
|
}
|
|
972
|
+
|
|
794
973
|
if let paymentIntentId = recurringDetails["payment_intent_id"] {
|
|
795
974
|
UserStoreSingleton.shared.paymentIntentId = "\(paymentIntentId)"
|
|
796
975
|
print("Saved payment_intent_id: \(paymentIntentId)")
|
|
@@ -803,8 +982,11 @@ public final class Request: NSObject {
|
|
|
803
982
|
UserStoreSingleton.shared.startDateType = "\(startDateType)"
|
|
804
983
|
print("Saved start_date_type: \(startDateType)")
|
|
805
984
|
}
|
|
985
|
+
} else {
|
|
986
|
+
self.is_recurring = false
|
|
987
|
+
UserStoreSingleton.shared.isRecurring = "0"
|
|
806
988
|
}
|
|
807
|
-
|
|
989
|
+
|
|
808
990
|
if self.appearanceSettings == nil, let appearanceSettings = dataObject["apperance_settings"] as? [String: Any] {
|
|
809
991
|
UserStoreSingleton.shared.body_bg_col = appearanceSettings["body_bg_col"] as? String
|
|
810
992
|
UserStoreSingleton.shared.border_radious = appearanceSettings["border_radious"] as? String
|
|
@@ -920,6 +1102,15 @@ extension DateFormatter {
|
|
|
920
1102
|
}()
|
|
921
1103
|
}
|
|
922
1104
|
|
|
1105
|
+
//extension DateFormatter {
|
|
1106
|
+
// static let recurringDateFormatter: DateFormatter = {
|
|
1107
|
+
// let formatter = DateFormatter()
|
|
1108
|
+
// formatter.dateFormat = "MM/dd/yyyy"
|
|
1109
|
+
// formatter.timeZone = .current
|
|
1110
|
+
// return formatter
|
|
1111
|
+
// }()
|
|
1112
|
+
//}
|
|
1113
|
+
|
|
923
1114
|
|
|
924
1115
|
|
|
925
1116
|
//extension UIApplication {
|
|
@@ -6,46 +6,53 @@
|
|
|
6
6
|
//
|
|
7
7
|
|
|
8
8
|
import UIKit
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
@objc
|
|
11
11
|
public enum ResultType: Int {
|
|
12
12
|
case cancelled
|
|
13
13
|
case success
|
|
14
14
|
case error
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
@objc
|
|
18
18
|
public final class SDKResult: NSObject {
|
|
19
19
|
|
|
20
20
|
@objc public let type: ResultType
|
|
21
|
-
@objc public let
|
|
22
|
-
@objc public let chargeData: [String: Any]?
|
|
21
|
+
@objc public let data: NSDictionary?
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
@objc public
|
|
23
|
+
// Computed properties for backward compatibility
|
|
24
|
+
@objc public var chargeData: [String: Any]? {
|
|
25
|
+
guard let data = data as? [String: Any] else { return nil }
|
|
26
|
+
|
|
27
|
+
// Extract everything except billingInfo and additionalInfo as chargeData
|
|
28
|
+
var chargeData: [String: Any] = [:]
|
|
29
|
+
for (key, value) in data {
|
|
30
|
+
if key != "billingInfo" && key != "additionalInfo" {
|
|
31
|
+
chargeData[key] = value
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return chargeData.isEmpty ? nil : chargeData
|
|
35
|
+
}
|
|
26
36
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
@objc public var billingInfo: [String: Any]? {
|
|
38
|
+
return data?["billingInfo"] as? [String: Any]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@objc public var additionalInfo: [String: Any]? {
|
|
42
|
+
return data?["additionalInfo"] as? [String: Any]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@objc public var error: NSError? {
|
|
46
|
+
// For backward compatibility, create NSError from data if type is error
|
|
47
|
+
guard type == .error, let data = data as? [String: Any] else { return nil }
|
|
48
|
+
let message = data["message"] as? String ?? "Unknown error"
|
|
49
|
+
return NSError(domain: "SDKResult", code: 0, userInfo: [NSLocalizedDescriptionKey: message])
|
|
35
50
|
}
|
|
36
51
|
|
|
37
|
-
// Initializer for
|
|
38
|
-
internal init(type: ResultType,
|
|
39
|
-
chargeData: [String: Any]? = nil,
|
|
40
|
-
billingInfo: [String: Any]? = nil,
|
|
41
|
-
additionalInfo: [String: Any]? = nil) {
|
|
52
|
+
// Initializer for all result types
|
|
53
|
+
internal init(type: ResultType, data: NSDictionary? = nil) {
|
|
42
54
|
self.type = type
|
|
43
|
-
self.
|
|
44
|
-
self.chargeData = chargeData
|
|
45
|
-
self.billingInfo = billingInfo
|
|
46
|
-
self.additionalInfo = additionalInfo
|
|
55
|
+
self.data = data
|
|
47
56
|
super.init()
|
|
48
57
|
}
|
|
49
58
|
}
|
|
50
|
-
|
|
51
|
-
|
|
@@ -320,8 +320,7 @@ class UserStoreSingleton: NSObject {
|
|
|
320
320
|
"payment_methods",
|
|
321
321
|
"bank_widget_key",
|
|
322
322
|
"vendor_id",
|
|
323
|
-
|
|
324
|
-
// "amount",
|
|
323
|
+
// "amount"
|
|
325
324
|
// "allowCycles",
|
|
326
325
|
// "interval",
|
|
327
326
|
// "isRecurring",
|
|
@@ -348,61 +347,61 @@ class UserStoreSingleton: NSObject {
|
|
|
348
347
|
|
|
349
348
|
}
|
|
350
349
|
|
|
351
|
-
var amount : String? {
|
|
352
|
-
get {
|
|
353
|
-
return (UserDefaults().object(forKey: "amount") as? String)
|
|
354
|
-
} set {
|
|
355
|
-
UserDefaults.standard.setValue(newValue, forKey: "amount")
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
var allowCycles : String? {
|
|
361
|
-
get {
|
|
362
|
-
return (UserDefaults().object(forKey: "allowCycles") as? String)
|
|
363
|
-
} set {
|
|
364
|
-
UserDefaults.standard.setValue(newValue, forKey: "allowCycles")
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
var interval : String? {
|
|
369
|
-
get {
|
|
370
|
-
return (UserDefaults().object(forKey: "interval") as? String)
|
|
371
|
-
} set {
|
|
372
|
-
UserDefaults.standard.setValue(newValue, forKey: "interval")
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
var isRecurring : String? {
|
|
377
|
-
get {
|
|
378
|
-
return (UserDefaults().object(forKey: "isRecurring") as? String)
|
|
379
|
-
} set {
|
|
380
|
-
UserDefaults.standard.setValue(newValue, forKey: "isRecurring")
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
var startDate : String? {
|
|
385
|
-
get {
|
|
386
|
-
return (UserDefaults().object(forKey: "startDate") as? String)
|
|
387
|
-
} set {
|
|
388
|
-
UserDefaults.standard.setValue(newValue, forKey: "startDate")
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
var startDateType : String? {
|
|
393
|
-
get {
|
|
394
|
-
return (UserDefaults().object(forKey: "startDateType") as? String)
|
|
395
|
-
} set {
|
|
396
|
-
UserDefaults.standard.setValue(newValue, forKey: "startDateType")
|
|
397
|
-
}
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
var paymentIntentId : String? {
|
|
401
|
-
get {
|
|
402
|
-
return (UserDefaults().object(forKey: "paymentIntentId") as? String)
|
|
403
|
-
} set {
|
|
404
|
-
UserDefaults.standard.setValue(newValue, forKey: "paymentIntentId")
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
|
|
350
|
+
//var amount : String? {
|
|
351
|
+
// get {
|
|
352
|
+
// return (UserDefaults().object(forKey: "amount") as? String)
|
|
353
|
+
// } set {
|
|
354
|
+
// UserDefaults.standard.setValue(newValue, forKey: "amount")
|
|
355
|
+
// }
|
|
356
|
+
//}
|
|
357
|
+
//
|
|
358
|
+
////Recurring params
|
|
359
|
+
//var allowCycles : String? {
|
|
360
|
+
// get {
|
|
361
|
+
// return (UserDefaults().object(forKey: "allowCycles") as? String)
|
|
362
|
+
// } set {
|
|
363
|
+
// UserDefaults.standard.setValue(newValue, forKey: "allowCycles")
|
|
364
|
+
// }
|
|
365
|
+
//}
|
|
366
|
+
//
|
|
367
|
+
//var interval : String? {
|
|
368
|
+
// get {
|
|
369
|
+
// return (UserDefaults().object(forKey: "interval") as? String)
|
|
370
|
+
// } set {
|
|
371
|
+
// UserDefaults.standard.setValue(newValue, forKey: "interval")
|
|
372
|
+
// }
|
|
373
|
+
//}
|
|
374
|
+
//
|
|
375
|
+
//var isRecurring : String? {
|
|
376
|
+
// get {
|
|
377
|
+
// return (UserDefaults().object(forKey: "isRecurring") as? String)
|
|
378
|
+
// } set {
|
|
379
|
+
// UserDefaults.standard.setValue(newValue, forKey: "isRecurring")
|
|
380
|
+
// }
|
|
381
|
+
//}
|
|
382
|
+
//
|
|
383
|
+
//var startDate : String? {
|
|
384
|
+
// get {
|
|
385
|
+
// return (UserDefaults().object(forKey: "startDate") as? String)
|
|
386
|
+
// } set {
|
|
387
|
+
// UserDefaults.standard.setValue(newValue, forKey: "startDate")
|
|
388
|
+
// }
|
|
389
|
+
//}
|
|
390
|
+
//
|
|
391
|
+
//var startDateType : String? {
|
|
392
|
+
// get {
|
|
393
|
+
// return (UserDefaults().object(forKey: "startDateType") as? String)
|
|
394
|
+
// } set {
|
|
395
|
+
// UserDefaults.standard.setValue(newValue, forKey: "startDateType")
|
|
396
|
+
// }
|
|
397
|
+
//}
|
|
398
|
+
//
|
|
399
|
+
//var paymentIntentId : String? {
|
|
400
|
+
// get {
|
|
401
|
+
// return (UserDefaults().object(forKey: "paymentIntentId") as? String)
|
|
402
|
+
// } set {
|
|
403
|
+
// UserDefaults.standard.setValue(newValue, forKey: "paymentIntentId")
|
|
404
|
+
// }
|
|
405
|
+
//}
|
|
406
|
+
//
|
|
407
|
+
//
|