@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
|
@@ -69,6 +69,17 @@
|
|
|
69
69
|
<option name="screenX" value="1080" />
|
|
70
70
|
<option name="screenY" value="2340" />
|
|
71
71
|
</PersistentDeviceSelectionData>
|
|
72
|
+
<PersistentDeviceSelectionData>
|
|
73
|
+
<option name="api" value="34" />
|
|
74
|
+
<option name="brand" value="samsung" />
|
|
75
|
+
<option name="codename" value="a16x" />
|
|
76
|
+
<option name="id" value="a16x" />
|
|
77
|
+
<option name="manufacturer" value="Samsung" />
|
|
78
|
+
<option name="name" value="A16 5G" />
|
|
79
|
+
<option name="screenDensity" value="450" />
|
|
80
|
+
<option name="screenX" value="1080" />
|
|
81
|
+
<option name="screenY" value="2340" />
|
|
82
|
+
</PersistentDeviceSelectionData>
|
|
72
83
|
<PersistentDeviceSelectionData>
|
|
73
84
|
<option name="api" value="34" />
|
|
74
85
|
<option name="brand" value="samsung" />
|
package/.idea/workspace.xml
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
<component name="ChangeListManager">
|
|
7
7
|
<list default="true" id="3e2fa6c1-ea79-4c71-afdb-28176876a8c4" name="Changes" comment="">
|
|
8
8
|
<change afterPath="$PROJECT_DIR$/ios/EnvironmentConfig.swift" afterDir="false" />
|
|
9
|
+
<change afterPath="$PROJECT_DIR$/ios/Helper/GrailPayHelper.swift" afterDir="false" />
|
|
10
|
+
<change afterPath="$PROJECT_DIR$/ios/Pods/ViewControllers/GrailPayVC.swift" afterDir="false" />
|
|
9
11
|
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.gitignore" afterDir="false" />
|
|
10
12
|
<change beforePath="$PROJECT_DIR$/.idea/caches/deviceStreaming.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/caches/deviceStreaming.xml" afterDir="false" />
|
|
11
13
|
<change beforePath="$PROJECT_DIR$/.npmrc" beforeDir="false" afterPath="$PROJECT_DIR$/.npmrc" afterDir="false" />
|
|
@@ -149,25 +151,27 @@
|
|
|
149
151
|
<option name="hideEmptyMiddlePackages" value="true" />
|
|
150
152
|
<option name="showLibraryContents" value="true" />
|
|
151
153
|
</component>
|
|
152
|
-
<component name="PropertiesComponent"
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
154
|
+
<component name="PropertiesComponent"><![CDATA[{
|
|
155
|
+
"keyToString": {
|
|
156
|
+
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
157
|
+
"RunOnceActivity.cidr.known.project.marker": "true",
|
|
158
|
+
"RunOnceActivity.readMode.enableVisualFormatting": "true",
|
|
159
|
+
"cf.first.check.clang-format": "false",
|
|
160
|
+
"cidr.known.project.marker": "true",
|
|
161
|
+
"dart.analysis.tool.window.visible": "false",
|
|
162
|
+
"git-widget-placeholder": "dev-branch",
|
|
163
|
+
"kotlin-language-version-configured": "true",
|
|
164
|
+
"last_opened_file_path": "/Users/appdev/Documents/em-MobileCheckoutSDK-ReactNative/ios/Pods/ViewControllers",
|
|
165
|
+
"show.migrate.to.gradle.popup": "false",
|
|
166
|
+
"structure.view.defaults.are.configured": "true"
|
|
165
167
|
}
|
|
166
|
-
}
|
|
168
|
+
}]]></component>
|
|
167
169
|
<component name="RecentsManager">
|
|
168
170
|
<key name="CopyFile.RECENT_KEYS">
|
|
169
|
-
<recent name="$PROJECT_DIR$/ios/
|
|
171
|
+
<recent name="$PROJECT_DIR$/ios/Pods/ViewControllers" />
|
|
170
172
|
<recent name="$PROJECT_DIR$/ios" />
|
|
173
|
+
<recent name="$PROJECT_DIR$/ios/ThirdParty" />
|
|
174
|
+
<recent name="$PROJECT_DIR$/ios/Example" />
|
|
171
175
|
</key>
|
|
172
176
|
<key name="MoveFile.RECENT_KEYS">
|
|
173
177
|
<recent name="$PROJECT_DIR$/ios" />
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ To add the path of sdk in your project. Open your `package.json` file and inside
|
|
|
7
7
|
|
|
8
8
|
```json
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@jimrising/easymerchantsdk-react-native": "^1.
|
|
10
|
+
"@jimrising/easymerchantsdk-react-native": "^1.3.0"
|
|
11
11
|
},
|
|
12
12
|
```
|
|
13
13
|
|
|
@@ -136,9 +136,9 @@ const App = () => {
|
|
|
136
136
|
if (Platform.OS === 'ios') {
|
|
137
137
|
await EasyMerchantSdk.setViewController();
|
|
138
138
|
EasyMerchantSdk.configureEnvironment(
|
|
139
|
-
'
|
|
139
|
+
'staging', // sandbox , staging , production
|
|
140
140
|
'apiKey',
|
|
141
|
-
'
|
|
141
|
+
'secretKey'
|
|
142
142
|
);
|
|
143
143
|
}
|
|
144
144
|
|
|
@@ -185,51 +185,64 @@ const App = () => {
|
|
|
185
185
|
const handleBilling = async () => {
|
|
186
186
|
const amount = '72';
|
|
187
187
|
const billingInfo = {
|
|
188
|
-
address: '
|
|
189
|
-
country: '
|
|
190
|
-
state: '
|
|
191
|
-
city: '
|
|
192
|
-
postal_code: '
|
|
188
|
+
address: 'Test',
|
|
189
|
+
country: 'test',
|
|
190
|
+
state: 'test',
|
|
191
|
+
city: 'test',
|
|
192
|
+
postal_code: '234132',
|
|
193
193
|
additional_info: {
|
|
194
|
-
name: '
|
|
195
|
-
email: '
|
|
194
|
+
name: 'Test User',
|
|
195
|
+
email: 'test@gmail.com',
|
|
196
196
|
phone_number: '7888821587',
|
|
197
197
|
country_code: '91',
|
|
198
198
|
description: 'SDK Test'
|
|
199
199
|
}
|
|
200
200
|
};
|
|
201
201
|
|
|
202
|
-
const
|
|
203
|
-
bodyBackgroundColor: '#
|
|
204
|
-
containerBackgroundColor: '#
|
|
205
|
-
primaryFontColor: '#
|
|
206
|
-
secondaryFontColor: '#
|
|
207
|
-
primaryButtonBackgroundColor: '#
|
|
208
|
-
primaryButtonHoverColor: '#
|
|
209
|
-
primaryButtonFontColor: '#FFFFFF',
|
|
210
|
-
secondaryButtonBackgroundColor: '#
|
|
211
|
-
secondaryButtonHoverColor: '#
|
|
212
|
-
secondaryButtonFontColor: '#
|
|
213
|
-
borderRadius: '12',
|
|
214
|
-
fontSize: '16'
|
|
202
|
+
const themeConfiguration = {
|
|
203
|
+
bodyBackgroundColor: '#FFEEEE',
|
|
204
|
+
containerBackgroundColor: '#FFCCCC',
|
|
205
|
+
primaryFontColor: '#B30000',
|
|
206
|
+
secondaryFontColor: '#660000',
|
|
207
|
+
primaryButtonBackgroundColor: '#D50000',
|
|
208
|
+
primaryButtonHoverColor: '#9C0000',
|
|
209
|
+
primaryButtonFontColor: '#FFFFFF',
|
|
210
|
+
secondaryButtonBackgroundColor: '#FF6666',
|
|
211
|
+
secondaryButtonHoverColor: '#FF4D4D',
|
|
212
|
+
secondaryButtonFontColor: '#FFFFFF',
|
|
213
|
+
borderRadius: '12',
|
|
214
|
+
fontSize: '16'
|
|
215
215
|
};
|
|
216
216
|
|
|
217
217
|
|
|
218
218
|
|
|
219
|
+
|
|
219
220
|
try {
|
|
220
221
|
if (Platform.OS === 'android') {
|
|
221
222
|
const result = await RNEasymerchantsdk.billing(amount, null);
|
|
222
223
|
setResponse(`✅ Android Payment Success: ${result}`);
|
|
223
224
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
225
|
+
await EasyMerchantSdk.billing(
|
|
226
|
+
amount,
|
|
227
|
+
JSON.stringify(billingInfo),
|
|
228
|
+
['card', 'bank', 'crypto'],
|
|
229
|
+
themeConfiguration,
|
|
230
|
+
false, // tokenOnly
|
|
231
|
+
false, // saveCard
|
|
232
|
+
false, // saveAccount
|
|
233
|
+
true, // authenticatedACH
|
|
234
|
+
{
|
|
235
|
+
accessToken: "251|uTijpDGfrS88UR2V1cZNMQ8S4hUJA0sVzsnsoUZF",
|
|
236
|
+
vendorId: "251",
|
|
237
|
+
role: "business",
|
|
238
|
+
timeout: 10,
|
|
239
|
+
isSandbox: true,
|
|
240
|
+
brandingName: "Lyfecycle Payments",
|
|
241
|
+
finderSubtitle: "Search for your bank",
|
|
242
|
+
searchPlaceholder: "Enter bank name"
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
|
|
233
246
|
setResponse('🔁 Billing started on iOS. Awaiting response...');
|
|
234
247
|
}
|
|
235
248
|
} catch (error) {
|
|
@@ -281,10 +294,8 @@ const styles = StyleSheet.create({
|
|
|
281
294
|
}
|
|
282
295
|
});
|
|
283
296
|
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
|
|
287
297
|
|
|
298
|
+
```
|
|
288
299
|
|
|
289
300
|
You can send `null` if billing info not available.
|
|
290
301
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#import "EasyMerchantSdk.h"
|
|
2
2
|
#import <React/RCTLog.h>
|
|
3
3
|
#import <React/RCTBridgeModule.h>
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
//#import <easymerchantsdk/easymerchantsdk-Swift.h>
|
|
5
|
+
#import <easymerchantsdk-Swift.h>
|
|
6
6
|
|
|
7
7
|
@implementation EasyMerchantSdk
|
|
8
8
|
|
|
@@ -25,6 +25,8 @@ RCT_EXPORT_METHOD(
|
|
|
25
25
|
tokenOnly:(BOOL)tokenOnly
|
|
26
26
|
saveCard:(BOOL)saveCard
|
|
27
27
|
saveAccount:(BOOL)saveAccount
|
|
28
|
+
authenticatedACH:(BOOL)authenticatedACH
|
|
29
|
+
grailPayParams:(NSDictionary *)grailPayParams
|
|
28
30
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
29
31
|
rejecter:(RCTPromiseRejectBlock)reject
|
|
30
32
|
)
|
|
@@ -38,10 +40,13 @@ RCT_EXPORT_METHOD(
|
|
|
38
40
|
tokenOnly:tokenOnly
|
|
39
41
|
saveCard:saveCard
|
|
40
42
|
saveAccount:saveAccount
|
|
43
|
+
authenticatedACH:authenticatedACH
|
|
44
|
+
grailPayParams:grailPayParams
|
|
41
45
|
resolver:resolve
|
|
42
46
|
rejecter:reject];
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
|
|
45
50
|
RCT_EXPORT_METHOD(setViewController:(RCTPromiseResolveBlock)resolve
|
|
46
51
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
47
52
|
{
|
|
@@ -60,66 +65,3 @@ RCT_EXPORT_METHOD(getPlatformVersion:(RCTPromiseResolveBlock)resolve
|
|
|
60
65
|
|
|
61
66
|
@end
|
|
62
67
|
|
|
63
|
-
//
|
|
64
|
-
//#import "EasyMerchantSdk.h"
|
|
65
|
-
//#import <React/RCTLog.h>
|
|
66
|
-
//#import <React/RCTBridgeModule.h>
|
|
67
|
-
////#import <easymerchantsdk/easymerchantsdk-Swift.h>
|
|
68
|
-
//#import <easymerchantsdk-Swift.h>
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//@implementation EasyMerchantSdk
|
|
72
|
-
//
|
|
73
|
-
//RCT_EXPORT_MODULE()
|
|
74
|
-
//
|
|
75
|
-
//RCT_EXPORT_METHOD(
|
|
76
|
-
// billing:(NSString *)amount
|
|
77
|
-
// billingInfo:(NSString *)billingInfo
|
|
78
|
-
// paymentMethods:(NSArray *)paymentMethods
|
|
79
|
-
// themeConfiguration:(NSDictionary *)themeConfiguration
|
|
80
|
-
// tokenOnly:(BOOL)tokenOnly
|
|
81
|
-
// saveCard:(BOOL)saveCard
|
|
82
|
-
// saveAccount:(BOOL)saveAccount
|
|
83
|
-
// resolver:(RCTPromiseResolveBlock)resolve
|
|
84
|
-
// rejecter:(RCTPromiseRejectBlock)reject
|
|
85
|
-
//)
|
|
86
|
-
//{
|
|
87
|
-
// EasyMerchantSdkPlugin *sdkPlugin = [[EasyMerchantSdkPlugin alloc] init];
|
|
88
|
-
//
|
|
89
|
-
// [sdkPlugin billing:amount
|
|
90
|
-
// billinginfo:billingInfo
|
|
91
|
-
// paymentMethods:paymentMethods
|
|
92
|
-
// themeConfiguration:themeConfiguration
|
|
93
|
-
// tokenOnly:tokenOnly
|
|
94
|
-
// saveCard:saveCard
|
|
95
|
-
// saveAccount:saveAccount
|
|
96
|
-
// resolver:resolve
|
|
97
|
-
// rejecter:reject];
|
|
98
|
-
//}
|
|
99
|
-
//
|
|
100
|
-
//RCT_EXPORT_METHOD(setViewController:(RCTPromiseResolveBlock)resolve
|
|
101
|
-
// rejecter:(RCTPromiseRejectBlock)reject)
|
|
102
|
-
//{
|
|
103
|
-
// UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
|
|
104
|
-
// EasyMerchantSdkPlugin *sdkPlugin = [[EasyMerchantSdkPlugin alloc] init];
|
|
105
|
-
// [sdkPlugin setViewController:rootViewController];
|
|
106
|
-
// resolve(@"ViewController set successfully");
|
|
107
|
-
//}
|
|
108
|
-
//
|
|
109
|
-
//RCT_EXPORT_METHOD(getPlatformVersion:(RCTPromiseResolveBlock)resolve
|
|
110
|
-
// rejecter:(RCTPromiseRejectBlock)reject)
|
|
111
|
-
//{
|
|
112
|
-
// NSString *platformVersion = [NSString stringWithFormat:@"iOS %@", [[UIDevice currentDevice] systemVersion]];
|
|
113
|
-
// resolve(platformVersion);
|
|
114
|
-
//}
|
|
115
|
-
//
|
|
116
|
-
//RCT_EXPORT_METHOD(configureEnvironment:(NSString *)env
|
|
117
|
-
// apiKey:(NSString *)apiKey
|
|
118
|
-
// apiSecret:(NSString *)apiSecret)
|
|
119
|
-
//{
|
|
120
|
-
// EasyMerchantSdkPlugin *sdkPlugin = [[EasyMerchantSdkPlugin alloc] init];
|
|
121
|
-
// [sdkPlugin configureEnvironment:env apiKey:apiKey apiSecret:apiSecret];
|
|
122
|
-
//}
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
//@end
|
|
@@ -1,130 +1,3 @@
|
|
|
1
|
-
//
|
|
2
|
-
//import Foundation
|
|
3
|
-
//import UIKit
|
|
4
|
-
//import React
|
|
5
|
-
//
|
|
6
|
-
//@objc(EasyMerchantSdkPlugin)
|
|
7
|
-
//public class EasyMerchantSdkPlugin: NSObject {
|
|
8
|
-
//
|
|
9
|
-
// private var viewController: UIViewController?
|
|
10
|
-
// private let viewControllerQueue = DispatchQueue(label: "com.easymerchantsdk.viewController")
|
|
11
|
-
//
|
|
12
|
-
// @objc public func setViewController(_ viewController: UIViewController) {
|
|
13
|
-
// viewControllerQueue.sync {
|
|
14
|
-
// self.viewController = viewController
|
|
15
|
-
// }
|
|
16
|
-
// print("ViewController set: \(String(describing: self.viewController))")
|
|
17
|
-
// }
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//@objc public func billing(
|
|
21
|
-
// _ amount: String,
|
|
22
|
-
// billinginfo: String,
|
|
23
|
-
// paymentMethods: [String],
|
|
24
|
-
// themeConfiguration: [String: Any],
|
|
25
|
-
// tokenOnly: Bool,
|
|
26
|
-
// saveCard: Bool,
|
|
27
|
-
// saveAccount: Bool,
|
|
28
|
-
// resolver: @escaping RCTPromiseResolveBlock,
|
|
29
|
-
// rejecter: @escaping RCTPromiseRejectBlock
|
|
30
|
-
//) {
|
|
31
|
-
// guard let amountValue = Double(amount), amountValue > 0 else {
|
|
32
|
-
// rejecter("INVALID_AMOUNT", "Amount must be a positive number", nil)
|
|
33
|
-
// return
|
|
34
|
-
// }
|
|
35
|
-
//
|
|
36
|
-
// guard !billinginfo.isEmpty,
|
|
37
|
-
// let billingInfoData = billinginfo.data(using: .utf8),
|
|
38
|
-
// let _ = try? JSONSerialization.jsonObject(with: billingInfoData, options: []) as? [String: Any] else {
|
|
39
|
-
// rejecter("INVALID_BILLING_INFO", "Billing info must be valid JSON", nil)
|
|
40
|
-
// return
|
|
41
|
-
// }
|
|
42
|
-
//
|
|
43
|
-
// let methods: [PaymentMethod] = paymentMethods.compactMap {
|
|
44
|
-
// switch $0.lowercased() {
|
|
45
|
-
// case "card": return .Card
|
|
46
|
-
// case "bank": return .Bank
|
|
47
|
-
// case "crypto": return .Crypto
|
|
48
|
-
// default: return nil
|
|
49
|
-
// }
|
|
50
|
-
// }
|
|
51
|
-
//
|
|
52
|
-
// let request = Request(
|
|
53
|
-
// amount: amountValue,
|
|
54
|
-
// billingInfoData: billingInfoData,
|
|
55
|
-
// paymentMethods: methods,
|
|
56
|
-
// themeConfiguration: themeConfiguration,
|
|
57
|
-
// tokenOnly: tokenOnly,
|
|
58
|
-
// saveCard: saveCard,
|
|
59
|
-
// saveAccount: saveAccount
|
|
60
|
-
// )
|
|
61
|
-
//
|
|
62
|
-
// let paymentController = EasyPayViewController(request: request, delegate: self)
|
|
63
|
-
//
|
|
64
|
-
// DispatchQueue.main.async {
|
|
65
|
-
// if let rootViewController = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController {
|
|
66
|
-
// rootViewController.present(paymentController, animated: true) {
|
|
67
|
-
// resolver("Payment process started for amount \(amount)")
|
|
68
|
-
// }
|
|
69
|
-
// } else {
|
|
70
|
-
// rejecter("VIEW_CONTROLLER_NOT_FOUND", "Root ViewController not found", nil)
|
|
71
|
-
// }
|
|
72
|
-
// }
|
|
73
|
-
//}
|
|
74
|
-
//
|
|
75
|
-
// @objc public func getPlatformVersion(
|
|
76
|
-
// _ resolver: @escaping RCTPromiseResolveBlock,
|
|
77
|
-
// rejecter: @escaping RCTPromiseRejectBlock
|
|
78
|
-
// ) {
|
|
79
|
-
// resolver("iOS \(UIDevice.current.systemVersion)")
|
|
80
|
-
// }
|
|
81
|
-
//}
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
//
|
|
87
|
-
//
|
|
88
|
-
//
|
|
89
|
-
//@objc(EasyMerchantSdkPlugin)
|
|
90
|
-
//extension EasyMerchantSdkPlugin: RCTBridgeModule {
|
|
91
|
-
// public static func moduleName() -> String {
|
|
92
|
-
// return "EasyMerchantSdk"
|
|
93
|
-
// }
|
|
94
|
-
//
|
|
95
|
-
// public static func requiresMainQueueSetup() -> Bool {
|
|
96
|
-
// return true
|
|
97
|
-
// }
|
|
98
|
-
//}
|
|
99
|
-
//
|
|
100
|
-
//extension EasyMerchantSdkPlugin: EasyPayViewControllerDelegate {
|
|
101
|
-
// public func easyPayController(_ controller: EasyPayViewController, didFinishWith result: Result) {
|
|
102
|
-
// DispatchQueue.main.async {
|
|
103
|
-
// switch result.type {
|
|
104
|
-
// case .cancelled:
|
|
105
|
-
// print("Payment Cancelled by user.")
|
|
106
|
-
// case .success:
|
|
107
|
-
// if let chargeData = result.chargeData {
|
|
108
|
-
// self.handleSuccess(with: chargeData)
|
|
109
|
-
// } else {
|
|
110
|
-
// print("Payment succeeded but no charge data received.")
|
|
111
|
-
// }
|
|
112
|
-
// case .error:
|
|
113
|
-
// if let chargeData = result.chargeData,
|
|
114
|
-
// let errorMessage = chargeData["errorMessage"] as? String {
|
|
115
|
-
// print("Payment Error: \(errorMessage)")
|
|
116
|
-
// } else {
|
|
117
|
-
// print("Unknown Payment Error.")
|
|
118
|
-
// }
|
|
119
|
-
// }
|
|
120
|
-
// }
|
|
121
|
-
// }
|
|
122
|
-
//
|
|
123
|
-
// private func handleSuccess(with chargeData: [String: Any]) {
|
|
124
|
-
// print("Payment Successful. Charge Data: \(chargeData)")
|
|
125
|
-
// }
|
|
126
|
-
//}
|
|
127
|
-
|
|
128
1
|
import Foundation
|
|
129
2
|
import UIKit
|
|
130
3
|
import React
|
|
@@ -139,20 +12,20 @@ public class EasyMerchantSdkPlugin: NSObject {
|
|
|
139
12
|
viewControllerQueue.sync {
|
|
140
13
|
self.viewController = viewController
|
|
141
14
|
}
|
|
142
|
-
|
|
143
|
-
|
|
15
|
+
print("ViewController set: \(String(describing: self.viewController))")
|
|
144
16
|
}
|
|
145
17
|
|
|
146
18
|
|
|
147
|
-
|
|
148
19
|
@objc public func billing(
|
|
149
20
|
_ amount: String,
|
|
150
21
|
billinginfo: String,
|
|
151
22
|
paymentMethods: [String],
|
|
152
|
-
themeConfiguration: [String: Any],
|
|
23
|
+
themeConfiguration: [String: Any], // Accept dynamic theme from JS
|
|
153
24
|
tokenOnly: Bool,
|
|
154
25
|
saveCard: Bool,
|
|
155
26
|
saveAccount: Bool,
|
|
27
|
+
authenticatedACH: Bool,
|
|
28
|
+
grailPayParams: [String: Any]?,
|
|
156
29
|
resolver: @escaping RCTPromiseResolveBlock,
|
|
157
30
|
rejecter: @escaping RCTPromiseRejectBlock
|
|
158
31
|
) {
|
|
@@ -176,14 +49,60 @@ public class EasyMerchantSdkPlugin: NSObject {
|
|
|
176
49
|
}
|
|
177
50
|
}
|
|
178
51
|
|
|
52
|
+
var grailParams: GrailPayRequest? = nil
|
|
53
|
+
if authenticatedACH, let params = grailPayParams {
|
|
54
|
+
grailParams = GrailPayRequest(
|
|
55
|
+
accessToken: params["accessToken"] as? String ?? "",
|
|
56
|
+
vendorId: params["vendorId"] as? String ?? "",
|
|
57
|
+
role: params["role"] as? String ?? "business",
|
|
58
|
+
timeout: params["timeout"] as? Int ?? 10,
|
|
59
|
+
isSandbox: params["isSandbox"] as? Bool ?? true,
|
|
60
|
+
brandingName: params["brandingName"] as? String ?? "Payments",
|
|
61
|
+
finderSubtitle: params["finderSubtitle"] as? String ?? "Find your bank",
|
|
62
|
+
searchPlaceholder: params["searchPlaceholder"] as? String ?? "Search"
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Extract themeConfiguration values from JS
|
|
67
|
+
let bodyBackgroundColor = themeConfiguration["bodyBackgroundColor"] as? String ?? "#EBF8FF"
|
|
68
|
+
let containerBackgroundColor = themeConfiguration["containerBackgroundColor"] as? String ?? "#FFFFFF"
|
|
69
|
+
let primaryFontColor = themeConfiguration["primaryFontColor"] as? String ?? "#1E3A8A"
|
|
70
|
+
let secondaryFontColor = themeConfiguration["secondaryFontColor"] as? String ?? "#696969"
|
|
71
|
+
let primaryButtonBackgroundColor = themeConfiguration["primaryButtonBackgroundColor"] as? String ?? "#1D4ED8"
|
|
72
|
+
let primaryButtonHoverColor = themeConfiguration["primaryButtonHoverColor"] as? String ?? "#2563EB"
|
|
73
|
+
let primaryButtonFontColor = themeConfiguration["primaryButtonFontColor"] as? String ?? "#FFFFFF"
|
|
74
|
+
let secondaryButtonBackgroundColor = themeConfiguration["secondaryButtonBackgroundColor"] as? String ?? "#FFFFFF"
|
|
75
|
+
let secondaryButtonHoverColor = themeConfiguration["secondaryButtonHoverColor"] as? String ?? "#BFDBFE"
|
|
76
|
+
let secondaryButtonFontColor = themeConfiguration["secondaryButtonFontColor"] as? String ?? "#1E40AF"
|
|
77
|
+
let borderRadius = themeConfiguration["borderRadius"] as? String ?? "8"
|
|
78
|
+
let fontSize = themeConfiguration["fontSize"] as? String ?? "14"
|
|
79
|
+
|
|
80
|
+
let themeConfig = ThemeConfiguration(
|
|
81
|
+
bodyBackgroundColor: bodyBackgroundColor,
|
|
82
|
+
containerBackgroundColor: containerBackgroundColor,
|
|
83
|
+
primaryFontColor: primaryFontColor,
|
|
84
|
+
secondaryFontColor: secondaryFontColor,
|
|
85
|
+
primaryButtonBackgroundColor: primaryButtonBackgroundColor,
|
|
86
|
+
primaryButtonHoverColor: primaryButtonHoverColor,
|
|
87
|
+
primaryButtonFontColor: primaryButtonFontColor,
|
|
88
|
+
secondaryButtonBackgroundColor: secondaryButtonBackgroundColor,
|
|
89
|
+
secondaryButtonHoverColor: secondaryButtonHoverColor,
|
|
90
|
+
secondaryButtonFontColor: secondaryButtonFontColor,
|
|
91
|
+
borderRadius: borderRadius,
|
|
92
|
+
fontSize: fontSize
|
|
93
|
+
)
|
|
94
|
+
|
|
179
95
|
let request = Request(
|
|
180
96
|
amount: amountValue,
|
|
181
97
|
billingInfoData: billingInfoData,
|
|
182
98
|
paymentMethods: methods,
|
|
183
|
-
themeConfiguration:
|
|
99
|
+
themeConfiguration: themeConfig,
|
|
184
100
|
tokenOnly: tokenOnly,
|
|
185
101
|
saveCard: saveCard,
|
|
186
|
-
saveAccount: saveAccount
|
|
102
|
+
saveAccount: saveAccount,
|
|
103
|
+
submitButtonText: "Submit",
|
|
104
|
+
authenticatedACH: authenticatedACH,
|
|
105
|
+
grailPayParams: authenticatedACH ? grailParams : nil
|
|
187
106
|
)
|
|
188
107
|
|
|
189
108
|
DispatchQueue.main.async {
|
|
@@ -203,25 +122,25 @@ public class EasyMerchantSdkPlugin: NSObject {
|
|
|
203
122
|
}
|
|
204
123
|
|
|
205
124
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
EnvironmentConfig.configure(apiKey: apiKey, apiSecret: apiSecret)
|
|
125
|
+
@objc public func configureEnvironment(_ env: String, apiKey: String, apiSecret: String) {
|
|
126
|
+
switch env.lowercased() {
|
|
127
|
+
case "production":
|
|
128
|
+
EnvironmentConfig.setEnvironment(.production)
|
|
129
|
+
case "sandbox":
|
|
130
|
+
EnvironmentConfig.setEnvironment(.sandbox)
|
|
131
|
+
default:
|
|
132
|
+
EnvironmentConfig.setEnvironment(.staging)
|
|
217
133
|
}
|
|
218
134
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
135
|
+
EnvironmentConfig.configure(apiKey: apiKey, apiSecret: apiSecret)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@objc public func getPlatformVersion(
|
|
139
|
+
_ resolver: @escaping RCTPromiseResolveBlock,
|
|
140
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
141
|
+
) {
|
|
142
|
+
resolver("iOS \(UIDevice.current.systemVersion)")
|
|
143
|
+
}
|
|
225
144
|
}
|
|
226
145
|
|
|
227
146
|
// MARK: - React Native Bridge
|
|
@@ -259,3 +178,4 @@ extension EasyMerchantSdkPlugin: EasyPayViewControllerDelegate {
|
|
|
259
178
|
NotificationCenter.default.post(name: NSNotification.Name(name), object: nil, userInfo: body)
|
|
260
179
|
}
|
|
261
180
|
}
|
|
181
|
+
|
|
@@ -47,6 +47,10 @@ public final class EasyPayViewController: UINavigationController {
|
|
|
47
47
|
self.easyPayDelegate = delegate
|
|
48
48
|
super.init(nibName: nil, bundle: nil)
|
|
49
49
|
|
|
50
|
+
if let themeConfiguration = request.themeConfiguration {
|
|
51
|
+
UserStoreSingleton.shared.updateThemeConfiguration(with: themeConfiguration)
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
self.modalPresentationStyle = .fullScreen
|
|
51
55
|
self.isModalInPresentation = true
|
|
52
56
|
}
|
package/ios/Classes/dsd
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
@objc public func billing(
|
|
2
|
+
_ amount: String,
|
|
3
|
+
billinginfo: String,
|
|
4
|
+
paymentMethods: [String],
|
|
5
|
+
themeConfiguration: [String: Any],
|
|
6
|
+
tokenOnly: Bool,
|
|
7
|
+
saveCard: Bool,
|
|
8
|
+
saveAccount: Bool,
|
|
9
|
+
authenticatedACH: Bool,
|
|
10
|
+
grailPayParams: [String: Any]?,
|
|
11
|
+
resolver: @escaping RCTPromiseResolveBlock,
|
|
12
|
+
rejecter: @escaping RCTPromiseRejectBlock
|
|
13
|
+
) {
|
|
14
|
+
guard let amountValue = Double(amount), amountValue > 0 else {
|
|
15
|
+
rejecter("INVALID_AMOUNT", "Amount must be a positive number", nil)
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
guard let billingInfoData = billinginfo.data(using: .utf8),
|
|
20
|
+
let _ = try? JSONSerialization.jsonObject(with: billingInfoData, options: []) else {
|
|
21
|
+
rejecter("INVALID_BILLING_INFO", "Billing info must be valid JSON", nil)
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let methods: [PaymentMethod] = paymentMethods.compactMap {
|
|
26
|
+
switch $0.lowercased() {
|
|
27
|
+
case "card": return .Card
|
|
28
|
+
case "bank": return .Bank
|
|
29
|
+
case "crypto": return .Crypto
|
|
30
|
+
default: return nil
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var grailParams: GrailPayRequest? = nil
|
|
35
|
+
if authenticatedACH, let params = grailPayParams {
|
|
36
|
+
grailParams = GrailPayRequest(
|
|
37
|
+
accessToken: params["accessToken"] as? String ?? "",
|
|
38
|
+
vendorId: params["vendorId"] as? String ?? "",
|
|
39
|
+
role: params["role"] as? String ?? "business",
|
|
40
|
+
timeout: params["timeout"] as? Int ?? 10,
|
|
41
|
+
isSandbox: params["isSandbox"] as? Bool ?? true,
|
|
42
|
+
brandingName: params["brandingName"] as? String ?? "Payments",
|
|
43
|
+
finderSubtitle: params["finderSubtitle"] as? String ?? "Find your bank",
|
|
44
|
+
searchPlaceholder: params["searchPlaceholder"] as? String ?? "Search"
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let request = Request(
|
|
49
|
+
amount: amountValue,
|
|
50
|
+
billingInfoData: billingInfoData,
|
|
51
|
+
paymentMethods: methods,
|
|
52
|
+
themeConfiguration: themeConfiguration,
|
|
53
|
+
tokenOnly: tokenOnly,
|
|
54
|
+
saveCard: saveCard,
|
|
55
|
+
saveAccount: saveAccount,
|
|
56
|
+
authenticatedACH: authenticatedACH,
|
|
57
|
+
grailPayParams: grailParams
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
DispatchQueue.main.async {
|
|
61
|
+
let controller = EasyPayViewController(request: request, delegate: self)
|
|
62
|
+
if let vc = self.viewController {
|
|
63
|
+
vc.present(controller, animated: true) {
|
|
64
|
+
resolver("Payment UI presented")
|
|
65
|
+
}
|
|
66
|
+
} else if let rootVC = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.rootViewController {
|
|
67
|
+
rootVC.present(controller, animated: true) {
|
|
68
|
+
resolver("Payment UI presented (fallback)")
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
rejecter("NO_VIEW_CONTROLLER", "No view controller available to present payment screen.", nil)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -49,6 +49,7 @@ public class EnvironmentConfig {
|
|
|
49
49
|
case account
|
|
50
50
|
case achCharge
|
|
51
51
|
case charges
|
|
52
|
+
case accountConnect
|
|
52
53
|
|
|
53
54
|
func path() -> String {
|
|
54
55
|
switch self {
|
|
@@ -61,6 +62,9 @@ public class EnvironmentConfig {
|
|
|
61
62
|
case .account: return "/api/v1/ach/account"
|
|
62
63
|
case .achCharge: return "/api/v1/ach/charge"
|
|
63
64
|
case .charges: return "/api/v1/charges"
|
|
65
|
+
case .accountConnect: return "/api/v1/ach/account/connect"
|
|
66
|
+
|
|
67
|
+
|
|
64
68
|
}
|
|
65
69
|
}
|
|
66
70
|
}
|