@jimrising/easymerchantsdk-react-native 1.3.4 → 1.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -4
- package/android/.gradle/8.10/checksums/checksums.lock +0 -0
- package/android/.gradle/8.10/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.10/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.10/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.10/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.10/gc.properties +0 -0
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/nb-cache/trust/0B5D6BE682AD6AEE9815EC13516BF075752CAE5AD5BECDCC00315C37622C2FD3 +1 -0
- package/android/.gradle/nb-cache/trust/23843E1876B2E51C07E80AB52D1E797E5D8053D8097EEEB15FB63DD903195C14 +1 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/.settings/org.eclipse.buildship.core.prefs +2 -0
- package/ios/Classes/EasyMerchantSdk.m +43 -28
- package/ios/Classes/EasyMerchantSdk.swift +68 -9
- package/ios/CustomComponents/PlanSelector.swift +28 -30
- package/ios/EnvironmentConfig.swift +30 -30
- package/ios/Example/ViewController.swift +47 -51
- package/ios/Models/AdditionalInfo.swift +43 -6
- package/ios/Models/BillingInfo.swift +50 -6
- package/ios/Models/RecurringIntervals.swift +34 -0
- package/ios/Models/RecurringStartDateType.swift +13 -0
- package/ios/Models/Request.swift +120 -11
- package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +609 -79
- package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +72 -25
- package/ios/Pods/ViewControllers/EmailVerificationVC.swift +14 -0
- package/ios/Pods/ViewControllers/OTPVerificationVC.swift +459 -42
- package/ios/Pods/ViewControllers/PaymentDoneVC.swift +16 -2
- package/ios/Pods/ViewControllers/PaymentErrorVC.swift +0 -2
- package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +1553 -372
- package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.swift +6 -2
- package/ios/Pods/ViewControllers/PaymentInformation/SavedCardsTVC/SavedCardsTVC.swift +6 -1
- package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +105 -0
- package/ios/easymerchantsdk.podspec +1 -1
- package/ios/easymerchantsdk.storyboard +554 -57
- package/package.json +2 -2
- package/.idea/caches/deviceStreaming.xml +0 -571
- package/.idea/em-MobileCheckoutSDK-ReactNative.iml +0 -9
- package/.idea/misc.xml +0 -5
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
1
|
//import UIKit
|
|
4
2
|
//import EasyPay
|
|
5
3
|
//
|
|
@@ -28,53 +26,51 @@
|
|
|
28
26
|
// }
|
|
29
27
|
//
|
|
30
28
|
// @IBAction private func payAction() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
34
|
-
// let apiKey = "14fbf8a186091763e59c289c1"
|
|
35
|
-
// let apiSecret = "f90863e7a853539f8ace8d6de"
|
|
29
|
+
// let apiKey = "14fbf8a186091763e59c289c1"
|
|
30
|
+
// let apiSecret = "f90863e7a853539f8ace8d6de"
|
|
36
31
|
//
|
|
37
32
|
// EasyPay.EnvironmentConfig.configure(apiKey: apiKey, apiSecret: apiSecret)
|
|
38
33
|
//
|
|
39
|
-
//
|
|
34
|
+
//
|
|
40
35
|
// let themeConfiguration = ThemeConfiguration(
|
|
41
|
-
// bodyBackgroundColor: "#
|
|
42
|
-
// containerBackgroundColor: "#
|
|
43
|
-
// primaryFontColor: "#
|
|
44
|
-
// secondaryFontColor: "#
|
|
45
|
-
// primaryButtonBackgroundColor: "#
|
|
46
|
-
// primaryButtonHoverColor: "#
|
|
47
|
-
// primaryButtonFontColor: "#FFFFFF",
|
|
48
|
-
// secondaryButtonBackgroundColor: "#
|
|
49
|
-
// secondaryButtonHoverColor: "#
|
|
50
|
-
// secondaryButtonFontColor: "#
|
|
36
|
+
// bodyBackgroundColor: "#1F2937", // dark gray-blue
|
|
37
|
+
// containerBackgroundColor: "#374151", // darker container
|
|
38
|
+
// primaryFontColor: "#F9FAFB", // near white
|
|
39
|
+
// secondaryFontColor: "#D1D5DB", // light gray
|
|
40
|
+
// primaryButtonBackgroundColor: "#4F46E5", // indigo (keep for contrast)
|
|
41
|
+
// primaryButtonHoverColor: "#4338CA", // deeper indigo
|
|
42
|
+
// primaryButtonFontColor: "#FFFFFF", // white text on button
|
|
43
|
+
// secondaryButtonBackgroundColor: "#1E40AF", // dark blue
|
|
44
|
+
// secondaryButtonHoverColor: "#1E3A8A", // deeper blue on hover
|
|
45
|
+
// secondaryButtonFontColor: "#E0E7FF", // soft blue-white
|
|
51
46
|
// borderRadius: "8",
|
|
52
47
|
// fontSize: "14"
|
|
53
48
|
// )
|
|
54
49
|
//
|
|
55
|
-
// let
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
// let
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
50
|
+
// let additionalInfo = AdditionalInfo(
|
|
51
|
+
// name: "Test User",
|
|
52
|
+
// email: "test@gmail.com",
|
|
53
|
+
// phone_number: "9465351125",
|
|
54
|
+
// country_code: "91",
|
|
55
|
+
// description: "Test"
|
|
56
|
+
// )
|
|
57
|
+
//
|
|
58
|
+
// let billingInfo = BillingInfo(
|
|
59
|
+
// address: "Mohali, Punjab",
|
|
60
|
+
// country: "India",
|
|
61
|
+
// state: "Punjab",
|
|
62
|
+
// city: "Anandpur Sahib",
|
|
63
|
+
// postal_code: "140118",
|
|
64
|
+
// additional_info: additionalInfo
|
|
65
|
+
// )
|
|
66
|
+
//
|
|
67
|
+
// // Encode Billing Info to Data
|
|
68
|
+
// guard let billingData = try? JSONEncoder().encode(billingInfo) else {
|
|
69
|
+
// print("Failed to encode BillingInfo")
|
|
74
70
|
// return
|
|
75
71
|
// }
|
|
76
72
|
//
|
|
77
|
-
// let authenticatedACH =
|
|
73
|
+
// let authenticatedACH = false
|
|
78
74
|
//
|
|
79
75
|
// let grailPayParams = GrailPayRequest(
|
|
80
76
|
// accessToken: "251|uTijpDGfrS88UR2V1cZNMQ8S4hUJA0sVzsnsoUZF",
|
|
@@ -89,15 +85,20 @@
|
|
|
89
85
|
//
|
|
90
86
|
// let request = EasyPay.Request(
|
|
91
87
|
// amount: 99,
|
|
92
|
-
// billingInfoData:
|
|
93
|
-
// paymentMethods: [.Card, .Bank
|
|
88
|
+
// billingInfoData: billingData,
|
|
89
|
+
// paymentMethods: [.Card, .Bank],
|
|
94
90
|
// themeConfiguration: themeConfiguration,
|
|
95
91
|
// tokenOnly: false,
|
|
96
92
|
// saveCard: false,
|
|
97
93
|
// saveAccount: false,
|
|
98
94
|
// submitButtonText: "Submit",
|
|
99
95
|
// authenticatedACH: authenticatedACH,
|
|
100
|
-
// grailPayParams: authenticatedACH ? grailPayParams : nil
|
|
96
|
+
// grailPayParams: authenticatedACH ? grailPayParams : nil,
|
|
97
|
+
// is_recurring: true,
|
|
98
|
+
// recurringIntervals: [.weekly, .monthly],
|
|
99
|
+
// recurringStartDateType: .custom,
|
|
100
|
+
// recurringStartDate: "05/30/2025", /// Format MM/dd/yyyy, must be today or future date
|
|
101
|
+
// enable3DS: true
|
|
101
102
|
// )
|
|
102
103
|
//
|
|
103
104
|
// if request.tokenOnly == true {
|
|
@@ -120,6 +121,11 @@
|
|
|
120
121
|
// switch result.type {
|
|
121
122
|
// case .cancelled:
|
|
122
123
|
// print("Cancelled")
|
|
124
|
+
// lblResponseShow.isHidden = false
|
|
125
|
+
// if let message = result.chargeData?["message"] as? String {
|
|
126
|
+
// print("Message from chargeData: \(message)")
|
|
127
|
+
// lblResponseShow.text = message
|
|
128
|
+
// }
|
|
123
129
|
// case .success:
|
|
124
130
|
// if let chargeData = result.chargeData {
|
|
125
131
|
// if let clientToken = chargeData["clientToken"] as? String {
|
|
@@ -148,13 +154,3 @@
|
|
|
148
154
|
//
|
|
149
155
|
//}
|
|
150
156
|
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
155
|
-
//
|
|
156
|
-
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
//
|
|
@@ -7,10 +7,47 @@
|
|
|
7
7
|
|
|
8
8
|
import Foundation
|
|
9
9
|
|
|
10
|
-
struct AdditionalInfo {
|
|
11
|
-
let name: String
|
|
12
|
-
let email: String
|
|
13
|
-
let phone: String
|
|
14
|
-
let description: String
|
|
15
|
-
}
|
|
10
|
+
//struct AdditionalInfo {
|
|
11
|
+
// let name: String
|
|
12
|
+
// let email: String
|
|
13
|
+
// let phone: String
|
|
14
|
+
// let description: String
|
|
15
|
+
//}
|
|
16
|
+
|
|
17
|
+
//public struct AdditionalInfo: Codable {
|
|
18
|
+
// public let name: String
|
|
19
|
+
// public let email: String
|
|
20
|
+
// public let phone_number: String
|
|
21
|
+
// public let country_code: String
|
|
22
|
+
// public let description: String
|
|
23
|
+
//
|
|
24
|
+
// public init(name: String, email: String, phone_number: String, country_code: String, description: String) {
|
|
25
|
+
// self.name = name
|
|
26
|
+
// self.email = email
|
|
27
|
+
// self.phone_number = phone_number
|
|
28
|
+
// self.country_code = country_code
|
|
29
|
+
// self.description = description
|
|
30
|
+
// }
|
|
31
|
+
//}
|
|
16
32
|
|
|
33
|
+
public struct AdditionalInfo: Codable {
|
|
34
|
+
public let name: String?
|
|
35
|
+
public let email: String?
|
|
36
|
+
public let phone_number: String?
|
|
37
|
+
public let country_code: String?
|
|
38
|
+
public let description: String?
|
|
39
|
+
|
|
40
|
+
public init(
|
|
41
|
+
name: String? = nil,
|
|
42
|
+
email: String? = nil,
|
|
43
|
+
phone_number: String? = nil,
|
|
44
|
+
country_code: String? = nil,
|
|
45
|
+
description: String? = nil
|
|
46
|
+
) {
|
|
47
|
+
self.name = name
|
|
48
|
+
self.email = email
|
|
49
|
+
self.phone_number = phone_number
|
|
50
|
+
self.country_code = country_code
|
|
51
|
+
self.description = description
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -7,10 +7,54 @@
|
|
|
7
7
|
|
|
8
8
|
import Foundation
|
|
9
9
|
|
|
10
|
-
struct BillingInfo {
|
|
11
|
-
let address: String
|
|
12
|
-
let country: String
|
|
13
|
-
let state: String
|
|
14
|
-
let city: String
|
|
15
|
-
let postalCode: String
|
|
10
|
+
//struct BillingInfo {
|
|
11
|
+
// let address: String
|
|
12
|
+
// let country: String
|
|
13
|
+
// let state: String
|
|
14
|
+
// let city: String
|
|
15
|
+
// let postalCode: String
|
|
16
|
+
//}
|
|
17
|
+
|
|
18
|
+
//public struct BillingInfo: Codable {
|
|
19
|
+
// public let address: String
|
|
20
|
+
// public let country: String
|
|
21
|
+
// public let state: String
|
|
22
|
+
// public let city: String
|
|
23
|
+
// public let postal_code: String
|
|
24
|
+
// public let additional_info: AdditionalInfo
|
|
25
|
+
//
|
|
26
|
+
// public init(address: String, country: String, state: String, city: String, postal_code: String, additional_info: AdditionalInfo) {
|
|
27
|
+
// self.address = address
|
|
28
|
+
// self.country = country
|
|
29
|
+
// self.state = state
|
|
30
|
+
// self.city = city
|
|
31
|
+
// self.postal_code = postal_code
|
|
32
|
+
// self.additional_info = additional_info
|
|
33
|
+
// }
|
|
34
|
+
//}
|
|
35
|
+
|
|
36
|
+
public struct BillingInfo: Codable {
|
|
37
|
+
public let address: String?
|
|
38
|
+
public let country: String?
|
|
39
|
+
public let state: String?
|
|
40
|
+
public let city: String?
|
|
41
|
+
public let postal_code: String?
|
|
42
|
+
public let additional_info: AdditionalInfo?
|
|
43
|
+
|
|
44
|
+
public init(
|
|
45
|
+
address: String? = nil,
|
|
46
|
+
country: String? = nil,
|
|
47
|
+
state: String? = nil,
|
|
48
|
+
city: String? = nil,
|
|
49
|
+
postal_code: String? = nil,
|
|
50
|
+
additional_info: AdditionalInfo? = nil
|
|
51
|
+
) {
|
|
52
|
+
self.address = address
|
|
53
|
+
self.country = country
|
|
54
|
+
self.state = state
|
|
55
|
+
self.city = city
|
|
56
|
+
self.postal_code = postal_code
|
|
57
|
+
self.additional_info = additional_info
|
|
58
|
+
}
|
|
16
59
|
}
|
|
60
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
// RecurringIntervals.swift
|
|
3
|
+
// EasyPay
|
|
4
|
+
//
|
|
5
|
+
// Created by Mony's Mac on 22/05/25.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
public enum RecurringIntervals: String, CaseIterable {
|
|
11
|
+
case daily = "daily"
|
|
12
|
+
case weekly = "weekly"
|
|
13
|
+
case monthly = "monthly"
|
|
14
|
+
case quarterly = "quarterly"
|
|
15
|
+
case halfYearly = "halfyearly"
|
|
16
|
+
case yearly = "yearly"
|
|
17
|
+
case everyTwoYears = "everytwoyears"
|
|
18
|
+
case everyThreeYears = "everythreeyears"
|
|
19
|
+
case everyFourYears = "everyfouryears"
|
|
20
|
+
case everyFiveYears = "everyfiveyears"
|
|
21
|
+
|
|
22
|
+
var displayName: String {
|
|
23
|
+
switch self {
|
|
24
|
+
case .halfYearly: return "Half Yearly"
|
|
25
|
+
case .everyTwoYears: return "Every Two Years"
|
|
26
|
+
case .everyThreeYears: return "Every Three Years"
|
|
27
|
+
case .everyFourYears: return "Every Four Years"
|
|
28
|
+
case .everyFiveYears: return "Every Five Years"
|
|
29
|
+
default: return rawValue.capitalized
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
package/ios/Models/Request.swift
CHANGED
|
@@ -20,7 +20,7 @@ public struct ThemeConfiguration: Codable {
|
|
|
20
20
|
public let secondaryButtonFontColor: String?
|
|
21
21
|
public let borderRadius: String?
|
|
22
22
|
public let fontSize: String?
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
public init(
|
|
25
25
|
bodyBackgroundColor: String? = nil,
|
|
26
26
|
containerBackgroundColor: String? = nil,
|
|
@@ -59,7 +59,7 @@ public struct GrailPayRequest: Codable {
|
|
|
59
59
|
public let brandingName: String
|
|
60
60
|
public let finderSubtitle: String
|
|
61
61
|
public let searchPlaceholder: String
|
|
62
|
-
|
|
62
|
+
|
|
63
63
|
public init(
|
|
64
64
|
accessToken: String,
|
|
65
65
|
vendorId: String,
|
|
@@ -75,9 +75,9 @@ public struct GrailPayRequest: Codable {
|
|
|
75
75
|
self.role = role
|
|
76
76
|
self.timeout = timeout
|
|
77
77
|
self.isSandbox = isSandbox
|
|
78
|
-
self.brandingName = brandingName
|
|
79
|
-
self.finderSubtitle = finderSubtitle
|
|
80
|
-
self.searchPlaceholder = searchPlaceholder
|
|
78
|
+
self.brandingName = brandingName
|
|
79
|
+
self.finderSubtitle = finderSubtitle
|
|
80
|
+
self.searchPlaceholder = searchPlaceholder
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -95,7 +95,11 @@ public final class Request: NSObject {
|
|
|
95
95
|
public let submitButtonText: String?
|
|
96
96
|
public let authenticatedACH: Bool?
|
|
97
97
|
public let grailPayParams: GrailPayRequest?
|
|
98
|
-
public
|
|
98
|
+
public var is_recurring: Bool?
|
|
99
|
+
public var recurringIntervals: [RecurringIntervals]?
|
|
100
|
+
public var recurringStartDateType: RecurringStartDateType?
|
|
101
|
+
public var recurringStartDate: String?
|
|
102
|
+
public let enable3DS: Bool?
|
|
99
103
|
|
|
100
104
|
public init(
|
|
101
105
|
amount: Double,
|
|
@@ -108,7 +112,11 @@ public final class Request: NSObject {
|
|
|
108
112
|
submitButtonText: String? = nil,
|
|
109
113
|
authenticatedACH: Bool = false,
|
|
110
114
|
grailPayParams: GrailPayRequest? = nil,
|
|
111
|
-
|
|
115
|
+
is_recurring: Bool = false,
|
|
116
|
+
recurringIntervals: [RecurringIntervals]? = nil,
|
|
117
|
+
recurringStartDateType: RecurringStartDateType? = nil,
|
|
118
|
+
recurringStartDate: String? = nil,
|
|
119
|
+
enable3DS: Bool = false
|
|
112
120
|
) {
|
|
113
121
|
self.amount = amount
|
|
114
122
|
self.billingInfoData = billingInfoData
|
|
@@ -119,7 +127,24 @@ public final class Request: NSObject {
|
|
|
119
127
|
self.submitButtonText = submitButtonText
|
|
120
128
|
self.authenticatedACH = authenticatedACH
|
|
121
129
|
self.grailPayParams = authenticatedACH ? grailPayParams : nil
|
|
122
|
-
self.
|
|
130
|
+
self.is_recurring = is_recurring
|
|
131
|
+
self.recurringIntervals = recurringIntervals
|
|
132
|
+
self.recurringStartDateType = recurringStartDateType
|
|
133
|
+
self.recurringStartDate = recurringStartDate
|
|
134
|
+
self.enable3DS = enable3DS
|
|
135
|
+
|
|
136
|
+
// Conditionally assign recurring fields only if is_recurring == true
|
|
137
|
+
if is_recurring {
|
|
138
|
+
self.is_recurring = true
|
|
139
|
+
self.recurringIntervals = recurringIntervals
|
|
140
|
+
self.recurringStartDateType = recurringStartDateType
|
|
141
|
+
self.recurringStartDate = recurringStartDate
|
|
142
|
+
} else {
|
|
143
|
+
self.is_recurring = false
|
|
144
|
+
self.recurringIntervals = nil
|
|
145
|
+
self.recurringStartDateType = nil
|
|
146
|
+
self.recurringStartDate = nil
|
|
147
|
+
}
|
|
123
148
|
|
|
124
149
|
if let paymentMethods = paymentMethods {
|
|
125
150
|
self.selectedPaymentMethods = paymentMethods
|
|
@@ -171,8 +196,6 @@ public final class Request: NSObject {
|
|
|
171
196
|
|
|
172
197
|
//MARK: - Payment Intent Api
|
|
173
198
|
func paymentIntentApi(completion: @escaping (Bool) -> Void) {
|
|
174
|
-
// Start loader when API call starts
|
|
175
|
-
|
|
176
199
|
guard let serviceURL = URL(string: EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.paymentIntent.path()) else {
|
|
177
200
|
print("Invalid URL")
|
|
178
201
|
completion(false)
|
|
@@ -185,11 +208,47 @@ public final class Request: NSObject {
|
|
|
185
208
|
request.addValue(EnvironmentConfig.apiKey ?? "", forHTTPHeaderField: "X-Api-Key")
|
|
186
209
|
request.addValue(EnvironmentConfig.apiSecret ?? "", forHTTPHeaderField: "X-Api-Secret")
|
|
187
210
|
|
|
211
|
+
// Check if recurringStartDate is not in the past
|
|
212
|
+
if let startDateString = recurringStartDate,
|
|
213
|
+
let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
|
|
214
|
+
|
|
215
|
+
let today = Calendar.current.startOfDay(for: Date())
|
|
216
|
+
let startDay = Calendar.current.startOfDay(for: startDate)
|
|
217
|
+
|
|
218
|
+
if startDay < today {
|
|
219
|
+
DispatchQueue.main.async {
|
|
220
|
+
if let topVC = UIApplication.topViewController() {
|
|
221
|
+
let alert = UIAlertController(title: "Invalid Date",
|
|
222
|
+
message: "The recurring start date cannot be in the past. Please select today or a future date.",
|
|
223
|
+
preferredStyle: .alert)
|
|
224
|
+
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { _ in
|
|
225
|
+
if let easyPayVC = UIApplication.findEasyPayViewController(from: topVC) {
|
|
226
|
+
easyPayVC.dismiss(animated: true)
|
|
227
|
+
} else {
|
|
228
|
+
// fallback: dismiss topVC itself if it's presented modally
|
|
229
|
+
topVC.dismiss(animated: true)
|
|
230
|
+
}
|
|
231
|
+
}))
|
|
232
|
+
topVC.present(alert, animated: true)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
completion(false)
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
188
241
|
let params: [String: Any] = [
|
|
189
242
|
"amount": amount,
|
|
243
|
+
"allowed_cycles": String(recurringIntervals?.count ?? 0),
|
|
244
|
+
"intervals": recurringIntervals?.map { $0.rawValue } ?? [],
|
|
245
|
+
"is_recurring": self.is_recurring ?? false,
|
|
246
|
+
"recurring_start_date": recurringStartDate ?? "",
|
|
247
|
+
"recurring_start_date_type": recurringStartDateType?.rawValue ?? ""
|
|
190
248
|
]
|
|
191
249
|
|
|
192
250
|
do {
|
|
251
|
+
|
|
193
252
|
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
|
|
194
253
|
} catch {
|
|
195
254
|
print("Error creating JSON data: \(error)")
|
|
@@ -240,7 +299,14 @@ public final class Request: NSObject {
|
|
|
240
299
|
completion(false)
|
|
241
300
|
}
|
|
242
301
|
} else {
|
|
243
|
-
|
|
302
|
+
if let data = data,
|
|
303
|
+
let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
|
|
304
|
+
let message = responseObj["message"] as? String {
|
|
305
|
+
print(message)
|
|
306
|
+
} else {
|
|
307
|
+
print("HTTP Status Code: \(httpResponse.statusCode)")
|
|
308
|
+
}
|
|
309
|
+
|
|
244
310
|
completion(false)
|
|
245
311
|
}
|
|
246
312
|
}
|
|
@@ -375,3 +441,46 @@ public final class Request: NSObject {
|
|
|
375
441
|
}
|
|
376
442
|
|
|
377
443
|
}
|
|
444
|
+
|
|
445
|
+
extension DateFormatter {
|
|
446
|
+
static let recurringDateFormatter: DateFormatter = {
|
|
447
|
+
let formatter = DateFormatter()
|
|
448
|
+
formatter.dateFormat = "MM/dd/yyyy"
|
|
449
|
+
formatter.timeZone = .current
|
|
450
|
+
return formatter
|
|
451
|
+
}()
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
extension UIApplication {
|
|
455
|
+
static func topViewController(base: UIViewController? = UIApplication.shared.connectedScenes
|
|
456
|
+
.compactMap { ($0 as? UIWindowScene)?.windows.first(where: \.isKeyWindow) }
|
|
457
|
+
.first?.rootViewController) -> UIViewController? {
|
|
458
|
+
if let nav = base as? UINavigationController {
|
|
459
|
+
return topViewController(base: nav.visibleViewController)
|
|
460
|
+
}
|
|
461
|
+
if let tab = base as? UITabBarController {
|
|
462
|
+
if let selected = tab.selectedViewController {
|
|
463
|
+
return topViewController(base: selected)
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
if let presented = base?.presentedViewController {
|
|
467
|
+
return topViewController(base: presented)
|
|
468
|
+
}
|
|
469
|
+
return base
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
extension UIApplication {
|
|
474
|
+
// Recursively find the presented EasyPayViewController (if any)
|
|
475
|
+
static func findEasyPayViewController(from vc: UIViewController?) -> EasyPayViewController? {
|
|
476
|
+
if let easyPayVC = vc as? EasyPayViewController {
|
|
477
|
+
return easyPayVC
|
|
478
|
+
}
|
|
479
|
+
if let presented = vc?.presentedViewController {
|
|
480
|
+
return findEasyPayViewController(from: presented)
|
|
481
|
+
}
|
|
482
|
+
return nil
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
|