@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.
Files changed (71) hide show
  1. package/README.md +42 -113
  2. package/android/build.gradle +1 -1
  3. package/ios/Classes/EasyMerchantSdk.m +2 -2
  4. package/ios/easymerchantsdk.podspec +1 -1
  5. package/package.json +1 -1
  6. package/.idea/caches/deviceStreaming.xml +0 -340
  7. package/.idea/em-MobileCheckoutSDK-ReactNative.iml +0 -9
  8. package/.idea/misc.xml +0 -5
  9. package/.idea/modules.xml +0 -8
  10. package/.idea/vcs.xml +0 -6
  11. package/android/build/generated/source/buildConfig/debug/com/reactlibrary/BuildConfig.java +0 -10
  12. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/AndroidManifest.xml +0 -7
  13. package/android/build/intermediates/aapt_friendly_merged_manifests/debug/processDebugManifest/aapt/output-metadata.json +0 -18
  14. package/android/build/intermediates/aar_metadata/debug/writeDebugAarMetadata/aar-metadata.properties +0 -6
  15. package/android/build/intermediates/annotation_processor_list/debug/javaPreCompileDebug/annotationProcessors.json +0 -1
  16. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  17. package/android/build/intermediates/compile_r_class_jar/debug/generateDebugRFile/R.jar +0 -0
  18. package/android/build/intermediates/compile_symbol_list/debug/generateDebugRFile/R.txt +0 -0
  19. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +0 -1
  20. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +0 -2
  21. package/android/build/intermediates/incremental/mergeDebugAssets/merger.xml +0 -2
  22. package/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml +0 -2
  23. package/android/build/intermediates/incremental/mergeDebugShaders/merger.xml +0 -2
  24. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/BuildConfig.class +0 -0
  25. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  26. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  27. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  28. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  29. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  30. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkPackage.class +0 -0
  31. package/android/build/intermediates/local_only_symbol_list/debug/parseDebugLocalResources/R-def.txt +0 -2
  32. package/android/build/intermediates/manifest_merge_blame_file/debug/processDebugManifest/manifest-merger-blame-debug-report.txt +0 -7
  33. package/android/build/intermediates/merged_manifest/debug/processDebugManifest/AndroidManifest.xml +0 -7
  34. package/android/build/intermediates/navigation_json/debug/extractDeepLinksDebug/navigation.json +0 -1
  35. package/android/build/intermediates/nested_resources_validation_report/debug/generateDebugResources/nestedResourcesValidationReport.txt +0 -1
  36. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/BuildConfig.class +0 -0
  37. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  38. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  39. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  40. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  41. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  42. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkPackage.class +0 -0
  43. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  44. package/android/build/intermediates/symbol_list_with_package_name/debug/generateDebugRFile/package-aware-r.txt +0 -1
  45. package/android/build/outputs/logs/manifest-merger-debug-report.txt +0 -16
  46. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  47. package/ios/Pods/UserDefaults/UserStoreSingleton.swift +0 -425
  48. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +0 -2996
  49. package/ios/Pods/ViewControllers/BaseVC.swift +0 -142
  50. package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +0 -3807
  51. package/ios/Pods/ViewControllers/BillingInfoVC/Cells/CityListTVC.swift +0 -46
  52. package/ios/Pods/ViewControllers/BillingInfoVC/Cells/CountryListTVC.swift +0 -47
  53. package/ios/Pods/ViewControllers/BillingInfoVC/Cells/StateListTVC.swift +0 -46
  54. package/ios/Pods/ViewControllers/Clean Runner_2025-07-23T14-58-05.txt +0 -13
  55. package/ios/Pods/ViewControllers/CountryListVC.swift +0 -435
  56. package/ios/Pods/ViewControllers/EmailVerificationVC.swift +0 -300
  57. package/ios/Pods/ViewControllers/GrailPayVC.swift +0 -492
  58. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +0 -2278
  59. package/ios/Pods/ViewControllers/PaymentDoneVC.swift +0 -287
  60. package/ios/Pods/ViewControllers/PaymentErrorVC.swift +0 -85
  61. package/ios/Pods/ViewControllers/PaymentInformation/AccountTypeTVC.swift +0 -41
  62. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +0 -13115
  63. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInformationCVC.swift +0 -35
  64. package/ios/Pods/ViewControllers/PaymentInformation/RecurringTVC.swift +0 -40
  65. package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.swift +0 -80
  66. package/ios/Pods/ViewControllers/PaymentInformation/SavedAccountsTVC/SavedAccountTVC.xib +0 -163
  67. package/ios/Pods/ViewControllers/PaymentInformation/SavedCardsTVC/SavedCardsTVC.swift +0 -81
  68. package/ios/Pods/ViewControllers/PaymentInformation/SavedCardsTVC/SavedCardsTVC.xib +0 -188
  69. package/ios/Pods/ViewControllers/PaymentStatusWebViewVC.swift +0 -167
  70. package/ios/Pods/ViewControllers/TermAndConditionsVC.swift +0 -63
  71. 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
- }