@jimrising/easymerchantsdk-react-native 2.0.6 → 2.0.9

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 (128) hide show
  1. package/README.md +134 -1783
  2. package/android/build/.transforms/15b6a8a60a6b32d0dcaf609723cf365b/transformed/classes/classes_dex/classes.dex +0 -0
  3. package/android/build/.transforms/8508f1428f740032c45a43f48b1bbe1e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$1$1.dex +0 -0
  4. package/android/build/.transforms/8508f1428f740032c45a43f48b1bbe1e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$1.dex +0 -0
  5. package/android/build/.transforms/8508f1428f740032c45a43f48b1bbe1e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  6. package/android/build/.transforms/8508f1428f740032c45a43f48b1bbe1e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  7. package/android/build/.transforms/eef2d06269ef2e204b4f065513034fca/transformed/classes/classes_dex/classes.dex +0 -0
  8. package/android/build/.transforms/ffabb40f9809b32eb9546ce76fc51764/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule$1$1.dex +0 -0
  9. package/android/build/.transforms/ffabb40f9809b32eb9546ce76fc51764/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule$1.dex +0 -0
  10. package/android/build/.transforms/ffabb40f9809b32eb9546ce76fc51764/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule$2.dex +0 -0
  11. package/android/build/.transforms/ffabb40f9809b32eb9546ce76fc51764/transformed/bundleLibRuntimeToDirRelease/bundleLibRuntimeToDirRelease_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
  12. package/android/build/intermediates/aar_main_jar/release/syncReleaseLibJars/classes.jar +0 -0
  13. package/android/build/intermediates/compile_library_classes_jar/debug/bundleLibCompileToJarDebug/classes.jar +0 -0
  14. package/android/build/intermediates/compile_library_classes_jar/release/bundleLibCompileToJarRelease/classes.jar +0 -0
  15. package/android/build/intermediates/full_jar/release/createFullJarRelease/full.jar +0 -0
  16. package/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties +1 -1
  17. package/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml +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 +526 -525
  21. package/android/build/intermediates/incremental/release/mergeReleaseResources/merged.dir/values/values.xml +1 -1
  22. package/android/build/intermediates/incremental/release/mergeReleaseResources/merger.xml +3 -3
  23. package/android/build/intermediates/incremental/release/packageReleaseResources/compile-file-map.properties +1 -1
  24. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  25. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  26. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  27. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  28. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  29. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  30. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  31. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  32. package/android/build/intermediates/lint-cache/lintVitalAnalyzeRelease/maven.google/androidx/core/group-index.xml +4 -3
  33. package/android/build/intermediates/lint-cache/lintVitalAnalyzeRelease/maven.google/androidx/lifecycle/group-index.xml +165 -165
  34. package/android/build/intermediates/lint-cache/lintVitalAnalyzeRelease/maven.google/com/android/tools/build/group-index.xml +15 -15
  35. package/android/build/intermediates/lint-cache/lintVitalAnalyzeRelease/maven.google/master-index.xml +1 -0
  36. package/android/build/intermediates/lint-cache/lintVitalAnalyzeRelease/sdk_index/snapshot.gz +0 -0
  37. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-dependencies.xml +4 -4
  38. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-libraries.xml +4 -4
  39. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-dependencies.xml +4 -4
  40. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-libraries.xml +4 -4
  41. package/android/build/intermediates/local_aar_for_lint/release/out.aar +0 -0
  42. package/android/build/intermediates/merged_res/release/mergeReleaseResources/drawable/close_icon_main.xml +16 -0
  43. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_card_addition_ifo.xml +1 -0
  44. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_card_billing_info.xml +1 -0
  45. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_card_scan.xml +1 -0
  46. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_payment_done.xml +1 -0
  47. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_payment_done_url.xml +3 -3
  48. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_payment_error.xml +1 -0
  49. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_select_payment_method.xml +25 -6
  50. package/android/build/intermediates/merged_res/release/mergeReleaseResources/layout/activity_verify_email.xml +1 -0
  51. package/android/build/intermediates/merged_res/release/mergeReleaseResources/values/values.xml +1 -1
  52. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/multi-v2/values-night-v8.json +2 -2
  53. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/multi-v2/values.json +102 -102
  54. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/anim-v21.json +8 -8
  55. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/anim.json +23 -23
  56. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/animator-v21.json +1 -1
  57. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/animator.json +26 -26
  58. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color-night-v8.json +3 -3
  59. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color-v31.json +10 -10
  60. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/color.json +153 -153
  61. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-hdpi-v4.json +1 -1
  62. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-mdpi-v4.json +1 -1
  63. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v21.json +3 -3
  64. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-v23.json +7 -7
  65. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xhdpi-v4.json +1 -1
  66. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xxhdpi-v4.json +1 -1
  67. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable-xxxhdpi-v4.json +1 -1
  68. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/drawable.json +141 -137
  69. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/font.json +9 -9
  70. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/interpolator-v21.json +10 -10
  71. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/interpolator.json +11 -11
  72. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-land.json +3 -3
  73. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-sw600dp-v13.json +2 -2
  74. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout-v26.json +1 -1
  75. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/layout.json +93 -93
  76. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-anydpi-v26.json +2 -2
  77. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-hdpi-v4.json +2 -2
  78. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-mdpi-v4.json +2 -2
  79. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xhdpi-v4.json +2 -2
  80. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xxhdpi-v4.json +2 -2
  81. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/mipmap-xxxhdpi-v4.json +2 -2
  82. package/android/build/intermediates/merged_res_blame_folder/release/mergeReleaseResources/out/single/xml.json +3 -3
  83. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  84. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  85. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  86. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  87. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  88. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  89. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  90. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  91. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  92. package/android/build/intermediates/runtime_library_classes_jar/release/bundleLibRuntimeToJarRelease/classes.jar +0 -0
  93. package/android/build/intermediates/source_set_path_map/release/mapReleaseSourceSetPaths/file-map.txt +8 -8
  94. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/drawable_close_icon_main.xml.flat +0 -0
  95. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_card_addition_ifo.xml.flat +0 -0
  96. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_card_billing_info.xml.flat +0 -0
  97. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_card_scan.xml.flat +0 -0
  98. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_payment_done.xml.flat +0 -0
  99. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_payment_done_url.xml.flat +0 -0
  100. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_payment_error.xml.flat +0 -0
  101. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_select_payment_method.xml.flat +0 -0
  102. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/layout_activity_verify_email.xml.flat +0 -0
  103. package/android/build/intermediates/verified_library_resources/release/verifyReleaseResources/compiled/values_values.arsc.flat +0 -0
  104. package/android/build/outputs/aar/jimrising_easymerchantsdk-react-native-release.aar +0 -0
  105. package/android/build/outputs/logs/manifest-merger-debug-report.txt +10 -10
  106. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1$1.class.uniqueId1 +0 -0
  107. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1.class.uniqueId0 +0 -0
  108. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$2.class.uniqueId3 +0 -0
  109. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule.class.uniqueId2 +0 -0
  110. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkPackage.class.uniqueId4 +0 -0
  111. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  112. package/android/build/tmp/compileReleaseJavaWithJavac/previous-compilation-data.bin +0 -0
  113. package/android/build.gradle +1 -1
  114. package/android/src/main/java/com/reactlibrary/RNEasymerchantsdkModule.java +93 -26
  115. package/ios/Classes/EasyMerchantSdk.m +4 -4
  116. package/ios/Classes/EasyMerchantSdk.swift +116 -60
  117. package/ios/Classes/EasyPayViewController.swift +3 -5
  118. package/ios/CustomComponents/CheckboxButton.swift +66 -0
  119. package/ios/Helper/GrailPayHelper.swift +1 -0
  120. package/ios/Models/Request.swift +8 -8
  121. package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +233 -97
  122. package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +376 -104
  123. package/ios/Pods/ViewControllers/OTPVerificationVC.swift +28 -27
  124. package/ios/Pods/ViewControllers/PaymentErrorVC.swift +22 -25
  125. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +575 -190
  126. package/ios/easymerchantsdk.podspec +1 -1
  127. package/ios/easymerchantsdk.storyboard +15 -15
  128. package/package.json +1 -1
@@ -1,7 +1,6 @@
1
1
  import Foundation
2
2
  import UIKit
3
3
  import React
4
- //import EasyPay // Import the EasyPay module
5
4
 
6
5
  @objc(EasyMerchantSdkPlugin)
7
6
  public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
@@ -10,8 +9,9 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
10
9
  public static func moduleName() -> String! {
11
10
  return "EasyMerchantSdk"
12
11
  }
13
-
12
+
14
13
  public static func requiresMainQueueSetup() -> Bool {
14
+ // We present view controllers and touch UIKit; main queue required.
15
15
  return true
16
16
  }
17
17
 
@@ -23,9 +23,12 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
23
23
  private var paymentReferenceResolver: RCTPromiseResolveBlock?
24
24
  private var paymentReferenceRejecter: RCTPromiseRejectBlock?
25
25
 
26
+ // MARK: - Notification tokens (so we can remove safely)
27
+ private var clientTokenObserver: NSObjectProtocol?
28
+ private var referenceObserver: NSObjectProtocol?
29
+
26
30
  // MARK: - View Controller Reference
27
- private let viewControllerQueue = DispatchQueue(label: "com.easymerchantsdk.viewController")
28
- private var viewController: UIViewController?
31
+ private weak var viewController: UIViewController?
29
32
 
30
33
  // MARK: - Init
31
34
  @objc public override init() {
@@ -40,8 +43,9 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
40
43
 
41
44
  // Expose setter for RN to inject the host view controller
42
45
  @objc public func setViewController(_ vc: UIViewController) {
43
- viewControllerQueue.sync {
44
- self.viewController = vc
46
+ // Always set on main thread; keep a weak ref to avoid retain cycles.
47
+ DispatchQueue.main.async { [weak self] in
48
+ self?.viewController = vc
45
49
  }
46
50
  }
47
51
 
@@ -58,9 +62,9 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
58
62
  @objc public func billing(
59
63
  _ amount: String,
60
64
  currency: String?,
61
- billingInfo: [String: Any]?,
65
+ fields: [String: Any]?,
62
66
  paymentMethods: [String],
63
- themeConfiguration: [String: Any]?,
67
+ appearanceSettings: [String: Any]?,
64
68
  tokenOnly: Bool,
65
69
  saveCard: Bool,
66
70
  saveAccount: Bool,
@@ -76,11 +80,11 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
76
80
  showReceipt: Bool,
77
81
  showTotal: Bool,
78
82
  showSubmitButton: Bool,
79
- isEmail : Bool,
83
+ isEmail: Bool,
80
84
  email: String?,
81
85
  name: String?,
82
86
  enable3DS: Bool,
83
- metadata: [String: Any]?,
87
+ metadata: [String: Any]?,
84
88
  resolver: @escaping RCTPromiseResolveBlock,
85
89
  rejecter: @escaping RCTPromiseRejectBlock
86
90
  ) {
@@ -92,7 +96,7 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
92
96
 
93
97
  // 2) Process billing info into FieldSection
94
98
  var billingInfoData: Data? = nil
95
- if let billingDict = billingInfo {
99
+ if let billingDict = fields {
96
100
  var billingFields: [FieldItem] = []
97
101
  var additionalFields: [FieldItem] = []
98
102
  var billingVisibility = true
@@ -126,14 +130,14 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
126
130
  additionalVisibility = visibility["additional"] ?? true
127
131
  }
128
132
 
129
- let fields = FieldSection(
133
+ let field = FieldSection(
130
134
  visibility: FieldsVisibility(billing: billingVisibility, additional: additionalVisibility),
131
135
  billing: billingFields,
132
136
  additional: additionalFields
133
137
  )
134
138
 
135
139
  do {
136
- billingInfoData = try JSONEncoder().encode(fields)
140
+ billingInfoData = try JSONEncoder().encode(field)
137
141
  } catch {
138
142
  rejecter("INVALID_BILLING_INFO", "Failed to encode billing info: \(error.localizedDescription)", nil)
139
143
  return
@@ -155,8 +159,6 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
155
159
  var grailParams: GrailPayRequest? = nil
156
160
  if authenticatedACH, let params = grailPayParams {
157
161
  grailParams = GrailPayRequest(
158
- // accessToken: params["accessToken"] as? String ?? "251|uTijpDGfrS88UR2V1cZNMQ8S4hUJA0sVzsnsoUZF",
159
- // vendorId: params["vendorId"] as? String ?? "251",
160
162
  role: params["role"] as? String ?? "business",
161
163
  timeout: params["timeout"] as? Int ?? 10,
162
164
  isSandbox: params["isSandbox"] as? Bool ?? true,
@@ -168,20 +170,20 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
168
170
 
169
171
  // 5) Build theme config
170
172
  let themeConfig = ThemeConfiguration(
171
- bodyBackgroundColor: themeConfiguration?["bodyBackgroundColor"] as? String ?? "#121212",
172
- containerBackgroundColor: themeConfiguration?["containerBackgroundColor"] as? String ?? "#1E1E1E",
173
- primaryFontColor: themeConfiguration?["primaryFontColor"] as? String ?? "#FFFFFF",
174
- secondaryFontColor: themeConfiguration?["secondaryFontColor"] as? String ?? "#B0B0B0",
175
- primaryButtonBackgroundColor: themeConfiguration?["primaryButtonBackgroundColor"] as? String ?? "#2563EB",
176
- primaryButtonHoverColor: themeConfiguration?["primaryButtonHoverColor"] as? String ?? "#1D4ED8",
177
- primaryButtonFontColor: themeConfiguration?["primaryButtonFontColor"] as? String ?? "#FFFFFF",
178
- secondaryButtonBackgroundColor: themeConfiguration?["secondaryButtonBackgroundColor"] as? String ?? "#374151",
179
- secondaryButtonHoverColor: themeConfiguration?["secondaryButtonHoverColor"] as? String ?? "#4B5563",
180
- secondaryButtonFontColor: themeConfiguration?["secondaryButtonFontColor"] as? String ?? "#E5E7EB",
181
- borderRadius: themeConfiguration?["borderRadius"] as? String ?? "8",
182
- fontSize: themeConfiguration?["fontSize"] as? String ?? "14",
183
- fontWeight: themeConfiguration?["fontWeight"] as? Int ?? 500,
184
- fontFamily: themeConfiguration?["fontFamily"] as? String ?? "\"Inter\", sans-serif"
173
+ bodyBackgroundColor: appearanceSettings?["bodyBackgroundColor"] as? String ?? "#121212",
174
+ containerBackgroundColor: appearanceSettings?["containerBackgroundColor"] as? String ?? "#1E1E1E",
175
+ primaryFontColor: appearanceSettings?["primaryFontColor"] as? String ?? "#FFFFFF",
176
+ secondaryFontColor: appearanceSettings?["secondaryFontColor"] as? String ?? "#B0B0B0",
177
+ primaryButtonBackgroundColor: appearanceSettings?["primaryButtonBackgroundColor"] as? String ?? "#2563EB",
178
+ primaryButtonHoverColor: appearanceSettings?["primaryButtonHoverColor"] as? String ?? "#1D4ED8",
179
+ primaryButtonFontColor: appearanceSettings?["primaryButtonFontColor"] as? String ?? "#FFFFFF",
180
+ secondaryButtonBackgroundColor: appearanceSettings?["secondaryButtonBackgroundColor"] as? String ?? "#374151",
181
+ secondaryButtonHoverColor: appearanceSettings?["secondaryButtonHoverColor"] as? String ?? "#4B5563",
182
+ secondaryButtonFontColor: appearanceSettings?["secondaryButtonFontColor"] as? String ?? "#E5E7EB",
183
+ borderRadius: appearanceSettings?["borderRadius"] as? String ?? "8",
184
+ fontSize: appearanceSettings?["fontSize"] as? String ?? "14",
185
+ fontWeight: appearanceSettings?["fontWeight"] as? Int ?? 500,
186
+ fontFamily: appearanceSettings?["fontFamily"] as? String ?? "\"Inter\", sans-serif"
185
187
  )
186
188
 
187
189
  // 6) Map recurring intervals
@@ -209,9 +211,9 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
209
211
  let request = Request(
210
212
  amount: amountValue,
211
213
  currency: currency ?? "usd",
212
- billingInfoData: billingInfoData,
214
+ fields: billingInfoData,
213
215
  paymentMethods: methods.isEmpty ? [.Card, .Bank] : methods,
214
- themeConfiguration: themeConfig,
216
+ appearanceSettings: themeConfig,
215
217
  tokenOnly: tokenOnly,
216
218
  saveCard: saveCard,
217
219
  saveAccount: saveAccount,
@@ -229,8 +231,8 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
229
231
  showSubmitButton: showSubmitButton,
230
232
  referenceID: enable3DS,
231
233
  referenceToken: nil,
232
- isEmail : isEmail,
233
- email:email,
234
+ isEmail: isEmail,
235
+ email: email,
234
236
  name: name,
235
237
  metadata: metadata
236
238
  )
@@ -241,7 +243,9 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
241
243
 
242
244
  // Handle tokenOnly or present EasyPayViewController
243
245
  if tokenOnly {
244
- NotificationCenter.default.addObserver(
246
+ // Register observer directly (no extra Dispatch wrapper).
247
+ // Store the token so we can remove it later.
248
+ clientTokenObserver = NotificationCenter.default.addObserver(
245
249
  forName: NSNotification.Name("ClientTokenReceived"),
246
250
  object: nil,
247
251
  queue: .main
@@ -255,11 +259,14 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
255
259
  self.clearResolvers()
256
260
  }
257
261
  } else {
258
- DispatchQueue.main.async {
262
+ // Always present on main thread
263
+ DispatchQueue.main.async { [weak self] in
264
+ guard let self = self else { return }
259
265
  let vc = EasyPayViewController(request: request, delegate: self)
266
+
260
267
  if let host = self.viewController {
261
268
  host.present(vc, animated: true, completion: nil)
262
- } else if let root = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController {
269
+ } else if let root = Self.topMostViewController() {
263
270
  root.present(vc, animated: true, completion: nil)
264
271
  } else {
265
272
  rejecter("NO_VIEW_CONTROLLER", "Cannot find a view controller to present.", nil)
@@ -285,27 +292,25 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
285
292
  self.paymentReferenceResolver = resolver
286
293
  self.paymentReferenceRejecter = rejecter
287
294
 
288
- // Build the request object
289
- let request = Request(
295
+ // Build the request object (kept for parity; actual flow listens for a notification)
296
+ _ = Request(
290
297
  referenceID: true,
291
298
  referenceToken: referenceToken
292
299
  )
293
300
 
294
- // Set up notification observer for ReferenceIDResponse
295
- DispatchQueue.main.async {
296
- NotificationCenter.default.addObserver(
297
- forName: NSNotification.Name("ReferenceIDResponse"),
298
- object: nil,
299
- queue: .main
300
- ) { [weak self] notification in
301
- guard let self = self else { return }
302
- if let data = notification.object as? [String: Any] {
303
- self.paymentReferenceResolver?(data)
304
- } else {
305
- self.paymentReferenceRejecter?("INVALID_RESPONSE", "Invalid response data.", nil)
306
- }
307
- self.clearReferenceResolvers()
301
+ // Register observer directly (no outer Dispatch wrapper).
302
+ referenceObserver = NotificationCenter.default.addObserver(
303
+ forName: NSNotification.Name("ReferenceIDResponse"),
304
+ object: nil,
305
+ queue: .main
306
+ ) { [weak self] notification in
307
+ guard let self = self else { return }
308
+ if let data = notification.object as? [String: Any] {
309
+ self.paymentReferenceResolver?(data)
310
+ } else {
311
+ self.paymentReferenceRejecter?("INVALID_RESPONSE", "Invalid response data.", nil)
308
312
  }
313
+ self.clearReferenceResolvers()
309
314
  }
310
315
  }
311
316
 
@@ -321,28 +326,70 @@ public class EasyMerchantSdkPlugin: NSObject, RCTBridgeModule {
321
326
  private func clearResolvers() {
322
327
  billingResolver = nil
323
328
  billingRejecter = nil
329
+ if let token = clientTokenObserver {
330
+ NotificationCenter.default.removeObserver(token)
331
+ clientTokenObserver = nil
332
+ }
324
333
  }
325
334
 
326
335
  private func clearReferenceResolvers() {
327
336
  paymentReferenceResolver = nil
328
337
  paymentReferenceRejecter = nil
329
- NotificationCenter.default.removeObserver(self, name: NSNotification.Name("ReferenceIDResponse"), object: nil)
338
+ if let token = referenceObserver {
339
+ NotificationCenter.default.removeObserver(token)
340
+ referenceObserver = nil
341
+ }
342
+ // (Old approach of removing by name kept out to avoid double-removal.)
343
+ }
344
+
345
+ // Find a top-most VC safely (iOS 13+ friendly)
346
+ private static func topMostViewController(base: UIViewController? = {
347
+ // Use key window from connected scenes
348
+ return UIApplication.shared.connectedScenes
349
+ .compactMap { $0 as? UIWindowScene }
350
+ .flatMap { $0.windows }
351
+ .first(where: { $0.isKeyWindow })?
352
+ .rootViewController
353
+ }()) -> UIViewController? {
354
+ if let nav = base as? UINavigationController {
355
+ return topMostViewController(base: nav.visibleViewController)
356
+ }
357
+ if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
358
+ return topMostViewController(base: selected)
359
+ }
360
+ if let presented = base?.presentedViewController {
361
+ return topMostViewController(base: presented)
362
+ }
363
+ return base
330
364
  }
331
365
  }
332
366
 
333
367
  // MARK: - Delegate Implementation
334
368
  extension EasyMerchantSdkPlugin: EasyPayViewControllerDelegate {
335
369
  public func easyPayController(_ controller: EasyPayViewController, didFinishWith result: SDKResult) {
336
- DispatchQueue.main.async {
370
+ let workItem = DispatchWorkItem { [weak self] in
371
+ guard let self = self else { return }
372
+
337
373
  switch result.type {
338
374
  case .cancelled:
339
- self.billingResolver?(["status": "cancelled", "message": "User cancelled"])
375
+ if let message = result.chargeData?["message"] as? String {
376
+ self.billingResolver?(["status": "cancelled", "message": message])
377
+ } else {
378
+ self.billingResolver?(["status": "cancelled"])
379
+ }
340
380
 
341
381
  case .success:
342
382
  var payload: [String: Any] = ["status": "success"]
343
- if let cd = result.chargeData { payload["chargeData"] = cd }
344
- if let bi = result.billingInfo { payload["billingInfo"] = bi }
345
- if let ai = result.additionalInfo { payload["additionalInfo"] = ai }
383
+
384
+ if let cd = result.chargeData {
385
+ payload["chargeData"] = cd
386
+ }
387
+ if let bi = result.billingInfo {
388
+ payload["billingInfo"] = bi
389
+ }
390
+ if let ai = result.additionalInfo {
391
+ payload["additionalInfo"] = ai
392
+ }
346
393
 
347
394
  // Extract referenceToken for 3DS
348
395
  if let additional = result.additionalInfo,
@@ -355,12 +402,21 @@ extension EasyMerchantSdkPlugin: EasyPayViewControllerDelegate {
355
402
  self.billingResolver?(payload)
356
403
 
357
404
  case .error:
358
- let errMsg = (result.chargeData?["errorMessage"] as? String) ?? "Unknown error"
359
- self.billingRejecter?("PAYMENT_ERROR", errMsg, nil)
405
+ // Check for an errorMessage in chargeData.
406
+ let errorMessage = (result.chargeData?["message"] as? String) ?? "An unknown error occurred."
407
+
408
+ let errorResponse: [String: Any] = [
409
+ "status": false,
410
+ "message": errorMessage
411
+ ]
412
+
413
+ self.billingResolver?(errorResponse)
360
414
  }
361
415
 
362
416
  self.clearResolvers()
363
417
  controller.dismiss(animated: true, completion: nil)
364
418
  }
419
+
420
+ DispatchQueue.main.async(execute: workItem)
365
421
  }
366
422
  }
@@ -45,7 +45,7 @@ public final class EasyPayViewController: UINavigationController {
45
45
  self.easyPayDelegate = delegate
46
46
  super.init(nibName: nil, bundle: nil)
47
47
 
48
- if let themeConfiguration = request.themeConfiguration {
48
+ if let themeConfiguration = request.appearanceSettings {
49
49
  UserStoreSingleton.shared.updateThemeConfiguration(with: themeConfiguration)
50
50
  }
51
51
 
@@ -61,15 +61,13 @@ public final class EasyPayViewController: UINavigationController {
61
61
  let vc = UIStoryboard(name: "easymerchantsdk", bundle: Bundle.easyPayBundle).instantiateViewController(withIdentifier: "PaymentInfoVC") as! PaymentInfoVC
62
62
  vc.modalPresentationStyle = .overFullScreen
63
63
  vc.configureWith(request: request, delegate: easyPayDelegate)
64
- vc.amount = Double(self.request.amount ?? 0)
65
-
64
+ vc.amount = Double(self.request.amount ?? 0) // Set the amount here.
66
65
  vc.selectedPaymentMethod = "Card"
67
66
 
68
- // vc.logOut()
69
67
  self.navigationBar.isHidden = true
70
68
  self.setViewControllers([vc], animated: false)
71
69
  }
72
-
70
+
73
71
  }
74
72
 
75
73
  private extension EasyPayViewController {
@@ -0,0 +1,66 @@
1
+ //
2
+ // CheckboxButton.swift
3
+ // EasyPay
4
+ //
5
+ // Created by iftekhar on 14/07/24.
6
+ //
7
+
8
+ //import Foundation
9
+ //
10
+ //final class CheckboxButton: UIButton {
11
+ //
12
+ // override func awakeFromNib() {
13
+ // super.awakeFromNib()
14
+ // self.addTarget(self, action: #selector(tapAction(_:)), for: .touchUpInside)
15
+ // }
16
+ //
17
+ // @objc private func tapAction(_ sender: UIButton) {
18
+ // self.isSelected.toggle()
19
+ // }
20
+ //}
21
+
22
+
23
+ import UIKit
24
+
25
+ final class CheckboxButton: UIButton {
26
+
27
+ override func awakeFromNib() {
28
+ super.awakeFromNib()
29
+ self.addTarget(self, action: #selector(tapAction(_:)), for: .touchUpInside)
30
+ applyPrimaryColor() // Apply primary color when the button initializes
31
+ applySecondaryFontColor()
32
+ applyFontSize()
33
+ }
34
+
35
+ @objc private func tapAction(_ sender: UIButton) {
36
+ self.isSelected.toggle()
37
+ }
38
+
39
+ private func applyPrimaryColor() {
40
+ if let primaryBtnBackgroundColor = UserStoreSingleton.shared.primary_btn_bg_col,
41
+ let primaryUIColor = UIColor(hex: primaryBtnBackgroundColor) {
42
+
43
+ // Apply tintColor to the image
44
+ self.imageView?.tintColor = primaryUIColor
45
+ self.setImage(self.image(for: .normal)?.withRenderingMode(.alwaysTemplate), for: .normal)
46
+ self.setImage(self.image(for: .selected)?.withRenderingMode(.alwaysTemplate), for: .selected)
47
+ }
48
+ }
49
+
50
+ private func applySecondaryFontColor() {
51
+ if let secondaryFontColor = UserStoreSingleton.shared.secondary_font_col,
52
+ let fontUIColor = UIColor(hex: secondaryFontColor) {
53
+ self.setTitleColor(fontUIColor, for: .normal)
54
+ self.setTitleColor(fontUIColor, for: .selected)
55
+ }
56
+ }
57
+
58
+ private func applyFontSize() {
59
+ if let fontSizeString = UserStoreSingleton.shared.fontSize,
60
+ let fontSizeDouble = Double(fontSizeString) {
61
+ let fontSize = CGFloat(fontSizeDouble)
62
+ self.titleLabel?.font = UIFont.systemFont(ofSize: fontSize) // Apply font size to the button title
63
+ }
64
+ }
65
+
66
+ }
@@ -17,3 +17,4 @@ public class GrailPayHelper {
17
17
  viewController.present(grailPayVC, animated: true)
18
18
  }
19
19
  }
20
+
@@ -148,8 +148,8 @@ public struct FieldSection: Codable {
148
148
  public final class Request: NSObject {
149
149
  public let amount: Double?
150
150
  public let currency: String?
151
- public let billingInfoData: Data?
152
- public let themeConfiguration: ThemeConfiguration?
151
+ public let fields: Data?
152
+ public let appearanceSettings: ThemeConfiguration?
153
153
  public let selectedPaymentMethods: [PaymentMethod]
154
154
  public let tokenOnly: Bool?
155
155
  public let saveCard: Bool?
@@ -177,9 +177,9 @@ public final class Request: NSObject {
177
177
  public init(
178
178
  amount: Double? = nil,
179
179
  currency: String? = nil,
180
- billingInfoData: Data? = nil,
180
+ fields: Data? = nil,
181
181
  paymentMethods: [PaymentMethod]? = nil,
182
- themeConfiguration: ThemeConfiguration? = nil,
182
+ appearanceSettings: ThemeConfiguration? = nil,
183
183
  tokenOnly: Bool = false,
184
184
  saveCard: Bool = false,
185
185
  saveAccount: Bool = false,
@@ -225,8 +225,8 @@ public final class Request: NSObject {
225
225
 
226
226
  self.amount = amount
227
227
  self.currency = currency
228
- self.billingInfoData = billingInfoData
229
- self.themeConfiguration = themeConfiguration
228
+ self.fields = fields
229
+ self.appearanceSettings = appearanceSettings
230
230
  self.tokenOnly = tokenOnly
231
231
  self.saveCard = saveCard
232
232
  self.saveAccount = saveAccount
@@ -273,7 +273,7 @@ public final class Request: NSObject {
273
273
  self.selectedPaymentMethods = savedMethods.compactMap { PaymentMethod(rawValue: $0) }
274
274
  }
275
275
  // ✅ Save theme configuration in UserStoreSingleton only if themeConfiguration is not nil or empty
276
- if let themeConfig = themeConfiguration {
276
+ if let themeConfig = appearanceSettings {
277
277
  UserStoreSingleton.shared.body_bg_col = themeConfig.bodyBackgroundColor
278
278
  UserStoreSingleton.shared.container_bg_col = themeConfig.containerBackgroundColor
279
279
  UserStoreSingleton.shared.primary_font_col = themeConfig.primaryFontColor
@@ -624,7 +624,7 @@ public final class Request: NSObject {
624
624
  print("Saved payment methods: \(paymentMethodNames)")
625
625
  }
626
626
 
627
- if self.themeConfiguration == nil, let appearanceSettings = dataObject["apperance_settings"] as? [String: Any] {
627
+ if self.appearanceSettings == nil, let appearanceSettings = dataObject["apperance_settings"] as? [String: Any] {
628
628
  UserStoreSingleton.shared.body_bg_col = appearanceSettings["body_bg_col"] as? String
629
629
  UserStoreSingleton.shared.border_radious = appearanceSettings["border_radious"] as? String
630
630
  UserStoreSingleton.shared.container_bg_col = appearanceSettings["container_bg_col"] as? String