@jimrising/easymerchantsdk-react-native 2.2.9 → 2.3.1

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 (102) hide show
  1. package/.idea/caches/deviceStreaming.xml +11 -0
  2. package/README.md +310 -171
  3. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  4. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$3.dex +0 -0
  5. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  6. package/android/build/.transforms/20e1216b87bd06eaab3c9e5c68d4267a/transformed/bundleLibRuntimeToDirDebug/desugar_graph.bin +0 -0
  7. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  8. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule$3.dex +0 -0
  9. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  10. package/android/build/.transforms/3f3a228346492fb34e3f574e941b632f/transformed/bundleLibRuntimeToDirRelease/desugar_graph.bin +0 -0
  11. package/android/build/.transforms/58b147bdc43284da2468dab19bc4a64d/transformed/classes/classes_dex/classes.dex +0 -0
  12. package/android/build/.transforms/e9a664a11ce12edf79cd87b1e07aa243/transformed/classes/classes_dex/classes.dex +0 -0
  13. package/android/build/intermediates/aar_main_jar/release/syncReleaseLibJars/classes.jar +0 -0
  14. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  15. package/android/build/intermediates/compile_library_classes_jar/release/bundleLibCompileToJarRelease/classes.jar +0 -0
  16. package/android/build/intermediates/full_jar/release/createFullJarRelease/full.jar +0 -0
  17. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  18. package/android/build/intermediates/incremental/lintVitalAnalyzeRelease/release-artifact-dependencies.xml +4 -4
  19. package/android/build/intermediates/incremental/lintVitalAnalyzeRelease/release-artifact-libraries.xml +4 -4
  20. package/android/build/intermediates/incremental/release/mergeReleaseResources/compile-file-map.properties +916 -916
  21. package/android/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +3 -3
  22. package/android/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties +1 -1
  23. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  24. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  25. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  26. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  27. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  28. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  29. package/android/build/intermediates/lint-cache/lintVitalAnalyzeRelease/maven.google/com/android/tools/build/group-index.xml +22 -0
  30. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-dependencies.xml +4 -4
  31. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-libraries.xml +4 -4
  32. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-dependencies.xml +4 -4
  33. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-libraries.xml +4 -4
  34. package/android/build/intermediates/local_aar_for_lint/release/out.aar +0 -0
  35. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_payment_done_url.xml +2 -1
  36. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/multi-v2/values-night-v8.json +2 -2
  37. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/multi-v2/values.json +38 -38
  38. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/anim-v21.json +9 -9
  39. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/anim.json +24 -24
  40. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/animator-v21.json +1 -1
  41. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/animator.json +34 -34
  42. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color-night-v8.json +3 -3
  43. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color-v31.json +10 -10
  44. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color.json +153 -153
  45. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-anydpi-v21.json +6 -6
  46. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-hdpi-v4.json +13 -13
  47. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-ldpi-v4.json +6 -6
  48. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-mdpi-v4.json +12 -12
  49. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v21.json +4 -4
  50. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v23.json +7 -7
  51. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v29.json +1 -1
  52. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xhdpi-v4.json +12 -12
  53. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xxhdpi-v4.json +7 -7
  54. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xxxhdpi-v4.json +7 -7
  55. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable.json +395 -395
  56. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/font.json +9 -9
  57. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/interpolator-v21.json +10 -10
  58. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/interpolator.json +11 -11
  59. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-land.json +3 -3
  60. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-sw600dp-v13.json +2 -2
  61. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-v21.json +4 -4
  62. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-v26.json +1 -1
  63. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout.json +108 -108
  64. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-anydpi-v26.json +2 -2
  65. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-hdpi-v4.json +2 -2
  66. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-mdpi-v4.json +2 -2
  67. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xhdpi-v4.json +2 -2
  68. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xxhdpi-v4.json +2 -2
  69. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xxxhdpi-v4.json +2 -2
  70. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/raw.json +46 -46
  71. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/xml.json +3 -3
  72. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  73. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  74. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  75. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  76. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$3.class +0 -0
  77. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  78. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  79. package/android/build/intermediates/runtime_library_classes_jar/release/bundleLibRuntimeToJarRelease/classes.jar +0 -0
  80. package/android/build/intermediates/source_set_path_map/release/mapReleaseSourceSetPaths/file-map.txt +38 -38
  81. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_payment_done_url.xml.flat +0 -0
  82. package/android/build/outputs/aar/jimrising_easymerchantsdk-react-native-release.aar +0 -0
  83. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  84. package/android/build/tmp/compileReleaseJavaWithJavac/previous-compilation-data.bin +0 -0
  85. package/android/build.gradle +1 -1
  86. package/android/src/main/java/com/reactlibrary/RNEasymerchantsdkModule.java +56 -1
  87. package/ios/Classes/EasyMerchantSdk.m +124 -141
  88. package/ios/Classes/EasyMerchantSdk.swift +270 -502
  89. package/ios/Classes/EasyPayViewController.swift +18 -15
  90. package/ios/CustomComponents/TextFieldStackView.swift +16 -46
  91. package/ios/EnvironmentConfig.swift +16 -0
  92. package/ios/Example/ViewController.swift +513 -76
  93. package/ios/Models/Request.swift +365 -171
  94. package/ios/Pods/UserDefaults/UserStoreSingleton.swift +116 -12
  95. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +2 -32
  96. package/ios/Pods/ViewControllers/GrailPayVC.swift +258 -18
  97. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +1 -66
  98. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +571 -369
  99. package/ios/Pods/ViewControllers/ThreeDSecurePaymentDoneVC.swift +18 -9
  100. package/ios/easymerchantsdk.podspec +1 -1
  101. package/ios/easymerchantsdk.storyboard +108 -85
  102. package/package.json +1 -1
@@ -65,6 +65,63 @@ class UserStoreSingleton: NSObject {
65
65
  }
66
66
  }
67
67
 
68
+ var amount : String? {
69
+ get {
70
+ return (UserDefaults().object(forKey: "amount") as? String)
71
+ } set {
72
+ UserDefaults.standard.setValue(newValue, forKey: "amount")
73
+ }
74
+ }
75
+
76
+ //Recurring params
77
+ var allowCycles : String? {
78
+ get {
79
+ return (UserDefaults().object(forKey: "allowCycles") as? String)
80
+ } set {
81
+ UserDefaults.standard.setValue(newValue, forKey: "allowCycles")
82
+ }
83
+ }
84
+
85
+ var interval : String? {
86
+ get {
87
+ return (UserDefaults().object(forKey: "interval") as? String)
88
+ } set {
89
+ UserDefaults.standard.setValue(newValue, forKey: "interval")
90
+ }
91
+ }
92
+
93
+ var isRecurring : String? {
94
+ get {
95
+ return (UserDefaults().object(forKey: "isRecurring") as? String)
96
+ } set {
97
+ UserDefaults.standard.setValue(newValue, forKey: "isRecurring")
98
+ }
99
+ }
100
+
101
+ var startDate : String? {
102
+ get {
103
+ return (UserDefaults().object(forKey: "startDate") as? String)
104
+ } set {
105
+ UserDefaults.standard.setValue(newValue, forKey: "startDate")
106
+ }
107
+ }
108
+
109
+ var startDateType : String? {
110
+ get {
111
+ return (UserDefaults().object(forKey: "startDateType") as? String)
112
+ } set {
113
+ UserDefaults.standard.setValue(newValue, forKey: "startDateType")
114
+ }
115
+ }
116
+
117
+ var paymentIntentId : String? {
118
+ get {
119
+ return (UserDefaults().object(forKey: "paymentIntentId") as? String)
120
+ } set {
121
+ UserDefaults.standard.setValue(newValue, forKey: "paymentIntentId")
122
+ }
123
+ }
124
+
68
125
  var isLoggedIn : Bool? {
69
126
  get {
70
127
  return (UserDefaults().object(forKey: "isLoggedIn") as? Bool)
@@ -248,19 +305,9 @@ class UserStoreSingleton: NSObject {
248
305
  self.border_radious = themeConfiguration.borderRadius
249
306
  self.fontSize = themeConfiguration.fontSize
250
307
  }
251
-
252
- // Method to clear user data from UserDefaults
253
- // func clearUserData() {
254
- // UserDefaults.standard.removeObject(forKey: "customer_id")
255
- // UserDefaults.standard.removeObject(forKey: "verificationEmail")
256
- // UserDefaults.standard.removeObject(forKey: "customer_token")
257
- // UserDefaults.standard.removeObject(forKey: "client_token")
258
- // UserDefaults.standard.synchronize() // Optional, but can help ensure the changes are applied immediately
259
- // }
260
308
 
261
309
  func clearUserData() {
262
310
  let keysToRemove = [
263
- "client_token",
264
311
  "payment_intent",
265
312
  "merchant_email",
266
313
  "merchant_name",
@@ -273,6 +320,14 @@ class UserStoreSingleton: NSObject {
273
320
  "payment_methods",
274
321
  "bank_widget_key",
275
322
  "vendor_id",
323
+
324
+ // "amount",
325
+ // "allowCycles",
326
+ // "interval",
327
+ // "isRecurring",
328
+ // "startDate",
329
+ // "startDateType",
330
+ // "paymentIntentId"
276
331
  ]
277
332
 
278
333
  for key in keysToRemove {
@@ -281,7 +336,7 @@ class UserStoreSingleton: NSObject {
281
336
 
282
337
  UserDefaults.standard.synchronize()
283
338
  }
284
-
339
+
285
340
  @objc private func handleAppTermination() {
286
341
  print("App is terminating. Clearing user data...")
287
342
  clearUserData()
@@ -293,12 +348,61 @@ class UserStoreSingleton: NSObject {
293
348
 
294
349
  }
295
350
 
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
+ }
296
358
 
359
+ //Recurring params
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
+ }
297
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
+ }
298
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
+ }
299
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
+ }
300
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
+ }
301
399
 
302
-
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
+ }
303
407
 
304
408
 
@@ -1161,7 +1161,6 @@ class AdditionalInfoVC: BaseVC {
1161
1161
  "routing_number": routingNumber ?? "",
1162
1162
  "account_number": accountNumber ?? "",
1163
1163
  "payment_mode": "auth_and_capture",
1164
- "payment_intent": UserStoreSingleton.shared.paymentIntent ?? "",
1165
1164
  "levelIndicator": 1,
1166
1165
  ]
1167
1166
 
@@ -1567,7 +1566,6 @@ class AdditionalInfoVC: BaseVC {
1567
1566
  "routing_number": routingNumber ?? "",
1568
1567
  "account_number": accountNumber ?? "",
1569
1568
  "payment_mode": "auth_and_capture",
1570
- "payment_intent": UserStoreSingleton.shared.paymentIntent ?? "",
1571
1569
  "levelIndicator": 1,
1572
1570
  "save_account": 1,
1573
1571
  "payment_method": "ach"
@@ -1758,14 +1756,7 @@ class AdditionalInfoVC: BaseVC {
1758
1756
  let token = UserStoreSingleton.shared.clientToken
1759
1757
  print("Setting clientToken header: \(token ?? "None")")
1760
1758
  uRLRequest.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
1761
-
1762
- // Add API headers
1763
- if let apiKey = EnvironmentConfig.apiKey,
1764
- let apiSecret = EnvironmentConfig.apiSecret {
1765
- uRLRequest.addValue(apiKey, forHTTPHeaderField: "x-api-key")
1766
- uRLRequest.addValue(apiSecret, forHTTPHeaderField: "x-api-secret")
1767
- }
1768
-
1759
+
1769
1760
  // Extract only the digits from the phone number (local only, no country code)
1770
1761
  let localPhone = txtFieldPhoneNumber.text?.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() ?? ""
1771
1762
 
@@ -1979,13 +1970,6 @@ class AdditionalInfoVC: BaseVC {
1979
1970
  print("Setting clientToken header: \(token ?? "None")")
1980
1971
  uRLRequest.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
1981
1972
 
1982
- // Add API headers
1983
- if let apiKey = EnvironmentConfig.apiKey,
1984
- let apiSecret = EnvironmentConfig.apiSecret {
1985
- uRLRequest.addValue(apiKey, forHTTPHeaderField: "x-api-key")
1986
- uRLRequest.addValue(apiSecret, forHTTPHeaderField: "x-api-secret")
1987
- }
1988
-
1989
1973
  // Extract only the digits from the phone number (local only, no country code)
1990
1974
  let localPhone = txtFieldPhoneNumber.text?.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() ?? ""
1991
1975
 
@@ -2184,13 +2168,6 @@ class AdditionalInfoVC: BaseVC {
2184
2168
  print("Setting clientToken header: \(token ?? "None")")
2185
2169
  uRLRequest.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
2186
2170
 
2187
- if let apiKey = EnvironmentConfig.apiKey {
2188
- uRLRequest.addValue(apiKey, forHTTPHeaderField: "X-Api-Key")
2189
- }
2190
- if let apiSecret = EnvironmentConfig.apiSecret {
2191
- uRLRequest.addValue(apiSecret, forHTTPHeaderField: "X-Api-Secret")
2192
- }
2193
-
2194
2171
  // Extract only the digits from the phone number (local only, no country code)
2195
2172
  let localPhone = txtFieldPhoneNumber.text?.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() ?? ""
2196
2173
 
@@ -2404,14 +2381,7 @@ class AdditionalInfoVC: BaseVC {
2404
2381
  let token = UserStoreSingleton.shared.clientToken
2405
2382
  print("Setting clientToken header: \(token ?? "None")")
2406
2383
  uRLRequest.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
2407
-
2408
- if let apiKey = EnvironmentConfig.apiKey {
2409
- uRLRequest.addValue(apiKey, forHTTPHeaderField: "X-Api-Key")
2410
- }
2411
- if let apiSecret = EnvironmentConfig.apiSecret {
2412
- uRLRequest.addValue(apiSecret, forHTTPHeaderField: "X-Api-Secret")
2413
- }
2414
-
2384
+
2415
2385
  let emailPrefix = userEmail?.components(separatedBy: "@").first ?? ""
2416
2386
 
2417
2387
  var params: [String: Any] = [
@@ -5,6 +5,254 @@
5
5
  //// Created by Mony's Mac on 02/05/25.
6
6
  ////
7
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
+
8
256
  import UIKit
9
257
  import WebKit
10
258
 
@@ -13,9 +261,9 @@ public class GrailPayVC: UIViewController {
13
261
  private var webView: WKWebView!
14
262
  private var loadingIndicator: UIActivityIndicatorView!
15
263
  private var request: GrailPayRequest
16
-
17
264
  public var onCompletion: ((SDKResult) -> Void)?
18
265
  private var didHandleBankConnection = false
266
+ private var allLinkedAccounts: [[String: Any]] = []
19
267
 
20
268
  public init(request: GrailPayRequest) {
21
269
  self.request = request
@@ -36,14 +284,11 @@ public class GrailPayVC: UIViewController {
36
284
  view.backgroundColor = .white
37
285
 
38
286
  let config = WKWebViewConfiguration()
39
-
40
- // Modern iOS 14+ JavaScript enablement
41
287
  if #available(iOS 14.0, *) {
42
288
  let webpagePreferences = WKWebpagePreferences()
43
289
  webpagePreferences.allowsContentJavaScript = true
44
290
  config.defaultWebpagePreferences = webpagePreferences
45
291
  } else {
46
- // Fallback for iOS < 14
47
292
  let preferences = WKPreferences()
48
293
  preferences.javaScriptEnabled = true
49
294
  config.preferences = preferences
@@ -69,9 +314,8 @@ public class GrailPayVC: UIViewController {
69
314
  private func loadGrailPaySDK() {
70
315
  loadingIndicator.startAnimating()
71
316
 
72
- let sdkURL = request.isSandbox
73
- ? "https://bank-link-widget-sandbox.grailpay.com/sdk.js"
74
- : "https://bank-link-widget.grailpay.com/sdk.js"
317
+ let sdkURL = EnvironmentConfig.grailPaySDKURL
318
+ let baseURL = URL(string: EnvironmentConfig.grailPayBaseURL)
75
319
 
76
320
  let html = """
77
321
  <!DOCTYPE html>
@@ -112,7 +356,7 @@ public class GrailPayVC: UIViewController {
112
356
  window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'bankConnected', data: data });
113
357
  },
114
358
  onLinkedDefaultAccount: function(data) {
115
- console.log("Default Account", data);
359
+ console.log("Default Account selected:", data);
116
360
  window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'defaultAccountSelected', data: data });
117
361
  },
118
362
  onLinkExit: function(data) {
@@ -148,10 +392,6 @@ public class GrailPayVC: UIViewController {
148
392
  </html>
149
393
  """
150
394
 
151
- let baseURL = URL(string: request.isSandbox
152
- ? "https://bank-link-widget-sandbox.grailpay.com"
153
- : "https://bank-link-widget.grailpay.com")
154
-
155
395
  webView.loadHTMLString(html, baseURL: baseURL)
156
396
  }
157
397
 
@@ -188,23 +428,23 @@ extension GrailPayVC: WKScriptMessageHandler {
188
428
 
189
429
  switch type {
190
430
  case "bankConnected":
191
- if let data = body["data"] {
192
- print("All linked account data from GrailPay:", data)
431
+ if let data = body["data"] as? [[String: Any]] {
432
+ print("All linked accounts:", data)
433
+ self.allLinkedAccounts = data
193
434
  }
194
435
 
195
436
  case "defaultAccountSelected":
196
- guard let dataG = body["data"] as? [String: Any] else {
437
+ guard let selectedAccount = body["data"] as? [String: Any] else {
197
438
  print("No account data selected")
198
439
  return
199
440
  }
200
441
 
201
- print("Received defaultAccountSelected: \(dataG)")
442
+ print(" Selected default account: \(selectedAccount)")
202
443
 
203
444
  if !didHandleBankConnection {
204
445
  didHandleBankConnection = true
205
- let dataArray: [[String: Any]] = [dataG]
206
446
  DispatchQueue.main.async {
207
- self.onCompletion?(SDKResult(type: .success, chargeData: ["data": dataArray]))
447
+ self.onCompletion?(SDKResult(type: .success, chargeData: ["data": [selectedAccount]]))
208
448
  self.dismiss(animated: true)
209
449
  }
210
450
  }