@jimrising/easymerchantsdk-react-native 1.2.8 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/caches/deviceStreaming.xml +11 -0
- package/.idea/workspace.xml +19 -15
- package/README.md +46 -35
- package/ios/Classes/EasyMerchantSdk.m +7 -65
- package/ios/Classes/EasyMerchantSdk.swift +70 -150
- package/ios/Classes/EasyPayViewController.swift +4 -0
- package/ios/Classes/dsd +74 -0
- package/ios/EnvironmentConfig.swift +4 -0
- package/ios/Example/ViewController.swift +72 -36
- package/ios/Helper/GrailPayHelper.swift +19 -0
- package/ios/Models/Request.swift +138 -142
- package/ios/Pods/UserDefaults/UserStoreSingleton.swift +21 -5
- package/ios/Pods/ViewControllers/GrailPayVC.swift +220 -0
- package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +632 -436
- package/ios/easymerchantsdk.podspec +3 -1
- package/ios/easymerchantsdk.storyboard +4092 -45
- package/package.json +1 -1
|
@@ -207,12 +207,28 @@ class UserStoreSingleton: NSObject {
|
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
|
|
210
|
-
func updateThemeConfiguration(with json: [String: Any]) {
|
|
211
|
-
json.forEach { key, value in
|
|
212
|
-
UserDefaults.standard.set(value, forKey: key)
|
|
210
|
+
// func updateThemeConfiguration(with json: [String: Any]) {
|
|
211
|
+
// json.forEach { key, value in
|
|
212
|
+
// UserDefaults.standard.set(value, forKey: key)
|
|
213
|
+
// }
|
|
214
|
+
// }
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
func updateThemeConfiguration(with themeConfiguration: ThemeConfiguration) {
|
|
218
|
+
self.body_bg_col = themeConfiguration.bodyBackgroundColor
|
|
219
|
+
self.container_bg_col = themeConfiguration.containerBackgroundColor
|
|
220
|
+
self.primary_font_col = themeConfiguration.primaryFontColor
|
|
221
|
+
self.secondary_font_col = themeConfiguration.secondaryFontColor
|
|
222
|
+
self.primary_btn_bg_col = themeConfiguration.primaryButtonBackgroundColor
|
|
223
|
+
self.primary_btn_hover_col = themeConfiguration.primaryButtonHoverColor
|
|
224
|
+
self.primary_btn_font_col = themeConfiguration.primaryButtonFontColor
|
|
225
|
+
self.secondary_btn_bg_col = themeConfiguration.secondaryButtonBackgroundColor
|
|
226
|
+
self.secondary_btn_hover_col = themeConfiguration.secondaryButtonHoverColor
|
|
227
|
+
self.secondary_btn_font_col = themeConfiguration.secondaryFontColor
|
|
228
|
+
self.border_radious = themeConfiguration.borderRadius
|
|
229
|
+
self.fontSize = themeConfiguration.fontSize
|
|
213
230
|
}
|
|
214
|
-
|
|
215
|
-
|
|
231
|
+
|
|
216
232
|
// Method to clear user data from UserDefaults
|
|
217
233
|
func clearUserData() {
|
|
218
234
|
UserDefaults.standard.removeObject(forKey: "customer_id")
|
|
@@ -0,0 +1,220 @@
|
|
|
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
|
+
|
|
17
|
+
public var onCompletion: ((Result) -> Void)?
|
|
18
|
+
|
|
19
|
+
public init(request: GrailPayRequest) {
|
|
20
|
+
self.request = request
|
|
21
|
+
super.init(nibName: nil, bundle: nil)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
required init?(coder: NSCoder) {
|
|
25
|
+
fatalError("init(coder:) has not been implemented")
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private var didHandleBankConnection = false
|
|
29
|
+
|
|
30
|
+
override public func viewDidLoad() {
|
|
31
|
+
super.viewDidLoad()
|
|
32
|
+
setupUI()
|
|
33
|
+
loadGrailPaySDK()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private func setupUI() {
|
|
37
|
+
view.backgroundColor = .white
|
|
38
|
+
|
|
39
|
+
let webConfig = WKWebViewConfiguration()
|
|
40
|
+
webConfig.userContentController.add(self, name: "grailpayHandler")
|
|
41
|
+
webConfig.allowsInlineMediaPlayback = true
|
|
42
|
+
webConfig.mediaTypesRequiringUserActionForPlayback = []
|
|
43
|
+
|
|
44
|
+
webView = WKWebView(frame: view.bounds, configuration: webConfig)
|
|
45
|
+
webView.navigationDelegate = self
|
|
46
|
+
webView.uiDelegate = self
|
|
47
|
+
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
48
|
+
view.addSubview(webView)
|
|
49
|
+
|
|
50
|
+
loadingIndicator = UIActivityIndicatorView(style: .large)
|
|
51
|
+
loadingIndicator.center = view.center
|
|
52
|
+
loadingIndicator.hidesWhenStopped = true
|
|
53
|
+
view.addSubview(loadingIndicator)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private func loadGrailPaySDK() {
|
|
57
|
+
loadingIndicator.startAnimating()
|
|
58
|
+
|
|
59
|
+
WKWebsiteDataStore.default().removeData(ofTypes: [WKWebsiteDataTypeCookies], modifiedSince: Date(timeIntervalSince1970: 0)) { [weak self] in
|
|
60
|
+
guard let self = self else { return }
|
|
61
|
+
|
|
62
|
+
let sdkURL = self.request.isSandbox ?
|
|
63
|
+
"https://bank-link-widget-sandbox.grailpay.com/sdk.js" :
|
|
64
|
+
"https://bank-link-widget.grailpay.com/sdk.js"
|
|
65
|
+
|
|
66
|
+
let html = """
|
|
67
|
+
<!DOCTYPE html>
|
|
68
|
+
<html>
|
|
69
|
+
<head>
|
|
70
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
71
|
+
<script>
|
|
72
|
+
window.sdkInitialized = false;
|
|
73
|
+
|
|
74
|
+
function initializeSDK() {
|
|
75
|
+
if (window.sdkInitialized) return;
|
|
76
|
+
|
|
77
|
+
if (typeof window.grailpay === 'undefined') {
|
|
78
|
+
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: 'SDK not loaded' });
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
window.grailpay.init({
|
|
83
|
+
token: '\(self.request.accessToken)',
|
|
84
|
+
vendorId: '\(self.request.vendorId)',
|
|
85
|
+
role: '\(self.request.role)',
|
|
86
|
+
timeout: \(self.request.timeout),
|
|
87
|
+
theme: {
|
|
88
|
+
branding_name: '\(self.request.brandingName)',
|
|
89
|
+
screens: {
|
|
90
|
+
finder: {
|
|
91
|
+
subtitle: '\(self.request.finderSubtitle)',
|
|
92
|
+
searchPlaceholder: '\(self.request.searchPlaceholder)'
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
onError: function(error) {
|
|
97
|
+
console.log("JS onError:", error);
|
|
98
|
+
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: error });
|
|
99
|
+
},
|
|
100
|
+
onBankConnected: function(data) {
|
|
101
|
+
console.log("✅ Bank connected:", data);
|
|
102
|
+
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'bankConnected', data: data });
|
|
103
|
+
},
|
|
104
|
+
onLinkExit: function(data) {
|
|
105
|
+
console.log("⚠️ User exited:", data);
|
|
106
|
+
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'linkExit', data: data });
|
|
107
|
+
}
|
|
108
|
+
}).then(function() {
|
|
109
|
+
window.sdkInitialized = true;
|
|
110
|
+
window.grailpay.open();
|
|
111
|
+
}).catch(function(error) {
|
|
112
|
+
console.log("❌ SDK init failed:", error);
|
|
113
|
+
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: error });
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function loadSDK() {
|
|
118
|
+
const script = document.createElement('script');
|
|
119
|
+
script.src = '\(sdkURL)';
|
|
120
|
+
script.onload = function() {
|
|
121
|
+
setTimeout(initializeSDK, 1000);
|
|
122
|
+
};
|
|
123
|
+
script.onerror = function(error) {
|
|
124
|
+
console.log("❌ Failed to load SDK script");
|
|
125
|
+
window.webkit.messageHandlers.grailpayHandler.postMessage({ type: 'error', data: 'Failed to load SDK script' });
|
|
126
|
+
};
|
|
127
|
+
document.head.appendChild(script);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
document.addEventListener('DOMContentLoaded', loadSDK);
|
|
131
|
+
</script>
|
|
132
|
+
</head>
|
|
133
|
+
<body style="margin: 0; padding: 0;"></body>
|
|
134
|
+
</html>
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
let baseURL = URL(string: self.request.isSandbox ? "https://bank-link-widget-sandbox.grailpay.com" : "https://bank-link-widget.grailpay.com")
|
|
138
|
+
self.webView.loadHTMLString(html, baseURL: baseURL)
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private func handleError(_ error: Error) {
|
|
143
|
+
DispatchQueue.main.async {
|
|
144
|
+
self.loadingIndicator.stopAnimating()
|
|
145
|
+
let nsError = error as NSError
|
|
146
|
+
self.onCompletion?(Result(error: nsError))
|
|
147
|
+
self.dismiss(animated: true)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
extension GrailPayVC: WKNavigationDelegate {
|
|
153
|
+
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
|
154
|
+
loadingIndicator.stopAnimating()
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
|
158
|
+
handleError(error)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
extension GrailPayVC: WKScriptMessageHandler {
|
|
163
|
+
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
164
|
+
print("📩 JS Message received: \(message.body)")
|
|
165
|
+
|
|
166
|
+
guard let body = message.body as? [String: Any],
|
|
167
|
+
let type = body["type"] as? String else {
|
|
168
|
+
print("⚠️ Malformed message")
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
switch type {
|
|
173
|
+
case "bankConnected":
|
|
174
|
+
guard let dataArray = body["data"] as? [[String: Any]], let firstAccount = dataArray.first else {
|
|
175
|
+
print("⚠️ No valid accounts in bankConnected")
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if !didHandleBankConnection {
|
|
180
|
+
didHandleBankConnection = true // ✅ Prevent duplicate triggers
|
|
181
|
+
print("✅ Received bankConnected: \(firstAccount)")
|
|
182
|
+
|
|
183
|
+
DispatchQueue.main.async {
|
|
184
|
+
self.onCompletion?(Result(type: .success, chargeData: ["data": dataArray]))
|
|
185
|
+
self.dismiss(animated: true)
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
case "linkExit":
|
|
190
|
+
if didHandleBankConnection {
|
|
191
|
+
print("ℹ️ linkExit ignored because success already handled")
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
print("⚠️ Received linkExit")
|
|
195
|
+
DispatchQueue.main.async {
|
|
196
|
+
self.onCompletion?(Result(type: .cancelled))
|
|
197
|
+
self.dismiss(animated: true)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
case "error":
|
|
201
|
+
let errorMessage = (body["data"] as? String) ?? "Unknown error"
|
|
202
|
+
let error = NSError(domain: "GrailPayError", code: 0, userInfo: [NSLocalizedDescriptionKey: errorMessage])
|
|
203
|
+
print("❌ GrailPay JS error: \(errorMessage)")
|
|
204
|
+
handleError(error)
|
|
205
|
+
|
|
206
|
+
default:
|
|
207
|
+
print("ℹ️ Unknown JS message type: \(type)")
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
extension GrailPayVC: WKUIDelegate {
|
|
214
|
+
public func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
|
|
215
|
+
if navigationAction.targetFrame == nil {
|
|
216
|
+
webView.load(navigationAction.request)
|
|
217
|
+
}
|
|
218
|
+
return nil
|
|
219
|
+
}
|
|
220
|
+
}
|