@jimrising/easymerchantsdk-react-native 2.5.2 → 2.5.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.
- package/android/build.gradle +1 -1
- package/ios/ApiManager/APIHeaders.swift +0 -6
- package/ios/ApiManager/APIRequest.swift +3 -8
- package/ios/Classes/EasyMerchantSdk.m +2 -2
- package/ios/Classes/EasyMerchantSdk.swift +76 -17
- package/ios/Helper/GrailPayHelper.swift +1 -0
- package/ios/Models/Request.swift +3 -3
- package/ios/Pods/Storyboard/EasyPaySdk.storyboard +83 -83
- package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +26 -3
- package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +10 -10
- package/ios/Pods/ViewControllers/GrailPayVC.swift +260 -268
- package/ios/Pods/ViewControllers/OTPVerificationVC.swift +74 -13
- package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +259 -124
- package/ios/Pods/ViewControllers/PaymentInformation/RecurringTVC.swift +3 -0
- package/ios/Pods/ViewControllers/PaymentStatusWebViewVC.swift +1 -32
- package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +10 -6
- package/ios/easymerchantsdk.podspec +1 -1
- package/package.json +1 -1
- package/ACH_CHARGE_ENDPOINT_TRACE.md +0 -69
package/android/build.gradle
CHANGED
|
@@ -96,7 +96,7 @@ dependencies {
|
|
|
96
96
|
implementation 'com.google.android.material:material:1.13.0'
|
|
97
97
|
|
|
98
98
|
// Third-party libs
|
|
99
|
-
implementation 'com.app:paysdk:1.
|
|
99
|
+
implementation 'com.app:paysdk:1.7.0'
|
|
100
100
|
implementation 'com.hbb20:ccp:2.7.3'
|
|
101
101
|
implementation 'com.github.bumptech.glide:glide:5.0.4'
|
|
102
102
|
implementation 'com.github.androidmads:QRGenerator:1.0.5'
|
|
@@ -22,12 +22,6 @@ struct APIHeaders {
|
|
|
22
22
|
return ["Customer-Token": token]
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
/// For verify_otp only: match Android — header "Customer-Token" (Pascal case), no Client-Token, no X-Api-Key/Secret
|
|
26
|
-
static func verifyOtpHeaders() -> [String: String] {
|
|
27
|
-
guard let token = UserStoreSingleton.shared.customerToken else { return [:] }
|
|
28
|
-
return ["Customer-Token": token]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
25
|
/// API key/secret headers (match Android SDK: X-Api-Key, X-Api-Secret)
|
|
32
26
|
static func apiAuthHeaders() -> [String: String] {
|
|
33
27
|
guard let key = EnvironmentConfig.apiKey,
|
|
@@ -29,14 +29,9 @@ struct APIRequest {
|
|
|
29
29
|
|
|
30
30
|
// Combine default headers with passed-in headers
|
|
31
31
|
var allHeaders = APIHeaders.commonHeaders()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} else {
|
|
36
|
-
allHeaders.merge(APIHeaders.clientTokenHeader(), uniquingKeysWith: { $1 })
|
|
37
|
-
allHeaders.merge(APIHeaders.customerTokenHeader(), uniquingKeysWith: { $1 })
|
|
38
|
-
allHeaders.merge(APIHeaders.apiAuthHeaders(), uniquingKeysWith: { $1 })
|
|
39
|
-
}
|
|
32
|
+
allHeaders.merge(APIHeaders.clientTokenHeader(), uniquingKeysWith: { $1 })
|
|
33
|
+
allHeaders.merge(APIHeaders.customerTokenHeader(), uniquingKeysWith: { $1 })
|
|
34
|
+
allHeaders.merge(APIHeaders.apiAuthHeaders(), uniquingKeysWith: { $1 })
|
|
40
35
|
allHeaders.merge(headers, uniquingKeysWith: { $1 }) // override if needed
|
|
41
36
|
|
|
42
37
|
// Apply to request
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
#import <React/RCTLog.h>
|
|
3
3
|
#import <React/RCTBridgeModule.h>
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
//#import "easymerchantsdk-Swift.h"
|
|
6
|
+
#import <easymerchantsdk/easymerchantsdk-Swift.h>
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
@interface EasyMerchantSdk ()
|
|
@@ -84,8 +84,8 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
|
|
|
84
84
|
return
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
guard let presentingVC =
|
|
88
|
-
reject("NO_VIEW_CONTROLLER", "Unable to find a
|
|
87
|
+
guard let (presentingVC, toDismiss) = presentingViewControllerAndOptionalDismiss() else {
|
|
88
|
+
reject("NO_VIEW_CONTROLLER", "Unable to find a view controller in the window hierarchy", nil)
|
|
89
89
|
clearCallbacks()
|
|
90
90
|
return
|
|
91
91
|
}
|
|
@@ -98,8 +98,8 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
let controller = EasyPayViewController(request: request, delegate: self)
|
|
101
|
-
DispatchQueue.main.async {
|
|
102
|
-
|
|
101
|
+
DispatchQueue.main.async { [weak self] in
|
|
102
|
+
self?.presentPaymentController(controller, from: presentingVC, dismissFirst: toDismiss)
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -117,15 +117,15 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
|
|
|
117
117
|
return
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
guard let presentingVC =
|
|
121
|
-
reject("NO_VIEW_CONTROLLER", "Unable to find a
|
|
120
|
+
guard let (presentingVC, toDismiss) = presentingViewControllerAndOptionalDismiss() else {
|
|
121
|
+
reject("NO_VIEW_CONTROLLER", "Unable to find a view controller in the window hierarchy", nil)
|
|
122
122
|
clearCallbacks()
|
|
123
123
|
return
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
let controller = EasyPayViewController(request: request, delegate: self)
|
|
127
|
-
DispatchQueue.main.async {
|
|
128
|
-
|
|
127
|
+
DispatchQueue.main.async { [weak self] in
|
|
128
|
+
self?.presentPaymentController(controller, from: presentingVC, dismissFirst: toDismiss)
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
131
|
|
|
@@ -145,16 +145,75 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
|
|
|
145
145
|
|
|
146
146
|
// MARK: - Helpers
|
|
147
147
|
|
|
148
|
-
private func
|
|
149
|
-
|
|
150
|
-
.
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
.first?.rootViewController else {
|
|
155
|
-
return nil
|
|
148
|
+
private func keyWindowRootViewController() -> UIViewController? {
|
|
149
|
+
if let windowScene = UIApplication.shared.connectedScenes
|
|
150
|
+
.first(where: { ($0 as? UIWindowScene)?.activationState == .foregroundActive }) as? UIWindowScene,
|
|
151
|
+
let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow }),
|
|
152
|
+
let root = keyWindow.rootViewController {
|
|
153
|
+
return root
|
|
156
154
|
}
|
|
157
|
-
|
|
155
|
+
return UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/// Returns (presenter, viewControllerToDismiss). If the top is a modal host or our EasyPay, we must dismiss it first so presenter is not "already presenting".
|
|
159
|
+
private func presentingViewControllerAndOptionalDismiss() -> (UIViewController, UIViewController?)? {
|
|
160
|
+
guard var vc = keyWindowRootViewController() else { return nil }
|
|
161
|
+
while let presented = vc.presentedViewController {
|
|
162
|
+
vc = presented
|
|
163
|
+
}
|
|
164
|
+
let top = vc
|
|
165
|
+
// Step back from modal host or our own payment VC to get the real presenter
|
|
166
|
+
while (isModalHostViewController(vc) || isEasyPayViewController(vc)), let presenter = vc.presentingViewController {
|
|
167
|
+
vc = presenter
|
|
168
|
+
}
|
|
169
|
+
if isModalHostViewController(vc) || isEasyPayViewController(vc) { return nil }
|
|
170
|
+
// If top was a modal or EasyPay, that top is currently presented by vc; we must dismiss it first
|
|
171
|
+
let dismissFirst: UIViewController? = (top !== vc) ? top : nil
|
|
172
|
+
return (vc, dismissFirst)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private func presentPaymentController(_ controller: UIViewController, from presentingVC: UIViewController, dismissFirst: UIViewController?) {
|
|
176
|
+
if let toDismiss = dismissFirst {
|
|
177
|
+
toDismiss.dismiss(animated: false) { [weak self] in
|
|
178
|
+
DispatchQueue.main.async {
|
|
179
|
+
// After dismiss, get top then step back from modal host / EasyPay so we never present from them
|
|
180
|
+
guard let presenter = self?.presentingViewControllerInWindowHierarchy() else {
|
|
181
|
+
presentingVC.present(controller, animated: true)
|
|
182
|
+
return
|
|
183
|
+
}
|
|
184
|
+
presenter.present(controller, animated: true)
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
presentingVC.present(controller, animated: true)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/// Present from a VC that can safely present (not RCTFabricModalHostViewController; not our EasyPayViewController).
|
|
193
|
+
private func presentingViewControllerInWindowHierarchy() -> UIViewController? {
|
|
194
|
+
guard var vc = keyWindowRootViewController() else { return nil }
|
|
195
|
+
while let presented = vc.presentedViewController {
|
|
196
|
+
vc = presented
|
|
197
|
+
}
|
|
198
|
+
while (isModalHostViewController(vc) || isEasyPayViewController(vc)), let presenter = vc.presentingViewController {
|
|
199
|
+
vc = presenter
|
|
200
|
+
}
|
|
201
|
+
if isModalHostViewController(vc) || isEasyPayViewController(vc) { return nil }
|
|
202
|
+
return vc
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private func isModalHostViewController(_ vc: UIViewController?) -> Bool {
|
|
206
|
+
guard let vc = vc else { return false }
|
|
207
|
+
let name = String(describing: type(of: vc))
|
|
208
|
+
return name.contains("ModalHost") || name.contains("RCTModalHost")
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private func isEasyPayViewController(_ vc: UIViewController?) -> Bool {
|
|
212
|
+
vc is EasyPayViewController
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private func getTopViewController() -> UIViewController? {
|
|
216
|
+
guard let rootVC = keyWindowRootViewController() else { return nil }
|
|
158
217
|
var topVC = rootVC
|
|
159
218
|
while let presentedVC = topVC.presentedViewController {
|
|
160
219
|
topVC = presentedVC
|
package/ios/Models/Request.swift
CHANGED
|
@@ -939,11 +939,11 @@ public final class Request: NSObject {
|
|
|
939
939
|
let token = clientToken ?? UserStoreSingleton.shared.clientToken ?? ""
|
|
940
940
|
uRLRequest.addValue(token, forHTTPHeaderField: "clientToken")
|
|
941
941
|
|
|
942
|
-
// Add API key/secret headers
|
|
942
|
+
// Add API key/secret headers (match Android SDK: X-Api-Key, X-Api-Secret)
|
|
943
943
|
if let apiKey = EnvironmentConfig.apiKey,
|
|
944
944
|
let apiSecret = EnvironmentConfig.apiSecret {
|
|
945
|
-
uRLRequest.addValue(apiKey, forHTTPHeaderField: "
|
|
946
|
-
uRLRequest.addValue(apiSecret, forHTTPHeaderField: "
|
|
945
|
+
uRLRequest.addValue(apiKey, forHTTPHeaderField: "X-Api-Key")
|
|
946
|
+
uRLRequest.addValue(apiSecret, forHTTPHeaderField: "X-Api-Secret")
|
|
947
947
|
}
|
|
948
948
|
|
|
949
949
|
let task = URLSession.shared.dataTask(with: uRLRequest) { data, response, error in
|