@jimrising/easymerchantsdk-react-native 2.4.2 → 2.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.
- package/README.md +42 -113
- package/android/build.gradle +1 -1
- package/ios/Classes/EasyMerchantSdk.m +2 -2
- package/ios/easymerchantsdk.podspec +1 -1
- package/package.json +1 -1
- package/.idea/caches/deviceStreaming.xml +0 -340
- 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
- package/android/build/generated/source/buildConfig/debug/com/reactlibrary/BuildConfig.java +0 -10
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -7
- package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
- package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
- package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
- package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
- package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
- package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
- package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
- package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/BuildConfig.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
- package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkPackage.class +0 -0
- package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
- package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -7
- package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -7
- package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
- package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/BuildConfig.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
- package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkPackage.class +0 -0
- package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
- package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
- package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -16
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/ios/Pods/UserDefaults/UserStoreSingleton.swift +0 -425
- package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +0 -2996
- package/ios/Pods/ViewControllers/BaseVC.swift +0 -142
- package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +0 -3807
- package/ios/Pods/ViewControllers/BillingInfoVC/Cells/CityListTVC.swift +0 -46
- package/ios/Pods/ViewControllers/BillingInfoVC/Cells/CountryListTVC.swift +0 -47
- package/ios/Pods/ViewControllers/BillingInfoVC/Cells/StateListTVC.swift +0 -46
- package/ios/Pods/ViewControllers/Clean Runner_2025-07-23T14-58-05.txt +0 -13
- package/ios/Pods/ViewControllers/CountryListVC.swift +0 -435
- package/ios/Pods/ViewControllers/EmailVerificationVC.swift +0 -300
- package/ios/Pods/ViewControllers/GrailPayVC.swift +0 -492
- package/ios/Pods/ViewControllers/OTPVerificationVC.swift +0 -2278
- package/ios/Pods/ViewControllers/PaymentDoneVC.swift +0 -287
- package/ios/Pods/ViewControllers/PaymentErrorVC.swift +0 -85
- package/ios/Pods/ViewControllers/PaymentInformation/AccountTypeTVC.swift +0 -41
- package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +0 -13115
- package/ios/Pods/ViewControllers/PaymentInformation/PaymentInformationCVC.swift +0 -35
- package/ios/Pods/ViewControllers/PaymentInformation/RecurringTVC.swift +0 -40
- package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.swift +0 -80
- package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.xib +0 -163
- package/ios/Pods/ViewControllers/PaymentInformation/SavedCardsTVC/SavedCardsTVC.swift +0 -81
- package/ios/Pods/ViewControllers/PaymentInformation/SavedCardsTVC/SavedCardsTVC.xib +0 -188
- package/ios/Pods/ViewControllers/PaymentStatusWebViewVC.swift +0 -167
- package/ios/Pods/ViewControllers/TermAndConditionsVC.swift +0 -63
- package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +0 -1254
|
@@ -1,492 +0,0 @@
|
|
|
1
|
-
////
|
|
2
|
-
//// GrailPayVC.swift
|
|
3
|
-
//// EasyPay
|
|
4
|
-
////
|
|
5
|
-
//// Created by Mony's Mac on 02/05/25.
|
|
6
|
-
////
|
|
7
|
-
|
|
8
|
-
//import UIKit
|
|
9
|
-
//import WebKit
|
|
10
|
-
//
|
|
11
|
-
//public class GrailPayVC: UIViewController {
|
|
12
|
-
//
|
|
13
|
-
// private var webView: WKWebView!
|
|
14
|
-
// private var loadingIndicator: UIActivityIndicatorView!
|
|
15
|
-
// private var request: GrailPayRequest
|
|
16
|
-
// public var onCompletion: ((EasyPay.SDKResult) -> Void)?
|
|
17
|
-
// private var didHandleBankConnection = false
|
|
18
|
-
// private var allLinkedAccounts: [[String: Any]] = []
|
|
19
|
-
//
|
|
20
|
-
// public init(request: GrailPayRequest) {
|
|
21
|
-
// self.request = request
|
|
22
|
-
// super.init(nibName: nil, bundle: nil)
|
|
23
|
-
// }
|
|
24
|
-
//
|
|
25
|
-
// required init?(coder: NSCoder) {
|
|
26
|
-
// fatalError("init(coder:) has not been implemented")
|
|
27
|
-
// }
|
|
28
|
-
//
|
|
29
|
-
// override public func viewDidLoad() {
|
|
30
|
-
// super.viewDidLoad()
|
|
31
|
-
// setupUI()
|
|
32
|
-
// loadGrailPaySDK()
|
|
33
|
-
// }
|
|
34
|
-
//
|
|
35
|
-
// private func setupUI() {
|
|
36
|
-
// view.backgroundColor = .white
|
|
37
|
-
//
|
|
38
|
-
// let config = WKWebViewConfiguration()
|
|
39
|
-
// if #available(iOS 14.0, *) {
|
|
40
|
-
// let webpagePreferences = WKWebpagePreferences()
|
|
41
|
-
// webpagePreferences.allowsContentJavaScript = true
|
|
42
|
-
// config.defaultWebpagePreferences = webpagePreferences
|
|
43
|
-
// } else {
|
|
44
|
-
// let preferences = WKPreferences()
|
|
45
|
-
// preferences.javaScriptEnabled = true
|
|
46
|
-
// config.preferences = preferences
|
|
47
|
-
// }
|
|
48
|
-
//
|
|
49
|
-
// config.websiteDataStore = WKWebsiteDataStore.default()
|
|
50
|
-
// config.userContentController.add(self, name: "grailpayHandler")
|
|
51
|
-
// config.allowsInlineMediaPlayback = true
|
|
52
|
-
// config.mediaTypesRequiringUserActionForPlayback = []
|
|
53
|
-
//
|
|
54
|
-
// webView = WKWebView(frame: view.bounds, configuration: config)
|
|
55
|
-
// webView.navigationDelegate = self
|
|
56
|
-
// webView.uiDelegate = self
|
|
57
|
-
// webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
58
|
-
// view.addSubview(webView)
|
|
59
|
-
//
|
|
60
|
-
// loadingIndicator = UIActivityIndicatorView(style: .large)
|
|
61
|
-
// loadingIndicator.center = view.center
|
|
62
|
-
// loadingIndicator.hidesWhenStopped = true
|
|
63
|
-
// view.addSubview(loadingIndicator)
|
|
64
|
-
// }
|
|
65
|
-
//
|
|
66
|
-
// private func loadGrailPaySDK() {
|
|
67
|
-
// loadingIndicator.startAnimating()
|
|
68
|
-
//
|
|
69
|
-
//// let sdkURL = request.isSandbox
|
|
70
|
-
//// ? "https://bank-link-widget-sandbox.grailpay.com/sdk.js"
|
|
71
|
-
//// : "https://bank-link-widget.grailpay.com/sdk.js"
|
|
72
|
-
//
|
|
73
|
-
// let sdkURL = EnvironmentConfig.grailPaySDKURL
|
|
74
|
-
//
|
|
75
|
-
// let html = """
|
|
76
|
-
// <!DOCTYPE html>
|
|
77
|
-
// <html>
|
|
78
|
-
// <head>
|
|
79
|
-
// <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\">
|
|
80
|
-
// <script>
|
|
81
|
-
// window.sdkInitialized = false;
|
|
82
|
-
//
|
|
83
|
-
// function initializeSDK() {
|
|
84
|
-
// if (window.sdkInitialized) return;
|
|
85
|
-
//
|
|
86
|
-
// if (typeof window.grailpay === 'undefined') {
|
|
87
|
-
// window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: 'SDK not loaded' });
|
|
88
|
-
// return;
|
|
89
|
-
// }
|
|
90
|
-
//
|
|
91
|
-
// window.grailpay.init({
|
|
92
|
-
// token: '\(UserStoreSingleton.shared.bankWidgetKey ?? "")',
|
|
93
|
-
// vendorId: '\(UserStoreSingleton.shared.vendorID ?? "")',
|
|
94
|
-
// role: '\(request.role)',
|
|
95
|
-
// timeout: \(request.timeout),
|
|
96
|
-
// theme: {
|
|
97
|
-
// branding_name: '\(request.brandingName)',
|
|
98
|
-
// screens: {
|
|
99
|
-
// finder: {
|
|
100
|
-
// subtitle: '\(request.finderSubtitle)',
|
|
101
|
-
// searchPlaceholder: '\(request.searchPlaceholder)'
|
|
102
|
-
// }
|
|
103
|
-
// }
|
|
104
|
-
// },
|
|
105
|
-
// onError: function(error) {
|
|
106
|
-
// console.log("JS onError:", error);
|
|
107
|
-
// window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: error });
|
|
108
|
-
// },
|
|
109
|
-
// onBankConnected: function(data) {
|
|
110
|
-
// console.log("✅ Bank connected:", data);
|
|
111
|
-
// window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'bankConnected', data: data });
|
|
112
|
-
// },
|
|
113
|
-
// onLinkedDefaultAccount: function(data) {
|
|
114
|
-
// console.log("✅ Default Account selected:", data);
|
|
115
|
-
// window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'defaultAccountSelected', data: data });
|
|
116
|
-
// },
|
|
117
|
-
// onLinkExit: function(data) {
|
|
118
|
-
// console.log("⚠️ User exited:", data);
|
|
119
|
-
// window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'linkExit', data: data });
|
|
120
|
-
// }
|
|
121
|
-
// }).then(function() {
|
|
122
|
-
// window.sdkInitialized = true;
|
|
123
|
-
// window.grailpay.open();
|
|
124
|
-
// }).catch(function(error) {
|
|
125
|
-
// console.log("❌ SDK init failed:", error);
|
|
126
|
-
// window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: error });
|
|
127
|
-
// });
|
|
128
|
-
// }
|
|
129
|
-
//
|
|
130
|
-
// function loadSDK() {
|
|
131
|
-
// const script = document.createElement('script');
|
|
132
|
-
// script.src = '\(sdkURL)';
|
|
133
|
-
// script.onload = function() {
|
|
134
|
-
// setTimeout(initializeSDK, 1000);
|
|
135
|
-
// };
|
|
136
|
-
// script.onerror = function(error) {
|
|
137
|
-
// console.log("❌ Failed to load SDK script");
|
|
138
|
-
// window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: 'Failed to load SDK script' });
|
|
139
|
-
// };
|
|
140
|
-
// document.head.appendChild(script);
|
|
141
|
-
// }
|
|
142
|
-
//
|
|
143
|
-
// document.addEventListener('DOMContentLoaded', loadSDK);
|
|
144
|
-
// </script>
|
|
145
|
-
// </head>
|
|
146
|
-
// <body style=\"margin:0;padding:0;\"></body>
|
|
147
|
-
// </html>
|
|
148
|
-
// """
|
|
149
|
-
//
|
|
150
|
-
//// let baseURL = URL(string: request.isSandbox
|
|
151
|
-
//// ? "https://bank-link-widget-sandbox.grailpay.com"
|
|
152
|
-
//// : "https://bank-link-widget.grailpay.com")
|
|
153
|
-
//
|
|
154
|
-
// let baseURL = URL(string: EnvironmentConfig.grailPayBaseURL)
|
|
155
|
-
//
|
|
156
|
-
// webView.loadHTMLString(html, baseURL: baseURL)
|
|
157
|
-
// }
|
|
158
|
-
//
|
|
159
|
-
// private func handleError(_ error: Error) {
|
|
160
|
-
// DispatchQueue.main.async {
|
|
161
|
-
// self.loadingIndicator.stopAnimating()
|
|
162
|
-
// self.onCompletion?(EasyPay.SDKResult(error: error as NSError))
|
|
163
|
-
// self.dismiss(animated: true)
|
|
164
|
-
// }
|
|
165
|
-
// }
|
|
166
|
-
//}
|
|
167
|
-
//
|
|
168
|
-
//// MARK: - WKNavigationDelegate
|
|
169
|
-
//extension GrailPayVC: WKNavigationDelegate {
|
|
170
|
-
// public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
171
|
-
// loadingIndicator.stopAnimating()
|
|
172
|
-
// }
|
|
173
|
-
//
|
|
174
|
-
// public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
|
175
|
-
// handleError(error)
|
|
176
|
-
// }
|
|
177
|
-
//}
|
|
178
|
-
//
|
|
179
|
-
//// MARK: - WKScriptMessageHandler
|
|
180
|
-
//extension GrailPayVC: WKScriptMessageHandler {
|
|
181
|
-
// public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
182
|
-
// print("JS Message received: \(message.body)")
|
|
183
|
-
//
|
|
184
|
-
// guard let body = message.body as? [String: Any],
|
|
185
|
-
// let type = body["type"] as? String else {
|
|
186
|
-
// print("Invalid message structure")
|
|
187
|
-
// return
|
|
188
|
-
// }
|
|
189
|
-
//
|
|
190
|
-
// switch type {
|
|
191
|
-
// case "bankConnected":
|
|
192
|
-
// if let data = body["data"] as? [[String: Any]] {
|
|
193
|
-
// print("✅ All linked accounts:", data)
|
|
194
|
-
// self.allLinkedAccounts = data
|
|
195
|
-
// }
|
|
196
|
-
//
|
|
197
|
-
// case "defaultAccountSelected":
|
|
198
|
-
// guard let selectedAccount = body["data"] as? [String: Any] else {
|
|
199
|
-
// print("No account data selected")
|
|
200
|
-
// return
|
|
201
|
-
// }
|
|
202
|
-
//
|
|
203
|
-
// print("✅ Selected default account: \(selectedAccount)")
|
|
204
|
-
//
|
|
205
|
-
// if !didHandleBankConnection {
|
|
206
|
-
// didHandleBankConnection = true
|
|
207
|
-
// DispatchQueue.main.async {
|
|
208
|
-
// self.onCompletion?(EasyPay.SDKResult(type: .success, chargeData: ["data": [selectedAccount]]))
|
|
209
|
-
// self.dismiss(animated: true)
|
|
210
|
-
// }
|
|
211
|
-
// }
|
|
212
|
-
//
|
|
213
|
-
// case "linkExit":
|
|
214
|
-
// if didHandleBankConnection {
|
|
215
|
-
// print("linkExit ignored (already handled)")
|
|
216
|
-
// return
|
|
217
|
-
// }
|
|
218
|
-
// print("User exited linking flow")
|
|
219
|
-
// DispatchQueue.main.async {
|
|
220
|
-
// self.onCompletion?(EasyPay.SDKResult(type: .cancelled))
|
|
221
|
-
// self.dismiss(animated: true)
|
|
222
|
-
// }
|
|
223
|
-
//
|
|
224
|
-
// case "error":
|
|
225
|
-
// let errorMessage = body["data"] as? String ?? "Unknown error"
|
|
226
|
-
// print("GrailPay Error:", errorMessage)
|
|
227
|
-
// let error = NSError(domain: "GrailPayError", code: 0, userInfo: [NSLocalizedDescriptionKey: errorMessage])
|
|
228
|
-
// handleError(error)
|
|
229
|
-
//
|
|
230
|
-
// default:
|
|
231
|
-
// print("Unknown JS message type:", type)
|
|
232
|
-
// }
|
|
233
|
-
// }
|
|
234
|
-
//}
|
|
235
|
-
//
|
|
236
|
-
//// MARK: - WKUIDelegate
|
|
237
|
-
//extension GrailPayVC: WKUIDelegate {
|
|
238
|
-
// public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration,
|
|
239
|
-
// for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
|
|
240
|
-
// if navigationAction.targetFrame == nil {
|
|
241
|
-
// webView.load(navigationAction.request)
|
|
242
|
-
// }
|
|
243
|
-
// return nil
|
|
244
|
-
// }
|
|
245
|
-
//}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
import UIKit
|
|
257
|
-
import WebKit
|
|
258
|
-
|
|
259
|
-
public class GrailPayVC: UIViewController {
|
|
260
|
-
|
|
261
|
-
private var webView: WKWebView!
|
|
262
|
-
private var loadingIndicator: UIActivityIndicatorView!
|
|
263
|
-
private var request: GrailPayRequest
|
|
264
|
-
public var onCompletion: ((SDKResult) -> Void)?
|
|
265
|
-
private var didHandleBankConnection = false
|
|
266
|
-
private var allLinkedAccounts: [[String: Any]] = []
|
|
267
|
-
|
|
268
|
-
public init(request: GrailPayRequest) {
|
|
269
|
-
self.request = request
|
|
270
|
-
super.init(nibName: nil, bundle: nil)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
required init?(coder: NSCoder) {
|
|
274
|
-
fatalError("init(coder:) has not been implemented")
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
override public func viewDidLoad() {
|
|
278
|
-
super.viewDidLoad()
|
|
279
|
-
setupUI()
|
|
280
|
-
loadGrailPaySDK()
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
private func setupUI() {
|
|
284
|
-
view.backgroundColor = .white
|
|
285
|
-
|
|
286
|
-
let config = WKWebViewConfiguration()
|
|
287
|
-
if #available(iOS 14.0, *) {
|
|
288
|
-
let webpagePreferences = WKWebpagePreferences()
|
|
289
|
-
webpagePreferences.allowsContentJavaScript = true
|
|
290
|
-
config.defaultWebpagePreferences = webpagePreferences
|
|
291
|
-
} else {
|
|
292
|
-
let preferences = WKPreferences()
|
|
293
|
-
preferences.javaScriptEnabled = true
|
|
294
|
-
config.preferences = preferences
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
config.websiteDataStore = WKWebsiteDataStore.default()
|
|
298
|
-
config.userContentController.add(self, name: "grailpayHandler")
|
|
299
|
-
config.allowsInlineMediaPlayback = true
|
|
300
|
-
config.mediaTypesRequiringUserActionForPlayback = []
|
|
301
|
-
|
|
302
|
-
webView = WKWebView(frame: view.bounds, configuration: config)
|
|
303
|
-
webView.navigationDelegate = self
|
|
304
|
-
webView.uiDelegate = self
|
|
305
|
-
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
306
|
-
view.addSubview(webView)
|
|
307
|
-
|
|
308
|
-
loadingIndicator = UIActivityIndicatorView(style: .large)
|
|
309
|
-
loadingIndicator.center = view.center
|
|
310
|
-
loadingIndicator.hidesWhenStopped = true
|
|
311
|
-
view.addSubview(loadingIndicator)
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private func loadGrailPaySDK() {
|
|
315
|
-
loadingIndicator.startAnimating()
|
|
316
|
-
|
|
317
|
-
let sdkURL = EnvironmentConfig.grailPaySDKURL
|
|
318
|
-
let baseURL = URL(string: EnvironmentConfig.grailPayBaseURL)
|
|
319
|
-
|
|
320
|
-
let html = """
|
|
321
|
-
<!DOCTYPE html>
|
|
322
|
-
<html>
|
|
323
|
-
<head>
|
|
324
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
325
|
-
<script>
|
|
326
|
-
window.sdkInitialized = false;
|
|
327
|
-
|
|
328
|
-
function initializeSDK() {
|
|
329
|
-
if (window.sdkInitialized) return;
|
|
330
|
-
|
|
331
|
-
if (typeof window.grailpay === 'undefined') {
|
|
332
|
-
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: 'SDK not loaded' });
|
|
333
|
-
return;
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
window.grailpay.init({
|
|
337
|
-
token: '\(UserStoreSingleton.shared.bankWidgetKey ?? "")',
|
|
338
|
-
vendorId: '\(UserStoreSingleton.shared.vendorID ?? "")',
|
|
339
|
-
role: '\(request.role)',
|
|
340
|
-
timeout: \(request.timeout),
|
|
341
|
-
theme: {
|
|
342
|
-
branding_name: '\(request.brandingName)',
|
|
343
|
-
screens: {
|
|
344
|
-
finder: {
|
|
345
|
-
subtitle: '\(request.finderSubtitle)',
|
|
346
|
-
searchPlaceholder: '\(request.searchPlaceholder)'
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
},
|
|
350
|
-
onError: function(error) {
|
|
351
|
-
console.log("JS onError:", error);
|
|
352
|
-
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: error });
|
|
353
|
-
},
|
|
354
|
-
onBankConnected: function(data) {
|
|
355
|
-
console.log("✅ Bank connected:", data);
|
|
356
|
-
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'bankConnected', data: data });
|
|
357
|
-
},
|
|
358
|
-
onLinkedDefaultAccount: function(data) {
|
|
359
|
-
console.log("✅ Default Account selected:", data);
|
|
360
|
-
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'defaultAccountSelected', data: data });
|
|
361
|
-
},
|
|
362
|
-
onLinkExit: function(data) {
|
|
363
|
-
console.log("⚠️ User exited:", data);
|
|
364
|
-
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'linkExit', data: data });
|
|
365
|
-
}
|
|
366
|
-
}).then(function() {
|
|
367
|
-
window.sdkInitialized = true;
|
|
368
|
-
window.grailpay.open();
|
|
369
|
-
}).catch(function(error) {
|
|
370
|
-
console.log("❌ SDK init failed:", error);
|
|
371
|
-
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: error });
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
function loadSDK() {
|
|
376
|
-
const script = document.createElement('script');
|
|
377
|
-
script.src = '\(sdkURL)';
|
|
378
|
-
script.onload = function() {
|
|
379
|
-
setTimeout(initializeSDK, 1000);
|
|
380
|
-
};
|
|
381
|
-
script.onerror = function(error) {
|
|
382
|
-
console.log("❌ Failed to load SDK script");
|
|
383
|
-
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: 'Failed to load SDK script' });
|
|
384
|
-
};
|
|
385
|
-
document.head.appendChild(script);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
document.addEventListener('DOMContentLoaded', loadSDK);
|
|
389
|
-
</script>
|
|
390
|
-
</head>
|
|
391
|
-
<body style="margin:0;padding:0;"></body>
|
|
392
|
-
</html>
|
|
393
|
-
"""
|
|
394
|
-
|
|
395
|
-
webView.loadHTMLString(html, baseURL: baseURL)
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
private func handleError(_ error: Error) {
|
|
399
|
-
DispatchQueue.main.async {
|
|
400
|
-
self.loadingIndicator.stopAnimating()
|
|
401
|
-
let errorData: [String: Any] = [
|
|
402
|
-
"status": false,
|
|
403
|
-
"message": error.localizedDescription
|
|
404
|
-
]
|
|
405
|
-
self.onCompletion?(SDKResult(type: .error, data: errorData as NSDictionary))
|
|
406
|
-
self.dismiss(animated: true)
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// MARK: - WKNavigationDelegate
|
|
412
|
-
extension GrailPayVC: WKNavigationDelegate {
|
|
413
|
-
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
414
|
-
loadingIndicator.stopAnimating()
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
|
418
|
-
handleError(error)
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
// MARK: - WKScriptMessageHandler
|
|
423
|
-
extension GrailPayVC: WKScriptMessageHandler {
|
|
424
|
-
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
425
|
-
print("JS Message received: \(message.body)")
|
|
426
|
-
|
|
427
|
-
guard let body = message.body as? [String: Any],
|
|
428
|
-
let type = body["type"] as? String else {
|
|
429
|
-
print("Invalid message structure")
|
|
430
|
-
return
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
switch type {
|
|
434
|
-
case "bankConnected":
|
|
435
|
-
if let data = body["data"] as? [[String: Any]] {
|
|
436
|
-
print("✅ All linked accounts:", data)
|
|
437
|
-
self.allLinkedAccounts = data
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
case "defaultAccountSelected":
|
|
441
|
-
guard let selectedAccount = body["data"] as? [String: Any] else {
|
|
442
|
-
print("No account data selected")
|
|
443
|
-
return
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
print("✅ Selected default account: \(selectedAccount)")
|
|
447
|
-
|
|
448
|
-
if !didHandleBankConnection {
|
|
449
|
-
didHandleBankConnection = true
|
|
450
|
-
DispatchQueue.main.async {
|
|
451
|
-
self.onCompletion?(SDKResult(type: .success, data: ["data": [selectedAccount]] as NSDictionary))
|
|
452
|
-
self.dismiss(animated: true)
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
case "linkExit":
|
|
457
|
-
if didHandleBankConnection {
|
|
458
|
-
print("linkExit ignored (already handled)")
|
|
459
|
-
return
|
|
460
|
-
}
|
|
461
|
-
print("User exited linking flow")
|
|
462
|
-
DispatchQueue.main.async {
|
|
463
|
-
let cancelData: [String: Any] = [
|
|
464
|
-
"status": false,
|
|
465
|
-
"message": "User cancelled the payment"
|
|
466
|
-
]
|
|
467
|
-
self.onCompletion?(SDKResult(type: .cancelled, data: cancelData as NSDictionary))
|
|
468
|
-
self.dismiss(animated: true)
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
case "error":
|
|
472
|
-
let errorMessage = body["data"] as? String ?? "Unknown error"
|
|
473
|
-
print("GrailPay Error:", errorMessage)
|
|
474
|
-
let error = NSError(domain: "GrailPayError", code: 0, userInfo: [NSLocalizedDescriptionKey: errorMessage])
|
|
475
|
-
handleError(error)
|
|
476
|
-
|
|
477
|
-
default:
|
|
478
|
-
print("Unknown JS message type:", type)
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// MARK: - WKUIDelegate
|
|
484
|
-
extension GrailPayVC: WKUIDelegate {
|
|
485
|
-
public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration,
|
|
486
|
-
for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
|
|
487
|
-
if navigationAction.targetFrame == nil {
|
|
488
|
-
webView.load(navigationAction.request)
|
|
489
|
-
}
|
|
490
|
-
return nil
|
|
491
|
-
}
|
|
492
|
-
}
|