@jimrising/easymerchantsdk-react-native 1.8.2 → 1.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.idea/caches/deviceStreaming.xml +22 -0
- package/README.md +161 -61
- package/android/build/.transforms/15b6a8a60a6b32d0dcaf609723cf365b/transformed/classes/classes_dex/classes.dex +0 -0
- package/android/build/.transforms/8508f1428f740032c45a43f48b1bbe1e/transformed/bundleLibRuntimeToDirDebug/bundleLibRuntimeToDirDebug_dex/com/reactlibrary/RNEasymerchantsdkModule.dex +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1$1.class.uniqueId1 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1.class.uniqueId0 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$2.class.uniqueId3 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule.class.uniqueId2 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkPackage.class.uniqueId4 +0 -0
- package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
- package/android/build.gradle +1 -1
- package/ios/Classes/EasyMerchantSdk.m +0 -1
- package/ios/Classes/EasyPayViewController.swift +7 -20
- package/ios/Models/Request.swift +221 -38
- package/ios/Pods/UserDefaults/UserStoreSingleton.swift +40 -11
- package/ios/Pods/ViewControllers/AdditionalInfoVC.swift +5 -1
- package/ios/Pods/ViewControllers/BillingInfoVC/BillingInfoVC.swift +13 -4
- package/ios/Pods/ViewControllers/OTPVerificationVC.swift +7 -2
- package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +28 -17
- package/ios/easymerchantsdk.podspec +1 -1
- package/package.json +1 -1
|
@@ -135,6 +135,17 @@
|
|
|
135
135
|
<option name="screenX" value="1080" />
|
|
136
136
|
<option name="screenY" value="2400" />
|
|
137
137
|
</PersistentDeviceSelectionData>
|
|
138
|
+
<PersistentDeviceSelectionData>
|
|
139
|
+
<option name="api" value="35" />
|
|
140
|
+
<option name="brand" value="google" />
|
|
141
|
+
<option name="codename" value="akita" />
|
|
142
|
+
<option name="id" value="akita" />
|
|
143
|
+
<option name="manufacturer" value="Google" />
|
|
144
|
+
<option name="name" value="Pixel 8a" />
|
|
145
|
+
<option name="screenDensity" value="420" />
|
|
146
|
+
<option name="screenX" value="1080" />
|
|
147
|
+
<option name="screenY" value="2400" />
|
|
148
|
+
</PersistentDeviceSelectionData>
|
|
138
149
|
<PersistentDeviceSelectionData>
|
|
139
150
|
<option name="api" value="34" />
|
|
140
151
|
<option name="brand" value="motorola" />
|
|
@@ -509,6 +520,17 @@
|
|
|
509
520
|
<option name="screenX" value="1008" />
|
|
510
521
|
<option name="screenY" value="2244" />
|
|
511
522
|
</PersistentDeviceSelectionData>
|
|
523
|
+
<PersistentDeviceSelectionData>
|
|
524
|
+
<option name="api" value="34" />
|
|
525
|
+
<option name="brand" value="motorola" />
|
|
526
|
+
<option name="codename" value="lion" />
|
|
527
|
+
<option name="id" value="lion" />
|
|
528
|
+
<option name="manufacturer" value="Motorola" />
|
|
529
|
+
<option name="name" value="moto g04" />
|
|
530
|
+
<option name="screenDensity" value="280" />
|
|
531
|
+
<option name="screenX" value="720" />
|
|
532
|
+
<option name="screenY" value="1612" />
|
|
533
|
+
</PersistentDeviceSelectionData>
|
|
512
534
|
<PersistentDeviceSelectionData>
|
|
513
535
|
<option name="api" value="33" />
|
|
514
536
|
<option name="brand" value="google" />
|
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.8.
|
|
10
|
+
"@jimrising/easymerchantsdk-react-native": "^1.8.4"
|
|
11
11
|
},
|
|
12
12
|
```
|
|
13
13
|
|
|
@@ -137,38 +137,47 @@ const App = () => {
|
|
|
137
137
|
const [email, setEmail] = useState('');
|
|
138
138
|
const [environment, setEnvironment] = useState('sandbox');
|
|
139
139
|
const [isRecurring, setIsRecurring] = useState(false);
|
|
140
|
-
const [
|
|
141
|
-
const [
|
|
140
|
+
const [isAuthenticatedACH, setAuthenticatedACH] = useState(false);
|
|
141
|
+
const [isSecureAuthentication, setSecureAuthentication] = useState(false);
|
|
142
|
+
const [isBillingVisible, setBillingVisible] = useState(false);
|
|
143
|
+
const [isAdditionalVisible, setAdditionalVisible] = useState(false);
|
|
144
|
+
const [emailEditable, setEmailEditable] = useState(true);
|
|
145
|
+
const [isEmail, setIsEmail] = useState(true);
|
|
142
146
|
const [result, setResult] = useState('');
|
|
143
147
|
const [referenceToken, setReferenceToken] = useState('');
|
|
144
148
|
const [loading, setLoading] = useState(false);
|
|
149
|
+
const [apiKey, setApiKey] = useState('');
|
|
150
|
+
const [apiSecret, setApiSecret] = useState('');
|
|
151
|
+
|
|
152
|
+
useEffect(() => {
|
|
153
|
+
const key = environment === 'staging'
|
|
154
|
+
? 'stagingApiKey'
|
|
155
|
+
: 'sandboxApiKey';
|
|
156
|
+
|
|
157
|
+
const secret = environment === 'staging'
|
|
158
|
+
? 'stagingApiSecretKey'
|
|
159
|
+
: 'sandboxApiSecretKey';
|
|
160
|
+
|
|
161
|
+
setApiKey(key);
|
|
162
|
+
setApiSecret(secret);
|
|
163
|
+
|
|
164
|
+
const setupIOS = async () => {
|
|
165
|
+
if (Platform.OS === 'ios') {
|
|
166
|
+
try {
|
|
167
|
+
await EasyMerchantSdk.setViewController();
|
|
168
|
+
await EasyMerchantSdk.configureEnvironment(
|
|
169
|
+
environment,
|
|
170
|
+
key,
|
|
171
|
+
secret
|
|
172
|
+
);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.error('iOS Initialization Error:', err);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
setupIOS();
|
|
179
|
+
}, [environment]);
|
|
145
180
|
|
|
146
|
-
useEffect(() => {
|
|
147
|
-
const setupIOS = async () => {
|
|
148
|
-
if (Platform.OS === 'ios') {
|
|
149
|
-
try {
|
|
150
|
-
await EasyMerchantSdk.setViewController();
|
|
151
|
-
|
|
152
|
-
const iosKey = environment === 'staging'
|
|
153
|
-
? 'stagingApiKey'
|
|
154
|
-
: 'sandboxApiKey';
|
|
155
|
-
|
|
156
|
-
const iosSecret = environment === 'staging'
|
|
157
|
-
? 'stagingSecretKey'
|
|
158
|
-
: 'sandboxSecretKey';
|
|
159
|
-
|
|
160
|
-
await EasyMerchantSdk.configureEnvironment(
|
|
161
|
-
environment,
|
|
162
|
-
iosKey,
|
|
163
|
-
iosSecret
|
|
164
|
-
);
|
|
165
|
-
} catch (err) {
|
|
166
|
-
console.error('iOS Initialization Error:', err);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
setupIOS();
|
|
171
|
-
}, [environment]);
|
|
172
181
|
|
|
173
182
|
const handlePayment = async () => {
|
|
174
183
|
if (!amount || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0) {
|
|
@@ -183,8 +192,8 @@ const App = () => {
|
|
|
183
192
|
if (Platform.OS === 'android') {
|
|
184
193
|
const config = {
|
|
185
194
|
amount,
|
|
186
|
-
apiKey:
|
|
187
|
-
secretKey:
|
|
195
|
+
apiKey: apiKey,
|
|
196
|
+
secretKey: apiSecret,
|
|
188
197
|
jsonConfig: {
|
|
189
198
|
environment,
|
|
190
199
|
amount,
|
|
@@ -192,8 +201,8 @@ const App = () => {
|
|
|
192
201
|
currency: 'usd',
|
|
193
202
|
saveCard: true,
|
|
194
203
|
saveAccount: true,
|
|
195
|
-
authenticatedACH:
|
|
196
|
-
secureAuthentication:
|
|
204
|
+
authenticatedACH: isAuthenticatedACH,
|
|
205
|
+
secureAuthentication: isSecureAuthentication,
|
|
197
206
|
showReceipt: true,
|
|
198
207
|
showDonate: false,
|
|
199
208
|
showTotal: true,
|
|
@@ -203,18 +212,18 @@ const App = () => {
|
|
|
203
212
|
email,
|
|
204
213
|
name: 'Pavan',
|
|
205
214
|
fields: {
|
|
206
|
-
visibility: { billing:
|
|
215
|
+
visibility: { billing: isBillingVisible, additional: isAdditionalVisible },
|
|
207
216
|
billing: [
|
|
208
217
|
{ name: 'address', required: true, value: 'New Address' },
|
|
209
|
-
{ name: 'country', required: true, value: '
|
|
218
|
+
{ name: 'country', required: true, value: 'India' },
|
|
210
219
|
{ name: 'state', required: true, value: 'California' },
|
|
211
|
-
{ name: 'city', required: true, value: '
|
|
220
|
+
{ name: 'city', required: true, value: 'Goa' },
|
|
212
221
|
{ name: 'postal_code', required: true, value: '1432456' },
|
|
213
222
|
],
|
|
214
223
|
additional: [
|
|
215
224
|
{ name: 'name', required: true, value: 'Test User 7' },
|
|
216
225
|
{ name: 'email_address', required: true, value: 'usertest@gmail.com' },
|
|
217
|
-
{ name: 'phone_number', required:
|
|
226
|
+
{ name: 'phone_number', required: true, value: '8978967895' },
|
|
218
227
|
{ name: 'description', required: true, value: 'Hi This is description' },
|
|
219
228
|
],
|
|
220
229
|
},
|
|
@@ -261,6 +270,7 @@ const App = () => {
|
|
|
261
270
|
const response = await RNEasymerchantsdk.makePayment(config);
|
|
262
271
|
console.log('Full payment response:', response);
|
|
263
272
|
setResult(JSON.stringify(response, null, 2));
|
|
273
|
+
|
|
264
274
|
} catch (error) {
|
|
265
275
|
setResult(`Error: ${error.message}`);
|
|
266
276
|
Alert.alert('Payment Error', error.message);
|
|
@@ -274,9 +284,9 @@ const App = () => {
|
|
|
274
284
|
|
|
275
285
|
const handleBilling = async () => {
|
|
276
286
|
const billingInfo = {
|
|
277
|
-
visibility: { billing:
|
|
287
|
+
visibility: { billing: isBillingVisible, additional: isAdditionalVisible },
|
|
278
288
|
billing: {
|
|
279
|
-
address: 'San
|
|
289
|
+
address: 'San Fransisco',
|
|
280
290
|
country: 'USA',
|
|
281
291
|
state: 'California',
|
|
282
292
|
city: 'Paris',
|
|
@@ -303,22 +313,23 @@ const App = () => {
|
|
|
303
313
|
},
|
|
304
314
|
};
|
|
305
315
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
316
|
+
const themeConfiguration = {
|
|
317
|
+
bodyBackgroundColor: "#0f1715",
|
|
318
|
+
containerBackgroundColor: "#152321",
|
|
319
|
+
primaryFontColor: "#FFFFFF",
|
|
320
|
+
secondaryFontColor: "#A0B5A4",
|
|
321
|
+
primaryButtonBackgroundColor: "#10B981",
|
|
322
|
+
primaryButtonHoverColor: "#059669",
|
|
323
|
+
primaryButtonFontColor: "#FFFFFF",
|
|
324
|
+
secondaryButtonBackgroundColor: "#374151",
|
|
325
|
+
secondaryButtonHoverColor: "#4B5563",
|
|
326
|
+
secondaryButtonFontColor: "#E5E7EB",
|
|
327
|
+
borderRadius: "8",
|
|
328
|
+
fontSize: "14",
|
|
329
|
+
fontWeight: 500,
|
|
330
|
+
fontFamily: "\"Inter\", sans-serif"
|
|
331
|
+
};
|
|
332
|
+
|
|
322
333
|
|
|
323
334
|
const authConfig = {
|
|
324
335
|
role: 'business',
|
|
@@ -339,7 +350,7 @@ const App = () => {
|
|
|
339
350
|
false, // tokenOnly
|
|
340
351
|
true, // saveCard
|
|
341
352
|
true, // saveAccount
|
|
342
|
-
|
|
353
|
+
isAuthenticatedACH, // authenticatedACH
|
|
343
354
|
authConfig, // grailPayParams
|
|
344
355
|
'Submit',
|
|
345
356
|
isRecurring, // isRecurring
|
|
@@ -347,7 +358,7 @@ const App = () => {
|
|
|
347
358
|
isRecurring ? ['weekly', 'monthly'] : [], // if isRecurring == true then it is required
|
|
348
359
|
isRecurring ? 'custom' : '', // if isRecurring == true then it is required
|
|
349
360
|
isRecurring ? '07/08/2025' : '', // if isRecurring == true then it is required
|
|
350
|
-
|
|
361
|
+
isSecureAuthentication, // secureAuthentication
|
|
351
362
|
true, // showReceipt
|
|
352
363
|
true, // showTotal
|
|
353
364
|
true, // showSubmitButton
|
|
@@ -365,6 +376,20 @@ const App = () => {
|
|
|
365
376
|
}
|
|
366
377
|
};
|
|
367
378
|
|
|
379
|
+
const handleCheckStatus = async () => {
|
|
380
|
+
setLoading(true);
|
|
381
|
+
try {
|
|
382
|
+
const response = await RNEasymerchantsdk.checkPaymentStatus();
|
|
383
|
+
console.log('Full payment response:', response);
|
|
384
|
+
setResult(JSON.stringify(response, null, 2));
|
|
385
|
+
} catch (error) {
|
|
386
|
+
setResult(`Error: ${error.message}`);
|
|
387
|
+
Alert.alert('Status Check Error', error.message);
|
|
388
|
+
} finally {
|
|
389
|
+
setLoading(false);
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
|
|
368
393
|
const handlePaymentReference = async () => {
|
|
369
394
|
if (Platform.OS === 'android') {
|
|
370
395
|
setResult('❌ Payment Reference not supported on Android');
|
|
@@ -387,6 +412,8 @@ const App = () => {
|
|
|
387
412
|
<ScrollView contentContainerStyle={styles.scrollContent}>
|
|
388
413
|
<Text style={styles.title}>EasyMerchant SDK</Text>
|
|
389
414
|
|
|
415
|
+
<Text style={styles.label}>amount</Text>
|
|
416
|
+
|
|
390
417
|
<TextInput
|
|
391
418
|
style={styles.input}
|
|
392
419
|
placeholder="Enter amount (e.g., 10.00)"
|
|
@@ -395,6 +422,8 @@ const App = () => {
|
|
|
395
422
|
onChangeText={setAmount}
|
|
396
423
|
/>
|
|
397
424
|
|
|
425
|
+
<Text style={styles.label}>Email</Text>
|
|
426
|
+
|
|
398
427
|
<TextInput
|
|
399
428
|
style={styles.input}
|
|
400
429
|
placeholder="Enter email"
|
|
@@ -419,6 +448,38 @@ const App = () => {
|
|
|
419
448
|
</View>
|
|
420
449
|
</View>
|
|
421
450
|
|
|
451
|
+
|
|
452
|
+
<View style={styles.pickerContainer}>
|
|
453
|
+
<Text style={styles.label}>Billing Visible:</Text>
|
|
454
|
+
<View style={styles.buttonGroup}>
|
|
455
|
+
<Button
|
|
456
|
+
title="Yes"
|
|
457
|
+
onPress={() => setBillingVisible(true)}
|
|
458
|
+
color={isBillingVisible ? '#2563EB' : '#ccc'}
|
|
459
|
+
/>
|
|
460
|
+
<Button
|
|
461
|
+
title="No"
|
|
462
|
+
onPress={() => setBillingVisible(false)}
|
|
463
|
+
color={!isBillingVisible ? '#2563EB' : '#ccc'}
|
|
464
|
+
/>
|
|
465
|
+
</View>
|
|
466
|
+
</View>
|
|
467
|
+
|
|
468
|
+
<View style={styles.pickerContainer}>
|
|
469
|
+
<Text style={styles.label}>Additional Info Visible:</Text>
|
|
470
|
+
<View style={styles.buttonGroup}>
|
|
471
|
+
<Button
|
|
472
|
+
title="Yes"
|
|
473
|
+
onPress={() => setAdditionalVisible(true)}
|
|
474
|
+
color={isAdditionalVisible ? '#2563EB' : '#ccc'}
|
|
475
|
+
/>
|
|
476
|
+
<Button
|
|
477
|
+
title="No"
|
|
478
|
+
onPress={() => setAdditionalVisible(false)}
|
|
479
|
+
color={!isAdditionalVisible ? '#2563EB' : '#ccc'}
|
|
480
|
+
/>
|
|
481
|
+
</View>
|
|
482
|
+
</View>
|
|
422
483
|
<View style={styles.pickerContainer}>
|
|
423
484
|
<Text style={styles.label}>Recurring Payment:</Text>
|
|
424
485
|
<View style={styles.buttonGroup}>
|
|
@@ -435,6 +496,38 @@ const App = () => {
|
|
|
435
496
|
</View>
|
|
436
497
|
</View>
|
|
437
498
|
|
|
499
|
+
<View style={styles.pickerContainer}>
|
|
500
|
+
<Text style={styles.label}>AuthenticatedACH:</Text>
|
|
501
|
+
<View style={styles.buttonGroup}>
|
|
502
|
+
<Button
|
|
503
|
+
title="Yes"
|
|
504
|
+
onPress={() => setAuthenticatedACH(true)}
|
|
505
|
+
color={isAuthenticatedACH ? '#2563EB' : '#ccc'}
|
|
506
|
+
/>
|
|
507
|
+
<Button
|
|
508
|
+
title="No"
|
|
509
|
+
onPress={() => setAuthenticatedACH(false)}
|
|
510
|
+
color={!isAuthenticatedACH ? '#2563EB' : '#ccc'}
|
|
511
|
+
/>
|
|
512
|
+
</View>
|
|
513
|
+
</View>
|
|
514
|
+
|
|
515
|
+
<View style={styles.pickerContainer}>
|
|
516
|
+
<Text style={styles.label}>SecureAuthentication:</Text>
|
|
517
|
+
<View style={styles.buttonGroup}>
|
|
518
|
+
<Button
|
|
519
|
+
title="Yes"
|
|
520
|
+
onPress={() => setSecureAuthentication(true)}
|
|
521
|
+
color={isSecureAuthentication ? '#2563EB' : '#ccc'}
|
|
522
|
+
/>
|
|
523
|
+
<Button
|
|
524
|
+
title="No"
|
|
525
|
+
onPress={() => setSecureAuthentication(false)}
|
|
526
|
+
color={!isSecureAuthentication ? '#2563EB' : '#ccc'}
|
|
527
|
+
/>
|
|
528
|
+
</View>
|
|
529
|
+
</View>
|
|
530
|
+
|
|
438
531
|
{Platform.OS === 'android' ? (
|
|
439
532
|
<View style={styles.pickerContainer}>
|
|
440
533
|
<Text style={styles.label}>Email Editable (Android):</Text>
|
|
@@ -469,10 +562,17 @@ const App = () => {
|
|
|
469
562
|
</View>
|
|
470
563
|
)}
|
|
471
564
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
565
|
+
|
|
566
|
+
<View style={styles.buttonGroup}>
|
|
567
|
+
<Button title="Pay" onPress={handlePayment} />
|
|
568
|
+
{Platform.OS === 'ios' ? (
|
|
569
|
+
<Button title="Payment Ref" onPress={handlePaymentReference} />
|
|
570
|
+
) : (
|
|
571
|
+
<Button title="Check Status" onPress={handleCheckStatus} disabled={loading} />
|
|
572
|
+
)}
|
|
573
|
+
</View>
|
|
574
|
+
|
|
575
|
+
|
|
476
576
|
|
|
477
577
|
<Text selectable style={styles.result}>{result}</Text>
|
|
478
578
|
</ScrollView>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/android/build.gradle
CHANGED
|
@@ -39,7 +39,7 @@ repositories {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
dependencies {
|
|
42
|
-
implementation 'com.app:paysdk:1.3.
|
|
42
|
+
implementation 'com.app:paysdk:1.3.7'
|
|
43
43
|
implementation 'com.hbb20:ccp:2.7.3'
|
|
44
44
|
implementation 'com.github.bumptech.glide:glide:4.16.0'
|
|
45
45
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1"
|
|
@@ -7,13 +7,11 @@
|
|
|
7
7
|
|
|
8
8
|
import UIKit
|
|
9
9
|
|
|
10
|
-
// @available(iOS 16.0, *)
|
|
11
10
|
@objc
|
|
12
11
|
public protocol EasyPayViewControllerDelegate {
|
|
13
12
|
func easyPayController(_ controller: EasyPayViewController, didFinishWith result: SDKResult)
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
// @available(iOS 16.0, *)
|
|
17
15
|
@objc
|
|
18
16
|
public final class EasyPayViewController: UINavigationController {
|
|
19
17
|
|
|
@@ -48,8 +46,8 @@ public final class EasyPayViewController: UINavigationController {
|
|
|
48
46
|
super.init(nibName: nil, bundle: nil)
|
|
49
47
|
|
|
50
48
|
if let themeConfiguration = request.themeConfiguration {
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
UserStoreSingleton.shared.updateThemeConfiguration(with: themeConfiguration)
|
|
50
|
+
}
|
|
53
51
|
|
|
54
52
|
self.modalPresentationStyle = .fullScreen
|
|
55
53
|
self.isModalInPresentation = true
|
|
@@ -63,30 +61,19 @@ public final class EasyPayViewController: UINavigationController {
|
|
|
63
61
|
let vc = UIStoryboard(name: "easymerchantsdk", bundle: Bundle.easyPayBundle).instantiateViewController(withIdentifier: "PaymentInfoVC") as! PaymentInfoVC
|
|
64
62
|
vc.modalPresentationStyle = .overFullScreen
|
|
65
63
|
vc.configureWith(request: request, delegate: easyPayDelegate)
|
|
66
|
-
vc.amount = Int(request.amount ?? 0
|
|
64
|
+
vc.amount = Int(request.amount ?? 0) // Set the amount here.
|
|
65
|
+
vc.selectedPaymentMethod = "Card"
|
|
66
|
+
|
|
67
|
+
vc.logOut()
|
|
67
68
|
self.navigationBar.isHidden = true
|
|
68
69
|
self.setViewControllers([vc], animated: false)
|
|
69
70
|
}
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// @available(iOS 16.0, *)
|
|
74
|
-
private extension EasyPayViewController {
|
|
75
|
-
func setupDetents() {
|
|
76
|
-
if let sheetController = self.sheetPresentationController {
|
|
77
|
-
sheetController.prefersGrabberVisible = false
|
|
78
|
-
var detents: [UISheetPresentationController.Detent] = []
|
|
79
|
-
detents.append(.large())
|
|
80
|
-
sheetController.detents = detents
|
|
81
|
-
}
|
|
82
|
-
}
|
|
71
|
+
|
|
83
72
|
}
|
|
84
73
|
|
|
85
74
|
private extension EasyPayViewController {
|
|
86
|
-
|
|
87
75
|
private static func runFirstTimeSetup() {
|
|
88
76
|
UIFont.registerEasyPayFonts()
|
|
89
77
|
Self.isFirstTimeSetupComleted = true
|
|
90
78
|
}
|
|
91
|
-
|
|
92
79
|
}
|
package/ios/Models/Request.swift
CHANGED
|
@@ -171,7 +171,7 @@ public final class Request: NSObject {
|
|
|
171
171
|
public let isEmail: Bool?
|
|
172
172
|
public let email: String?
|
|
173
173
|
public let name: String?
|
|
174
|
-
|
|
174
|
+
|
|
175
175
|
public init(
|
|
176
176
|
amount: Double? = nil,
|
|
177
177
|
currency: String? = nil,
|
|
@@ -284,6 +284,13 @@ public final class Request: NSObject {
|
|
|
284
284
|
|
|
285
285
|
super.init()
|
|
286
286
|
|
|
287
|
+
// /// ✅ Clear old user data first
|
|
288
|
+
// DispatchQueue.main.async {
|
|
289
|
+
// if let topVC = UIApplication.topViewController() as? PaymentInfoVC {
|
|
290
|
+
// topVC.logOut()
|
|
291
|
+
// }
|
|
292
|
+
// }
|
|
293
|
+
|
|
287
294
|
// If tokenOnly is true, fetch only the clientToken and do not open the SDK
|
|
288
295
|
if tokenOnly {
|
|
289
296
|
self.paymentIntentApi { success in
|
|
@@ -315,93 +322,237 @@ public final class Request: NSObject {
|
|
|
315
322
|
}
|
|
316
323
|
|
|
317
324
|
//MARK: - Payment Intent Api
|
|
325
|
+
// func paymentIntentApi(completion: @escaping (Bool) -> Void) {
|
|
326
|
+
// guard let serviceURL = URL(string: EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.paymentIntent.path()) else {
|
|
327
|
+
// showErrorAndDismiss(message: "Invalid payment URL.")
|
|
328
|
+
// completion(false)
|
|
329
|
+
// return
|
|
330
|
+
// }
|
|
331
|
+
//
|
|
332
|
+
// var request = URLRequest(url: serviceURL)
|
|
333
|
+
// request.httpMethod = "POST"
|
|
334
|
+
// request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
335
|
+
// request.addValue(EnvironmentConfig.apiKey ?? "", forHTTPHeaderField: "X-Api-Key")
|
|
336
|
+
// request.addValue(EnvironmentConfig.apiSecret ?? "", forHTTPHeaderField: "X-Api-Secret")
|
|
337
|
+
//
|
|
338
|
+
// // Recurring date validation
|
|
339
|
+
// if let startDateString = recurringStartDate,
|
|
340
|
+
// let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
|
|
341
|
+
// let today = Calendar.current.startOfDay(for: Date())
|
|
342
|
+
// let startDay = Calendar.current.startOfDay(for: startDate)
|
|
343
|
+
//
|
|
344
|
+
// if startDay < today {
|
|
345
|
+
// showErrorAndDismiss(message: "The recurring start date cannot be in the past. Please select today or a future date.")
|
|
346
|
+
// completion(false)
|
|
347
|
+
// return
|
|
348
|
+
// }
|
|
349
|
+
// }
|
|
350
|
+
//
|
|
351
|
+
// let params: [String: Any] = [
|
|
352
|
+
// "amount": amount ?? 0,
|
|
353
|
+
// // "allowed_cycles": String(recurringIntervals?.count ?? 0),
|
|
354
|
+
// "allowed_cycles": numOfCycle ?? 0,
|
|
355
|
+
// "intervals": recurringIntervals?.map { $0.rawValue } ?? [],
|
|
356
|
+
// "is_recurring": self.is_recurring ?? false,
|
|
357
|
+
// "recurring_start_date": recurringStartDate ?? "",
|
|
358
|
+
// "recurring_start_date_type": recurringStartDateType?.rawValue ?? ""
|
|
359
|
+
// ]
|
|
360
|
+
//
|
|
361
|
+
// do {
|
|
362
|
+
// request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
|
|
363
|
+
// } catch {
|
|
364
|
+
// showErrorAndDismiss(message: "Failed to encode payment data.")
|
|
365
|
+
// completion(false)
|
|
366
|
+
// return
|
|
367
|
+
// }
|
|
368
|
+
//
|
|
369
|
+
// let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
370
|
+
// guard let httpResponse = response as? HTTPURLResponse, error == nil else {
|
|
371
|
+
// self.showErrorAndDismiss(message: error?.localizedDescription ?? "An unknown error occurred.")
|
|
372
|
+
// completion(false)
|
|
373
|
+
// return
|
|
374
|
+
// }
|
|
375
|
+
//
|
|
376
|
+
// if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
|
|
377
|
+
// if let data = data {
|
|
378
|
+
// do {
|
|
379
|
+
// if let responseObject = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
|
|
380
|
+
// if let clientToken = responseObject["client_token"] as? String {
|
|
381
|
+
// UserStoreSingleton.shared.clientToken = clientToken
|
|
382
|
+
// print(clientToken)
|
|
383
|
+
// }
|
|
384
|
+
// if let paymentIntent = responseObject["payment_intent"] as? String {
|
|
385
|
+
// UserStoreSingleton.shared.paymentIntent = paymentIntent
|
|
386
|
+
// }
|
|
387
|
+
// self.hostedCheckoutsApi { success in
|
|
388
|
+
// completion(success)
|
|
389
|
+
// }
|
|
390
|
+
// return
|
|
391
|
+
// } else {
|
|
392
|
+
// self.showErrorAndDismiss(message: "Invalid response format.")
|
|
393
|
+
// }
|
|
394
|
+
// } catch {
|
|
395
|
+
// self.showErrorAndDismiss(message: "Failed to parse response.")
|
|
396
|
+
// }
|
|
397
|
+
// } else {
|
|
398
|
+
// self.showErrorAndDismiss(message: "No response data received.")
|
|
399
|
+
// }
|
|
400
|
+
// } else {
|
|
401
|
+
// var message = "Payment request failed with status code: \(httpResponse.statusCode)"
|
|
402
|
+
// if let data = data,
|
|
403
|
+
// let responseObj = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any],
|
|
404
|
+
// let msg = responseObj["message"] as? String {
|
|
405
|
+
// message = msg
|
|
406
|
+
// }
|
|
407
|
+
// self.showErrorAndDismiss(message: message)
|
|
408
|
+
// }
|
|
409
|
+
// completion(false)
|
|
410
|
+
// }
|
|
411
|
+
//
|
|
412
|
+
// task.resume()
|
|
413
|
+
// }
|
|
414
|
+
|
|
415
|
+
// MARK: - Payment Intent Api
|
|
318
416
|
func paymentIntentApi(completion: @escaping (Bool) -> Void) {
|
|
417
|
+
// ✅ Show Loader
|
|
418
|
+
DispatchQueue.main.async {
|
|
419
|
+
UIApplication.topViewController()?.ep_showLoadingIndicator()
|
|
420
|
+
}
|
|
421
|
+
|
|
319
422
|
guard let serviceURL = URL(string: EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.paymentIntent.path()) else {
|
|
320
|
-
|
|
423
|
+
DispatchQueue.main.async {
|
|
424
|
+
UIApplication.topViewController()?.ep_hideLoadingIndicator()
|
|
425
|
+
self.showErrorAndDismiss(message: "Invalid payment URL.")
|
|
426
|
+
}
|
|
321
427
|
completion(false)
|
|
322
428
|
return
|
|
323
429
|
}
|
|
324
|
-
|
|
430
|
+
|
|
325
431
|
var request = URLRequest(url: serviceURL)
|
|
326
432
|
request.httpMethod = "POST"
|
|
327
433
|
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
328
434
|
request.addValue(EnvironmentConfig.apiKey ?? "", forHTTPHeaderField: "X-Api-Key")
|
|
329
435
|
request.addValue(EnvironmentConfig.apiSecret ?? "", forHTTPHeaderField: "X-Api-Secret")
|
|
330
|
-
|
|
331
|
-
//
|
|
436
|
+
|
|
437
|
+
// Validate recurring start date
|
|
332
438
|
if let startDateString = recurringStartDate,
|
|
333
439
|
let startDate = DateFormatter.recurringDateFormatter.date(from: startDateString) {
|
|
334
440
|
let today = Calendar.current.startOfDay(for: Date())
|
|
335
441
|
let startDay = Calendar.current.startOfDay(for: startDate)
|
|
336
|
-
|
|
442
|
+
|
|
337
443
|
if startDay < today {
|
|
338
|
-
|
|
444
|
+
DispatchQueue.main.async {
|
|
445
|
+
UIApplication.topViewController()?.ep_hideLoadingIndicator()
|
|
446
|
+
self.showErrorAndDismiss(message: "The recurring start date cannot be in the past. Please select today or a future date.")
|
|
447
|
+
}
|
|
339
448
|
completion(false)
|
|
340
449
|
return
|
|
341
450
|
}
|
|
342
451
|
}
|
|
343
|
-
|
|
452
|
+
|
|
344
453
|
let params: [String: Any] = [
|
|
345
454
|
"amount": amount ?? 0,
|
|
346
|
-
// "allowed_cycles": String(recurringIntervals?.count ?? 0),
|
|
347
455
|
"allowed_cycles": numOfCycle ?? 0,
|
|
348
456
|
"intervals": recurringIntervals?.map { $0.rawValue } ?? [],
|
|
349
457
|
"is_recurring": self.is_recurring ?? false,
|
|
350
458
|
"recurring_start_date": recurringStartDate ?? "",
|
|
351
459
|
"recurring_start_date_type": recurringStartDateType?.rawValue ?? ""
|
|
352
460
|
]
|
|
353
|
-
|
|
461
|
+
|
|
354
462
|
do {
|
|
355
463
|
request.httpBody = try JSONSerialization.data(withJSONObject: params, options: .prettyPrinted)
|
|
356
464
|
} catch {
|
|
357
|
-
|
|
465
|
+
DispatchQueue.main.async {
|
|
466
|
+
UIApplication.topViewController()?.ep_hideLoadingIndicator()
|
|
467
|
+
self.showErrorAndDismiss(message: "Failed to encode payment data.")
|
|
468
|
+
}
|
|
358
469
|
completion(false)
|
|
359
470
|
return
|
|
360
471
|
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
472
|
+
|
|
473
|
+
URLSession.shared.dataTask(with: request) { data, response, error in
|
|
474
|
+
defer {
|
|
475
|
+
DispatchQueue.main.async {
|
|
476
|
+
UIApplication.topViewController()?.ep_hideLoadingIndicator()
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if let error = error {
|
|
481
|
+
DispatchQueue.main.async {
|
|
482
|
+
self.showErrorAndDismiss(message: error.localizedDescription)
|
|
483
|
+
}
|
|
365
484
|
completion(false)
|
|
366
485
|
return
|
|
367
486
|
}
|
|
368
|
-
|
|
487
|
+
|
|
488
|
+
guard let httpResponse = response as? HTTPURLResponse else {
|
|
489
|
+
DispatchQueue.main.async {
|
|
490
|
+
self.showErrorAndDismiss(message: "Invalid response.")
|
|
491
|
+
}
|
|
492
|
+
completion(false)
|
|
493
|
+
return
|
|
494
|
+
}
|
|
495
|
+
|
|
369
496
|
if httpResponse.statusCode == 200 || httpResponse.statusCode == 201 {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
}
|
|
382
|
-
return
|
|
383
|
-
} else {
|
|
497
|
+
guard let data = data else {
|
|
498
|
+
DispatchQueue.main.async {
|
|
499
|
+
self.showErrorAndDismiss(message: "No response data received.")
|
|
500
|
+
}
|
|
501
|
+
completion(false)
|
|
502
|
+
return
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
do {
|
|
506
|
+
guard let responseObject = try JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
|
507
|
+
DispatchQueue.main.async {
|
|
384
508
|
self.showErrorAndDismiss(message: "Invalid response format.")
|
|
385
509
|
}
|
|
386
|
-
|
|
510
|
+
completion(false)
|
|
511
|
+
return
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
// ✅ Save values into UserStoreSingleton
|
|
515
|
+
if let clientToken = responseObject["client_token"] as? String {
|
|
516
|
+
UserStoreSingleton.shared.clientToken = clientToken
|
|
517
|
+
print("✅ Saved Client Token: \(clientToken)")
|
|
518
|
+
}
|
|
519
|
+
if let paymentIntent = responseObject["payment_intent"] as? String {
|
|
520
|
+
UserStoreSingleton.shared.paymentIntent = paymentIntent
|
|
521
|
+
print("✅ Saved Payment Intent: \(paymentIntent)")
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// ✅ Proceed to next step only after saving
|
|
525
|
+
self.hostedCheckoutsApi { success in
|
|
526
|
+
DispatchQueue.main.async {
|
|
527
|
+
UIApplication.topViewController()?.ep_hideLoadingIndicator()
|
|
528
|
+
}
|
|
529
|
+
completion(success)
|
|
530
|
+
}
|
|
531
|
+
return
|
|
532
|
+
|
|
533
|
+
} catch {
|
|
534
|
+
DispatchQueue.main.async {
|
|
387
535
|
self.showErrorAndDismiss(message: "Failed to parse response.")
|
|
388
536
|
}
|
|
389
|
-
|
|
390
|
-
|
|
537
|
+
completion(false)
|
|
538
|
+
return
|
|
391
539
|
}
|
|
540
|
+
|
|
392
541
|
} else {
|
|
393
542
|
var message = "Payment request failed with status code: \(httpResponse.statusCode)"
|
|
394
543
|
if let data = data,
|
|
395
|
-
let responseObj = try? JSONSerialization.jsonObject(with: data
|
|
544
|
+
let responseObj = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
396
545
|
let msg = responseObj["message"] as? String {
|
|
397
546
|
message = msg
|
|
398
547
|
}
|
|
399
|
-
|
|
548
|
+
DispatchQueue.main.async {
|
|
549
|
+
self.showErrorAndDismiss(message: message)
|
|
550
|
+
}
|
|
400
551
|
}
|
|
552
|
+
|
|
401
553
|
completion(false)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
task.resume()
|
|
554
|
+
|
|
555
|
+
}.resume()
|
|
405
556
|
}
|
|
406
557
|
|
|
407
558
|
private func showErrorAndDismiss(message: String) {
|
|
@@ -663,3 +814,35 @@ extension UIApplication {
|
|
|
663
814
|
}
|
|
664
815
|
}
|
|
665
816
|
|
|
817
|
+
|
|
818
|
+
extension UIViewController {
|
|
819
|
+
|
|
820
|
+
func ep_showLoadingIndicator() {
|
|
821
|
+
let tag = 99999 // A unique tag so we can identify and remove the loader later
|
|
822
|
+
if self.view.viewWithTag(tag) == nil {
|
|
823
|
+
let loader = UIActivityIndicatorView(style: .large)
|
|
824
|
+
loader.center = self.view.center
|
|
825
|
+
loader.tag = tag
|
|
826
|
+
loader.startAnimating()
|
|
827
|
+
loader.color = .gray
|
|
828
|
+
loader.hidesWhenStopped = true
|
|
829
|
+
loader.translatesAutoresizingMaskIntoConstraints = false
|
|
830
|
+
self.view.addSubview(loader)
|
|
831
|
+
|
|
832
|
+
// Optional: center constraints
|
|
833
|
+
NSLayoutConstraint.activate([
|
|
834
|
+
loader.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
|
|
835
|
+
loader.centerYAnchor.constraint(equalTo: self.view.centerYAnchor)
|
|
836
|
+
])
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
func ep_hideLoadingIndicator() {
|
|
841
|
+
let tag = 99999
|
|
842
|
+
if let loader = self.view.viewWithTag(tag) as? UIActivityIndicatorView {
|
|
843
|
+
loader.stopAnimating()
|
|
844
|
+
loader.removeFromSuperview()
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
|
|
@@ -234,12 +234,6 @@ class UserStoreSingleton: NSObject {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
// func updateThemeConfiguration(with json: [String: Any]) {
|
|
238
|
-
// json.forEach { key, value in
|
|
239
|
-
// UserDefaults.standard.set(value, forKey: key)
|
|
240
|
-
// }
|
|
241
|
-
// }
|
|
242
|
-
|
|
243
237
|
func updateThemeConfiguration(with themeConfiguration: ThemeConfiguration) {
|
|
244
238
|
self.body_bg_col = themeConfiguration.bodyBackgroundColor
|
|
245
239
|
self.container_bg_col = themeConfiguration.containerBackgroundColor
|
|
@@ -256,13 +250,38 @@ class UserStoreSingleton: NSObject {
|
|
|
256
250
|
}
|
|
257
251
|
|
|
258
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
|
+
|
|
259
261
|
func clearUserData() {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
262
|
+
let keysToRemove = [
|
|
263
|
+
"client_token",
|
|
264
|
+
"payment_intent",
|
|
265
|
+
"merchant_email",
|
|
266
|
+
"merchant_name",
|
|
267
|
+
"payment_account",
|
|
268
|
+
"price",
|
|
269
|
+
"isLoggedIn",
|
|
270
|
+
"customer_id",
|
|
271
|
+
"customer_token",
|
|
272
|
+
"verificationEmail",
|
|
273
|
+
"payment_methods",
|
|
274
|
+
"bank_widget_key",
|
|
275
|
+
"vendor_id",
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
for key in keysToRemove {
|
|
279
|
+
UserDefaults.standard.removeObject(forKey: key)
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
UserDefaults.standard.synchronize()
|
|
264
283
|
}
|
|
265
|
-
|
|
284
|
+
|
|
266
285
|
@objc private func handleAppTermination() {
|
|
267
286
|
print("App is terminating. Clearing user data...")
|
|
268
287
|
clearUserData()
|
|
@@ -273,3 +292,13 @@ class UserStoreSingleton: NSObject {
|
|
|
273
292
|
}
|
|
274
293
|
|
|
275
294
|
}
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
@@ -324,7 +324,8 @@ class AdditionalInfoVC: BaseVC {
|
|
|
324
324
|
grailPayAccountChargeApi(customerId: UserStoreSingleton.shared.customerId)
|
|
325
325
|
} else {
|
|
326
326
|
// Navigate to EmailVerificationVC for all other payment methods
|
|
327
|
-
if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
|
|
327
|
+
// if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "EmailVerificationVC") as? EmailVerificationVC {
|
|
328
|
+
if let emailVerificationVC = self.storyboard?.instantiateViewController(withIdentifier: "OTPVerificationVC") as? OTPVerificationVC {
|
|
328
329
|
|
|
329
330
|
emailVerificationVC.billingInfoData = billingInfoData
|
|
330
331
|
emailVerificationVC.selectedPaymentMethod = selectedPaymentMethod
|
|
@@ -337,6 +338,7 @@ class AdditionalInfoVC: BaseVC {
|
|
|
337
338
|
emailVerificationVC.additionalInfo = fieldSection?.additional
|
|
338
339
|
emailVerificationVC.visibility = fieldSection?.visibility
|
|
339
340
|
emailVerificationVC.amount = amount
|
|
341
|
+
emailVerificationVC.email = userEmail
|
|
340
342
|
|
|
341
343
|
// Payment method-specific data
|
|
342
344
|
switch selectedPaymentMethod {
|
|
@@ -1710,6 +1712,7 @@ class AdditionalInfoVC: BaseVC {
|
|
|
1710
1712
|
paymentDoneVC.visibility = self.visibility
|
|
1711
1713
|
paymentDoneVC.amount = self.amount
|
|
1712
1714
|
paymentDoneVC.cardApiParams = params
|
|
1715
|
+
|
|
1713
1716
|
// if self.visibility?.billing == true {
|
|
1714
1717
|
paymentDoneVC.billingInfoData = self.billingInfo
|
|
1715
1718
|
var billingDict: [String: Any] = [:]
|
|
@@ -1907,6 +1910,7 @@ class AdditionalInfoVC: BaseVC {
|
|
|
1907
1910
|
paymentDoneVC.visibility = self.visibility
|
|
1908
1911
|
paymentDoneVC.amount = self.amount
|
|
1909
1912
|
paymentDoneVC.cardApiParams = params
|
|
1913
|
+
|
|
1910
1914
|
// if self.visibility?.billing == true {
|
|
1911
1915
|
paymentDoneVC.billingInfoData = self.billingInfo
|
|
1912
1916
|
var billingDict: [String: Any] = [:]
|
|
@@ -682,7 +682,8 @@ class BillingInfoVC: BaseVC {
|
|
|
682
682
|
|
|
683
683
|
}
|
|
684
684
|
else if !isAdditionalVisible && isSavedForFuture {
|
|
685
|
-
let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
|
|
685
|
+
// let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
|
|
686
|
+
let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
|
|
686
687
|
vc.cardNumber = cardNumber
|
|
687
688
|
vc.expiryDate = expiryDate
|
|
688
689
|
vc.cvv = cvv
|
|
@@ -754,7 +755,8 @@ class BillingInfoVC: BaseVC {
|
|
|
754
755
|
navigationController?.pushViewController(vc, animated: true)
|
|
755
756
|
}
|
|
756
757
|
else if !isAdditionalVisible && isSavedForFuture {
|
|
757
|
-
|
|
758
|
+
// let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
|
|
759
|
+
let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
|
|
758
760
|
vc.accountName = accountName
|
|
759
761
|
vc.routingNumber = routingNumber
|
|
760
762
|
vc.accountType = accountType
|
|
@@ -764,7 +766,7 @@ class BillingInfoVC: BaseVC {
|
|
|
764
766
|
vc.fieldSection = updatedFieldSection
|
|
765
767
|
vc.selectedPaymentMethod = selectedPaymentMethod
|
|
766
768
|
vc.easyPayDelegate = easyPayDelegate
|
|
767
|
-
vc.request = request
|
|
769
|
+
vc.request = self.request
|
|
768
770
|
vc.chosenPlan = chosenPlan
|
|
769
771
|
vc.startDate = startDate
|
|
770
772
|
vc.billingInfo = updatedFieldSection.billing
|
|
@@ -776,6 +778,7 @@ class BillingInfoVC: BaseVC {
|
|
|
776
778
|
vc.grailPayAccountID = grailPayAccountID
|
|
777
779
|
vc.selectedGrailPayAccountType = selectedGrailPayAccountType
|
|
778
780
|
vc.selectedGrailPayAccountName = selectedGrailPayAccountName
|
|
781
|
+
vc.email = userEmail
|
|
779
782
|
navigationController?.pushViewController(vc, animated: true)
|
|
780
783
|
}
|
|
781
784
|
else if isFrom == "SavedBank" {
|
|
@@ -815,7 +818,8 @@ class BillingInfoVC: BaseVC {
|
|
|
815
818
|
navigationController?.pushViewController(vc, animated: true)
|
|
816
819
|
}
|
|
817
820
|
else if !isAdditionalVisible && isSavedForFuture {
|
|
818
|
-
let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
|
|
821
|
+
// let vc = easymerchantsdk.instantiateViewController(withIdentifier: "EmailVerificationVC") as! EmailVerificationVC
|
|
822
|
+
let vc = easymerchantsdk.instantiateViewController(withIdentifier: "OTPVerificationVC") as! OTPVerificationVC
|
|
819
823
|
vc.billingInfoData = updatedBillingData
|
|
820
824
|
vc.fieldSection = updatedFieldSection
|
|
821
825
|
vc.billingInfo = updatedFieldSection.billing
|
|
@@ -833,6 +837,11 @@ class BillingInfoVC: BaseVC {
|
|
|
833
837
|
vc.selectedGrailPayAccountType = selectedGrailPayAccountType
|
|
834
838
|
vc.selectedGrailPayAccountName = selectedGrailPayAccountName
|
|
835
839
|
vc.userEmail = userEmail
|
|
840
|
+
vc.email = userEmail
|
|
841
|
+
|
|
842
|
+
vc.grailPayAccountID = self.grailPayAccountID
|
|
843
|
+
vc.selectedGrailPayAccountType = self.selectedGrailPayAccountType
|
|
844
|
+
vc.selectedGrailPayAccountName = self.selectedGrailPayAccountName
|
|
836
845
|
navigationController?.pushViewController(vc, animated: true)
|
|
837
846
|
}
|
|
838
847
|
else {
|
|
@@ -76,9 +76,12 @@ class OTPVerificationVC: BaseVC {
|
|
|
76
76
|
|
|
77
77
|
var isSavedNewCard: Bool = false
|
|
78
78
|
|
|
79
|
+
var isSavedNewAccount: Bool?
|
|
80
|
+
var isFrom = String()
|
|
81
|
+
|
|
79
82
|
override func viewDidLoad() {
|
|
80
83
|
super.viewDidLoad()
|
|
81
|
-
emailVerificationApi()
|
|
84
|
+
// emailVerificationApi()
|
|
82
85
|
|
|
83
86
|
uiFinishingTouchElements()
|
|
84
87
|
|
|
@@ -111,6 +114,7 @@ class OTPVerificationVC: BaseVC {
|
|
|
111
114
|
}
|
|
112
115
|
|
|
113
116
|
override func viewWillAppear(_ animated: Bool) {
|
|
117
|
+
emailVerificationApi()
|
|
114
118
|
startTimer()
|
|
115
119
|
uiFinishingTouchElements()
|
|
116
120
|
}
|
|
@@ -291,7 +295,7 @@ class OTPVerificationVC: BaseVC {
|
|
|
291
295
|
let token = UserStoreSingleton.shared.clientToken
|
|
292
296
|
print("Setting clientToken header: \(token ?? "None")")
|
|
293
297
|
request.addValue(token ?? "", forHTTPHeaderField: "Client-Token")
|
|
294
|
-
|
|
298
|
+
|
|
295
299
|
// Add API headers
|
|
296
300
|
if let apiKey = EnvironmentConfig.apiKey,
|
|
297
301
|
let apiSecret = EnvironmentConfig.apiSecret {
|
|
@@ -1813,6 +1817,7 @@ class OTPVerificationVC: BaseVC {
|
|
|
1813
1817
|
paymentDoneVC.visibility = self.visibility
|
|
1814
1818
|
paymentDoneVC.amount = self.amount
|
|
1815
1819
|
paymentDoneVC.cardApiParams = params
|
|
1820
|
+
|
|
1816
1821
|
// if self.visibility?.billing == true {
|
|
1817
1822
|
paymentDoneVC.billingInfoData = self.billingInfo
|
|
1818
1823
|
var billingDict: [String: Any] = [:]
|
|
@@ -406,7 +406,18 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
406
406
|
//MARK: - View Did Load
|
|
407
407
|
override func viewDidLoad() {
|
|
408
408
|
super.viewDidLoad()
|
|
409
|
-
|
|
409
|
+
// Then: safely start new API call
|
|
410
|
+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
|
|
411
|
+
self.request?.paymentIntentApi { success in
|
|
412
|
+
if success {
|
|
413
|
+
print("Payment Intent completed")
|
|
414
|
+
// Continue flow
|
|
415
|
+
} else {
|
|
416
|
+
print("Payment Intent failed")
|
|
417
|
+
// Handle failure
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
410
421
|
|
|
411
422
|
viewAppearanceOn()
|
|
412
423
|
|
|
@@ -730,9 +741,9 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
730
741
|
self.viewAddNewCard.isHidden = true
|
|
731
742
|
}
|
|
732
743
|
else {
|
|
733
|
-
|
|
744
|
+
// self.getShowCardsApi()
|
|
734
745
|
self.viewCardFields.isHidden = true
|
|
735
|
-
|
|
746
|
+
// self.viewSingleSavedCard.isHidden = false
|
|
736
747
|
self.viewBtnShowSavedCards.isHidden = true
|
|
737
748
|
self.viewBtnShowSavedCardHeight.constant = 0
|
|
738
749
|
self.viewBtnShowSavedCardTopCon.constant = 0
|
|
@@ -4312,7 +4323,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
4312
4323
|
print("isLoggedIn after clear: \(UserStoreSingleton.shared.isLoggedIn ?? false)")
|
|
4313
4324
|
|
|
4314
4325
|
UserStoreSingleton.shared.isLoggedIn = false
|
|
4315
|
-
self.settingsView.isHidden = true
|
|
4326
|
+
// self.settingsView.isHidden = true
|
|
4316
4327
|
self.btnSettings.isHidden = true
|
|
4317
4328
|
// self.txtFieldEmail.text = ""
|
|
4318
4329
|
self.txtFieldOTPText1.text = ""
|
|
@@ -5207,13 +5218,13 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
5207
5218
|
|
|
5208
5219
|
// MARK: - GET Show Cards API
|
|
5209
5220
|
func getShowCardsApi() {
|
|
5210
|
-
|
|
5221
|
+
// showLoadingIndicator()
|
|
5211
5222
|
|
|
5212
5223
|
let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.getCards.path()
|
|
5213
5224
|
|
|
5214
5225
|
guard let serviceURL = URL(string: fullURL) else {
|
|
5215
5226
|
print("❌ Invalid URL: \(fullURL)")
|
|
5216
|
-
|
|
5227
|
+
// hideLoadingIndicator()
|
|
5217
5228
|
return
|
|
5218
5229
|
}
|
|
5219
5230
|
|
|
@@ -5236,11 +5247,11 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
5236
5247
|
let task = session.dataTask(with: uRLRequest) { [weak self] (data, response, error) in
|
|
5237
5248
|
guard let self = self else { return }
|
|
5238
5249
|
|
|
5239
|
-
defer {
|
|
5240
|
-
DispatchQueue.main.async {
|
|
5241
|
-
self.hideLoadingIndicator()
|
|
5242
|
-
}
|
|
5243
|
-
}
|
|
5250
|
+
// defer {
|
|
5251
|
+
// DispatchQueue.main.async {
|
|
5252
|
+
// self.hideLoadingIndicator()
|
|
5253
|
+
// }
|
|
5254
|
+
// }
|
|
5244
5255
|
|
|
5245
5256
|
if let error = error {
|
|
5246
5257
|
print("❌ Error in getShowCardsApi: \(error.localizedDescription)")
|
|
@@ -7201,13 +7212,13 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
7201
7212
|
//MARK: - Bank Api's
|
|
7202
7213
|
// MARK: - GET Show Bank Accounts API
|
|
7203
7214
|
func getShowBankAccountsApi() {
|
|
7204
|
-
|
|
7215
|
+
// showLoadingIndicator()
|
|
7205
7216
|
|
|
7206
7217
|
let fullURL = EnvironmentConfig.baseURL + EnvironmentConfig.Endpoints.account.path()
|
|
7207
7218
|
|
|
7208
7219
|
guard let serviceURL = URL(string: fullURL) else {
|
|
7209
7220
|
print("Invalid URL")
|
|
7210
|
-
|
|
7221
|
+
// hideLoadingIndicator()
|
|
7211
7222
|
return
|
|
7212
7223
|
}
|
|
7213
7224
|
|
|
@@ -7218,7 +7229,7 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
7218
7229
|
// Retrieve and validate customer token
|
|
7219
7230
|
guard let token = UserStoreSingleton.shared.customerToken, !token.isEmpty else {
|
|
7220
7231
|
print("Customer token is missing or empty")
|
|
7221
|
-
|
|
7232
|
+
// hideLoadingIndicator()
|
|
7222
7233
|
showAlert(message: "Session expired. Please log in again.")
|
|
7223
7234
|
return
|
|
7224
7235
|
}
|
|
@@ -7230,9 +7241,9 @@ class PaymentInfoVC: BaseVC, BillingInfoVCDelegate {
|
|
|
7230
7241
|
let task = session.dataTask(with: urlRequest) { [weak self] (data, response, error) in
|
|
7231
7242
|
guard let self = self else { return }
|
|
7232
7243
|
|
|
7233
|
-
DispatchQueue.main.async {
|
|
7234
|
-
self.hideLoadingIndicator()
|
|
7235
|
-
}
|
|
7244
|
+
// DispatchQueue.main.async {
|
|
7245
|
+
// self.hideLoadingIndicator()
|
|
7246
|
+
// }
|
|
7236
7247
|
|
|
7237
7248
|
if let error = error {
|
|
7238
7249
|
print("Error: \(error.localizedDescription)")
|