@jimrising/easymerchantsdk-react-native 1.8.6 → 1.8.8

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 (56) hide show
  1. package/README.md +611 -567
  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/lintVitalAnalyzeRelease/release-artifact-dependencies.xml +4 -4
  17. package/android/build/intermediates/incremental/lintVitalAnalyzeRelease/release-artifact-libraries.xml +4 -4
  18. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  19. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  20. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  21. package/android/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  22. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  23. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  24. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  25. package/android/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  26. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-dependencies.xml +4 -4
  27. package/android/build/intermediates/lint_model/release/generateReleaseLintModel/release-artifact-libraries.xml +4 -4
  28. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-dependencies.xml +4 -4
  29. package/android/build/intermediates/lint_vital_lint_model/release/generateReleaseLintVitalModel/release-artifact-libraries.xml +4 -4
  30. package/android/build/intermediates/local_aar_for_lint/release/out.aar +0 -0
  31. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  32. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  33. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  34. package/android/build/intermediates/runtime_library_classes_dir/debug/bundleLibRuntimeToDirDebug/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  35. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$1$1.class +0 -0
  36. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$1.class +0 -0
  37. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule$2.class +0 -0
  38. package/android/build/intermediates/runtime_library_classes_dir/release/bundleLibRuntimeToDirRelease/com/reactlibrary/RNEasymerchantsdkModule.class +0 -0
  39. package/android/build/intermediates/runtime_library_classes_jar/debug/bundleLibRuntimeToJarDebug/classes.jar +0 -0
  40. package/android/build/intermediates/runtime_library_classes_jar/release/bundleLibRuntimeToJarRelease/classes.jar +0 -0
  41. package/android/build/outputs/aar/jimrising_easymerchantsdk-react-native-release.aar +0 -0
  42. package/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin +0 -0
  43. package/android/build/tmp/compileReleaseJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1$1.class.uniqueId1 +0 -0
  44. package/android/build/tmp/compileReleaseJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1.class.uniqueId3 +0 -0
  45. package/android/build/tmp/compileReleaseJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$2.class.uniqueId0 +0 -0
  46. package/android/build/tmp/compileReleaseJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule.class.uniqueId2 +0 -0
  47. package/android/build/tmp/compileReleaseJavaWithJavac/previous-compilation-data.bin +0 -0
  48. package/android/build.gradle +1 -1
  49. package/ios/Pods/ViewControllers/PaymentInformation/PaymentInfoVC.swift +82 -65
  50. package/ios/easymerchantsdk.podspec +1 -1
  51. package/package.json +1 -1
  52. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1$1.class.uniqueId1 +0 -0
  53. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$1.class.uniqueId0 +0 -0
  54. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule$2.class.uniqueId3 +0 -0
  55. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkModule.class.uniqueId2 +0 -0
  56. package/android/build/tmp/compileDebugJavaWithJavac/compileTransaction/stash-dir/RNEasymerchantsdkPackage.class.uniqueId4 +0 -0
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.6"
10
+ "@jimrising/easymerchantsdk-react-native": "^1.8.8"
11
11
  },
12
12
  ```
13
13
 
@@ -271,10 +271,42 @@ const App = () => {
271
271
  const [loading, setLoading] = useState(false);
272
272
  const [apiKey, setApiKey] = useState('apiKey');
273
273
  const [apiSecret, setApiSecret] = useState('apiSecret');
274
- const [isEnvironmentLoading, setIsEnvironmentLoading] = useState(false);
274
+ const [isEnvironmentLoading, setIsEnvironmentLoading] = useState(false);
275
+ const [showConfig, setShowConfig] = useState(true);
275
276
 
277
+
278
+ useEffect(() => {
279
+ const updateEnvironment = async () => {
280
+ const key = environment === 'staging'
281
+ ? 'stagingApiKey'
282
+ : 'sandboxApiKey';
283
+ const secret = environment === 'staging'
284
+ ? 'stagingApiSecret'
285
+ : 'sandboxApiSecret';
286
+
287
+ setApiKey(key);
288
+ setApiSecret(secret);
289
+
290
+ if (Platform.OS === 'ios') {
291
+ setIsEnvironmentLoading(true);
292
+ try {
293
+ await EasyMerchantSdk.setViewController();
294
+ await EasyMerchantSdk.configureEnvironment(environment, key, secret);
295
+ console.log(`iOS Environment configured: ${environment} with key ${key}`);
296
+ } catch (err) {
297
+ console.error('iOS Initialization Error:', err);
298
+ Alert.alert('Error', `Failed to configure iOS environment: ${err.message}`);
299
+ } finally {
300
+ setIsEnvironmentLoading(false);
301
+ }
302
+ }
303
+ };
304
+
305
+ updateEnvironment();
306
+ }, [environment]);
307
+
276
308
  useEffect(() => {
277
- if (Platform.OS !== 'android') {
309
+ if (Platform.OS !== 'android') {
278
310
  console.log('Event listeners skipped: not Android');
279
311
  return;
280
312
  }
@@ -285,30 +317,41 @@ if (Platform.OS !== 'android') {
285
317
  }
286
318
 
287
319
  const easyMerchantEvents = new NativeEventEmitter(RNEasymerchantsdk);
320
+
288
321
  const successSub = easyMerchantEvents.addListener('PaymentSuccess', (data) => {
289
322
  console.log('Payment success event:', data);
290
- const parsed = JSON.parse(data.response);
291
- console.log('Parsed PaymentSuccess:', parsed);
292
323
 
293
- if (parsed.billingInfo) {
294
- const billing = JSON.parse(parsed.billingInfo);
295
- console.log('Billing Info:', billing);
296
- }
324
+ try {
325
+ const parsed = JSON.parse(data.response);
326
+ console.log('Parsed PaymentSuccess:', parsed);
327
+
328
+ const billing = safeParseMaybeJSON(parsed.billingInfo);
329
+ const additional = safeParseMaybeJSON(parsed.additional_info);
297
330
 
298
- if (parsed.additional_info) {
299
- const additional = JSON.parse(parsed.additional_info);
331
+ console.log('Billing Info:', billing);
300
332
  console.log('Additional Info:', additional);
301
- }
302
333
 
303
- setResult(JSON.stringify(parsed, null, 2));
334
+ // Replace raw with parsed versions
335
+ parsed.billingInfo = billing;
336
+ parsed.additional_info = additional;
337
+
338
+ setResult(JSON.stringify(parsed, null, 2));
339
+ } catch (err) {
340
+ console.error('Error parsing PaymentSuccess response:', err);
341
+ }
304
342
  });
305
343
 
306
344
  const statusSub = easyMerchantEvents.addListener('PaymentStatus', (data) => {
307
345
  console.log('Raw Payment status event:', data);
308
- const parsed = JSON.parse(data.statusResponse);
309
- console.log('Parsed PaymentStatus:', parsed);
310
346
 
311
- setResult(JSON.stringify(parsed, null, 2));
347
+ try {
348
+ const parsed = JSON.parse(data.statusResponse);
349
+ console.log('Parsed PaymentStatus:', parsed);
350
+
351
+ setResult(JSON.stringify(parsed, null, 2));
352
+ } catch (err) {
353
+ console.error('Error parsing PaymentStatus response:', err);
354
+ }
312
355
  });
313
356
 
314
357
  const statusErrorSub = easyMerchantEvents.addListener('PaymentStatusError', (data) => {
@@ -324,36 +367,17 @@ if (Platform.OS !== 'android') {
324
367
  }, []);
325
368
 
326
369
 
327
-
328
- useEffect(() => {
329
- const updateEnvironment = async () => {
330
- const key = environment === 'staging'
331
- ? 'stagingApiKey'
332
- : 'sandboxApiKey';
333
- const secret = environment === 'staging'
334
- ? 'stagingApiSecret'
335
- : 'sandboxApiSecret';
336
-
337
- setApiKey(key);
338
- setApiSecret(secret);
339
-
340
- if (Platform.OS === 'ios') {
341
- setIsEnvironmentLoading(true);
342
- try {
343
- await EasyMerchantSdk.setViewController();
344
- await EasyMerchantSdk.configureEnvironment(environment, key, secret);
345
- console.log(`iOS Environment configured: ${environment} with key ${key}`);
346
- } catch (err) {
347
- console.error('iOS Initialization Error:', err);
348
- Alert.alert('Error', `Failed to configure iOS environment: ${err.message}`);
349
- } finally {
350
- setIsEnvironmentLoading(false);
351
- }
352
- }
353
- };
354
-
355
- updateEnvironment();
356
- }, [environment]);
370
+ const safeParseMaybeJSON = (value) => {
371
+ if (typeof value === 'string') {
372
+ try {
373
+ return JSON.parse(value);
374
+ } catch (e) {
375
+ console.warn('Failed to parse JSON string:', value);
376
+ return value;
377
+ }
378
+ }
379
+ return value;
380
+ };
357
381
 
358
382
  useEffect(() => {
359
383
  setBillingInfo(prev => ({
@@ -500,16 +524,18 @@ const handleAndroidBilling = async () => {
500
524
  };
501
525
 
502
526
  try {
503
- const response = await RNEasymerchantsdk.makePayment(config);
504
- console.log('Full payment response:', response);
527
+ const response = await RNEasymerchantsdk.makePayment(config);
528
+ console.log('Full payment response:', response);
505
529
 
506
- const parsedResponse = {
507
- ...response,
508
- billingInfo: response.billingInfo ? JSON.parse(response.billingInfo) : null,
509
- additional_info: response.additional_info ? JSON.parse(response.additional_info) : null,
510
- };
530
+ const parsedResponse = {
531
+ ...response,
532
+ billingInfo: safeParseMaybeJSON(response.billingInfo),
533
+ additional_info: safeParseMaybeJSON(response.additional_info),
534
+ };
535
+
536
+ console.log('Parsed safe response:', parsedResponse);
511
537
 
512
- setResult(JSON.stringify(parsedResponse, null, 2));
538
+ setResult(JSON.stringify(parsedResponse, null, 2));
513
539
  } catch (error) {
514
540
  setResult(`Error: ${error.message}`);
515
541
  Alert.alert('Payment Error', error.message);
@@ -595,6 +621,8 @@ const handleAndroidBilling = async () => {
595
621
  <ScrollView contentContainerStyle={styles.scrollContent}>
596
622
  <Text style={styles.title}>EasyMerchant SDK</Text>
597
623
 
624
+
625
+
598
626
  <Text style={styles.sectionTitle}>Basic Info</Text>
599
627
  <Text style={styles.label}>Amount</Text>
600
628
  <TextInput
@@ -613,603 +641,619 @@ const handleAndroidBilling = async () => {
613
641
  onChangeText={setEmail}
614
642
  />
615
643
 
616
- <Text style={styles.sectionTitle}>Environment</Text>
617
- <View style={styles.pickerContainer}>
618
- <Text style={styles.label}>Select Environment</Text>
619
- <View style={styles.buttonGroup}>
620
- <TouchableOpacity
621
- style={[
622
- styles.environmentButton,
623
- { backgroundColor: environment === 'sandbox' ? '#2563EB' : '#ccc' },
624
- ]}
625
- onPress={() => {
626
- console.log('Sandbox tapped, setting environment to sandbox');
627
- setEnvironment('sandbox');
628
- }}
629
- disabled={isEnvironmentLoading || environment === 'sandbox'}
630
- >
631
- <Text style={styles.buttonText}>Sandbox</Text>
632
- </TouchableOpacity>
633
- <TouchableOpacity
634
- style={[
635
- styles.environmentButton,
636
- { backgroundColor: environment === 'staging' ? '#2563EB' : '#ccc' },
637
- ]}
638
- onPress={() => {
639
- console.log('Staging tapped, setting environment to staging');
640
- setEnvironment('staging');
641
- }}
642
- disabled={isEnvironmentLoading || environment === 'staging'}
643
- >
644
- <Text style={styles.buttonText}>Staging</Text>
645
- </TouchableOpacity>
644
+ <View style={styles.buttonGroup}>
645
+ <Button title="Pay" onPress={handlePayment} />
646
+ {Platform.OS === 'ios' && (
647
+ <Button title="Payment Ref" onPress={handlePaymentReference} disabled={loading} />
648
+ )}
646
649
  </View>
647
- </View>
648
650
 
649
-
650
- <Text style={styles.sectionTitle}>Payment Options</Text>
651
- <View style={styles.toggleContainer}>
652
- <Text style={styles.label}>Recurring Payment</Text>
653
- <Switch
654
- value={isRecurring}
655
- onValueChange={setIsRecurring}
656
- trackColor={{ false: '#ccc', true: '#2563EB' }}
657
- thumbColor={isRecurring ? '#fff' : '#f4f3f4'}
658
- />
659
- </View>
660
- <View style={styles.toggleContainer}>
661
- <Text style={styles.label}>Authenticated ACH</Text>
662
- <Switch
663
- value={isAuthenticatedACH}
664
- onValueChange={setAuthenticatedACH}
665
- trackColor={{ false: '#ccc', true: '#2563EB' }}
666
- thumbColor={isAuthenticatedACH ? '#fff' : '#f4f3f4'}
667
- />
668
- </View>
669
- <View style={styles.toggleContainer}>
670
- <Text style={styles.label}>3DS</Text>
671
- <Switch
672
- value={isSecureAuthentication}
673
- onValueChange={setSecureAuthentication}
674
- trackColor={{ false: '#ccc', true: '#2563EB' }}
675
- thumbColor={isSecureAuthentication ? '#fff' : '#f4f3f4'}
676
- />
677
- </View>
678
- <View style={styles.toggleContainer}>
679
- <Text style={styles.label}>Billing Visible</Text>
680
- <Switch
681
- value={isBillingVisible}
682
- onValueChange={setBillingVisible}
683
- trackColor={{ false: '#ccc', true: '#2563EB' }}
684
- thumbColor={isBillingVisible ? '#fff' : '#f4f3f4'}
685
- />
686
- </View>
687
651
  <View style={styles.toggleContainer}>
688
- <Text style={styles.label}>Additional Info Visible</Text>
652
+ <Text style={styles.label}>Show Configurations</Text>
689
653
  <Switch
690
- value={isAdditionalVisible}
691
- onValueChange={setAdditionalVisible}
654
+ value={showConfig}
655
+ onValueChange={setShowConfig}
692
656
  trackColor={{ false: '#ccc', true: '#2563EB' }}
693
- thumbColor={isAdditionalVisible ? '#fff' : '#f4f3f4'}
694
- />
695
- </View>
696
- <Text style={styles.label}>Payment Methods (Shared)</Text>
697
- <View style={styles.buttonGroup}>
698
- <Button
699
- title="Card"
700
- onPress={() => togglePaymentMethod('card')}
701
- color={androidConfig.paymentMethod.includes('card') ? '#2563EB' : '#ccc'}
702
- />
703
- <Button
704
- title="ACH"
705
- onPress={() => togglePaymentMethod('ach')}
706
- color={androidConfig.paymentMethod.includes('ach') ? '#2563EB' : '#ccc'}
657
+ thumbColor={showConfig ? '#fff' : '#f4f3f4'}
707
658
  />
708
659
  </View>
709
- {Platform.OS === 'android' && (
710
- <View style={styles.toggleContainer}>
711
- <Text style={styles.label}>Email Editable (Android)</Text>
712
- <Switch
713
- value={emailEditable}
714
- onValueChange={setEmailEditable}
715
- trackColor={{ false: '#ccc', true: '#2563EB' }}
716
- thumbColor={emailEditable ? '#fff' : '#f4f3f4'}
717
- />
718
- </View>
719
- )}
720
- {Platform.OS === 'ios' && (
721
- <View style={styles.toggleContainer}>
722
- <Text style={styles.label}>Allow Email (iOS)</Text>
723
- <Switch
724
- value={isEmail}
725
- onValueChange={setIsEmail}
726
- trackColor={{ false: '#ccc', true: '#2563EB' }}
727
- thumbColor={isEmail ? '#fff' : '#f4f3f4'}
728
- />
729
- </View>
730
- )}
731
-
732
- <Text style={styles.sectionTitle}>Billing Info</Text>
733
- <Text style={styles.label}>Billing Address</Text>
734
- <TextInput
735
- style={styles.input}
736
- value={billingInfo.billing.address}
737
- onChangeText={value => updateBillingInfo('billing', 'address', value)}
738
- />
739
- <Text style={styles.label}>Billing Country</Text>
740
- <TextInput
741
- style={styles.input}
742
- value={billingInfo.billing.country}
743
- onChangeText={value => updateBillingInfo('billing', 'country', value)}
744
- />
745
- <Text style={styles.label}>Billing State</Text>
746
- <TextInput
747
- style={styles.input}
748
- value={billingInfo.billing.state}
749
- onChangeText={value => updateBillingInfo('billing', 'state', value)}
750
- />
751
- <Text style={styles.label}>Billing City</Text>
752
- <TextInput
753
- style={styles.input}
754
- value={billingInfo.billing.city}
755
- onChangeText={value => updateBillingInfo('billing', 'city', value)}
756
- />
757
- <Text style={styles.label}>Billing Postal Code</Text>
758
- <TextInput
759
- style={styles.input}
760
- value={billingInfo.billing.postal_code}
761
- onChangeText={value => updateBillingInfo('billing', 'postal_code', value)}
762
- />
763
- <Text style={styles.label}>Billing Required: Address</Text>
764
- <Switch
765
- value={billingInfo.billingRequired.address}
766
- onValueChange={value => updateBillingInfo('billingRequired', 'address', value)}
767
- trackColor={{ false: '#ccc', true: '#2563EB' }}
768
- thumbColor={billingInfo.billingRequired.address ? '#fff' : '#f4f3f4'}
769
- />
770
- <Text style={styles.label}>Billing Required: Country</Text>
771
- <Switch
772
- value={billingInfo.billingRequired.country}
773
- onValueChange={value => updateBillingInfo('billingRequired', 'country', value)}
774
- trackColor={{ false: '#ccc', true: '#2563EB' }}
775
- thumbColor={billingInfo.billingRequired.country ? '#fff' : '#f4f3f4'}
776
- />
777
- <Text style={styles.label}>Billing Required: State</Text>
778
- <Switch
779
- value={billingInfo.billingRequired.state}
780
- onValueChange={value => updateBillingInfo('billingRequired', 'state', value)}
781
- trackColor={{ false: '#ccc', true: '#2563EB' }}
782
- thumbColor={billingInfo.billingRequired.state ? '#fff' : '#f4f3f4'}
783
- />
784
- <Text style={styles.label}>Billing Required: City</Text>
785
- <Switch
786
- value={billingInfo.billingRequired.city}
787
- onValueChange={value => updateBillingInfo('billingRequired', 'city', value)}
788
- trackColor={{ false: '#ccc', true: '#2563EB' }}
789
- thumbColor={billingInfo.billingRequired.city ? '#fff' : '#f4f3f4'}
790
- />
791
- <Text style={styles.label}>Billing Required: Postal Code</Text>
792
- <Switch
793
- value={billingInfo.billingRequired.postal_code}
794
- onValueChange={value => updateBillingInfo('billingRequired', 'postal_code', value)}
795
- trackColor={{ false: '#ccc', true: '#2563EB' }}
796
- thumbColor={billingInfo.billingRequired.postal_code ? '#fff' : '#f4f3f4'}
797
- />
798
- <Text style={styles.label}>Additional: Name</Text>
799
- <TextInput
800
- style={styles.input}
801
- value={billingInfo.additional.name}
802
- onChangeText={value => updateBillingInfo('additional', 'name', value)}
803
- />
804
- <Text style={styles.label}>Additional: Email Address</Text>
805
- <TextInput
806
- style={styles.input}
807
- value={billingInfo.additional.email_address}
808
- onChangeText={value => updateBillingInfo('additional', 'email_address', value)}
809
- />
810
- <Text style={styles.label}>Additional: Phone Number</Text>
811
- <TextInput
812
- style={styles.input}
813
- value={billingInfo.additional.phone_number}
814
- onChangeText={value => updateBillingInfo('additional', 'phone_number', value)}
815
- />
816
- <Text style={styles.label}>Additional: Description</Text>
817
- <TextInput
818
- style={styles.input}
819
- value={billingInfo.additional.description}
820
- onChangeText={value => updateBillingInfo('additional', 'description', value)}
821
- />
822
- <Text style={styles.label}>Additional Required: Name</Text>
823
- <Switch
824
- value={billingInfo.additionalRequired.name}
825
- onValueChange={value => updateBillingInfo('additionalRequired', 'name', value)}
826
- trackColor={{ false: '#ccc', true: '#2563EB' }}
827
- thumbColor={billingInfo.additionalRequired.name ? '#fff' : '#f4f3f4'}
828
- />
829
- <Text style={styles.label}>Additional Required: Email Address</Text>
830
- <Switch
831
- value={billingInfo.additionalRequired.email_address}
832
- onValueChange={value => updateBillingInfo('additionalRequired', 'email_address', value)}
833
- trackColor={{ false: '#ccc', true: '#2563EB' }}
834
- thumbColor={billingInfo.additionalRequired.email_address ? '#fff' : '#f4f3f4'}
835
- />
836
- <Text style={styles.label}>Additional Required: Phone Number</Text>
837
- <Switch
838
- value={billingInfo.additionalRequired.phone_number}
839
- onValueChange={value => updateBillingInfo('additionalRequired', 'phone_number', value)}
840
- trackColor={{ false: '#ccc', true: '#2563EB' }}
841
- thumbColor={billingInfo.additionalRequired.phone_number ? '#fff' : '#f4f3f4'}
842
- />
843
- <Text style={styles.label}>Additional Required: Description</Text>
844
- <Switch
845
- value={billingInfo.additionalRequired.description}
846
- onValueChange={value => updateBillingInfo('additionalRequired', 'description', value)}
847
- trackColor={{ false: '#ccc', true: '#2563EB' }}
848
- thumbColor={billingInfo.additionalRequired.description ? '#fff' : '#f4f3f4'}
849
- />
850
660
 
851
- {Platform.OS === 'android' && (
661
+ {showConfig && (
852
662
  <>
853
- <Text style={styles.sectionTitle}>Android Configuration</Text>
854
- <Text style={styles.label}>Currency</Text>
855
- <TextInput
856
- style={styles.input}
857
- value={androidConfig.currency}
858
- onChangeText={value => updateAndroidConfig('currency', value)}
859
- />
860
- <Text style={styles.label}>Save Card</Text>
861
- <Switch
862
- value={androidConfig.saveCard}
863
- onValueChange={value => updateAndroidConfig('saveCard', value)}
864
- trackColor={{ false: '#ccc', true: '#2563EB' }}
865
- thumbColor={androidConfig.saveCard ? '#fff' : '#f4f3f4'}
866
- />
867
- <Text style={styles.label}>Save Account</Text>
868
- <Switch
869
- value={androidConfig.saveAccount}
870
- onValueChange={value => updateAndroidConfig('saveAccount', value)}
871
- trackColor={{ false: '#ccc', true: '#2563EB' }}
872
- thumbColor={androidConfig.saveAccount ? '#fff' : '#f4f3f4'}
873
- />
874
- <Text style={styles.label}>Show Receipt</Text>
875
- <Switch
876
- value={androidConfig.showReceipt}
877
- onValueChange={value => updateAndroidConfig('showReceipt', value)}
878
- trackColor={{ false: '#ccc', true: '#2563EB' }}
879
- thumbColor={androidConfig.showReceipt ? '#fff' : '#f4f3f4'}
880
- />
881
- <Text style={styles.label}>Show Donate</Text>
882
- <Switch
883
- value={androidConfig.showDonate}
884
- onValueChange={value => updateAndroidConfig('showDonate', value)}
885
- trackColor={{ false: '#ccc', true: '#2563EB' }}
886
- thumbColor={androidConfig.showDonate ? '#fff' : '#f4f3f4'}
887
- />
888
- <Text style={styles.label}>Show Total</Text>
889
- <Switch
890
- value={androidConfig.showTotal}
891
- onValueChange={value => updateAndroidConfig('showTotal', value)}
892
- trackColor={{ false: '#ccc', true: '#2563EB' }}
893
- thumbColor={androidConfig.showTotal ? '#fff' : '#f4f3f4'}
894
- />
895
- <Text style={styles.label}>Show Submit Button</Text>
896
- <Switch
897
- value={androidConfig.showSubmitButton}
898
- onValueChange={value => updateAndroidConfig('showSubmitButton', value)}
899
- trackColor={{ false: '#ccc', true: '#2563EB' }}
900
- thumbColor={androidConfig.showSubmitButton ? '#fff' : '#f4f3f4'}
901
- />
902
- <Text style={styles.label}>Name</Text>
903
- <TextInput
904
- style={styles.input}
905
- value={androidConfig.name}
906
- onChangeText={value => updateAndroidConfig('name', value)}
907
- />
908
- <Text style={styles.sectionTitle}>Android Fields</Text>
909
- {androidConfig.fields.billing.map((field, index) => (
910
- <View key={`billing-${index}`}>
911
- <Text style={styles.label}>{`Billing ${field.name}`}</Text>
912
- <TextInput
913
- style={styles.input}
914
- value={field.value}
915
- onChangeText={value => updateAndroidConfigFields('billing', index, 'value', value)}
916
- />
917
- <Text style={styles.label}>{`Billing ${field.name} Required`}</Text>
663
+ <Text style={styles.sectionTitle}>Environment</Text>
664
+ <View style={styles.pickerContainer}>
665
+ <Text style={styles.label}>Select Environment</Text>
666
+ <View style={styles.buttonGroup}>
667
+ <TouchableOpacity
668
+ style={[
669
+ styles.environmentButton,
670
+ { backgroundColor: environment === 'sandbox' ? '#2563EB' : '#ccc' },
671
+ ]}
672
+ onPress={() => {
673
+ console.log('Sandbox tapped, setting environment to sandbox');
674
+ setEnvironment('sandbox');
675
+ }}
676
+ disabled={isEnvironmentLoading || environment === 'sandbox'}
677
+ >
678
+ <Text style={styles.buttonText}>Sandbox</Text>
679
+ </TouchableOpacity>
680
+ <TouchableOpacity
681
+ style={[
682
+ styles.environmentButton,
683
+ { backgroundColor: environment === 'staging' ? '#2563EB' : '#ccc' },
684
+ ]}
685
+ onPress={() => {
686
+ console.log('Staging tapped, setting environment to staging');
687
+ setEnvironment('staging');
688
+ }}
689
+ disabled={isEnvironmentLoading || environment === 'staging'}
690
+ >
691
+ <Text style={styles.buttonText}>Staging</Text>
692
+ </TouchableOpacity>
693
+ </View>
694
+ </View>
695
+
696
+ <Text style={styles.sectionTitle}>Payment Options</Text>
697
+ <View style={styles.toggleContainer}>
698
+ <Text style={styles.label}>Recurring Payment</Text>
699
+ <Switch
700
+ value={isRecurring}
701
+ onValueChange={setIsRecurring}
702
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
703
+ thumbColor={isRecurring ? '#fff' : '#f4f3f4'}
704
+ />
705
+ </View>
706
+ <View style={styles.toggleContainer}>
707
+ <Text style={styles.label}>Authenticated ACH</Text>
708
+ <Switch
709
+ value={isAuthenticatedACH}
710
+ onValueChange={setAuthenticatedACH}
711
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
712
+ thumbColor={isAuthenticatedACH ? '#fff' : '#f4f3f4'}
713
+ />
714
+ </View>
715
+ <View style={styles.toggleContainer}>
716
+ <Text style={styles.label}>3DS</Text>
717
+ <Switch
718
+ value={isSecureAuthentication}
719
+ onValueChange={setSecureAuthentication}
720
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
721
+ thumbColor={isSecureAuthentication ? '#fff' : '#f4f3f4'}
722
+ />
723
+ </View>
724
+ <View style={styles.toggleContainer}>
725
+ <Text style={styles.label}>Billing Visible</Text>
726
+ <Switch
727
+ value={isBillingVisible}
728
+ onValueChange={setBillingVisible}
729
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
730
+ thumbColor={isBillingVisible ? '#fff' : '#f4f3f4'}
731
+ />
732
+ </View>
733
+ <View style={styles.toggleContainer}>
734
+ <Text style={styles.label}>Additional Info Visible</Text>
735
+ <Switch
736
+ value={isAdditionalVisible}
737
+ onValueChange={setAdditionalVisible}
738
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
739
+ thumbColor={isAdditionalVisible ? '#fff' : '#f4f3f4'}
740
+ />
741
+ </View>
742
+ <Text style={styles.label}>Payment Methods (Shared)</Text>
743
+ <View style={styles.buttonGroup}>
744
+ <Button
745
+ title="Card"
746
+ onPress={() => togglePaymentMethod('card')}
747
+ color={androidConfig.paymentMethod.includes('card') ? '#2563EB' : '#ccc'}
748
+ />
749
+ <Button
750
+ title="ACH"
751
+ onPress={() => togglePaymentMethod('ach')}
752
+ color={androidConfig.paymentMethod.includes('ach') ? '#2563EB' : '#ccc'}
753
+ />
754
+ </View>
755
+ {Platform.OS === 'android' && (
756
+ <View style={styles.toggleContainer}>
757
+ <Text style={styles.label}>Email Editable (Android)</Text>
918
758
  <Switch
919
- value={field.required}
920
- onValueChange={value => updateAndroidConfigFields('billing', index, 'required', value)}
759
+ value={emailEditable}
760
+ onValueChange={setEmailEditable}
921
761
  trackColor={{ false: '#ccc', true: '#2563EB' }}
922
- thumbColor={field.required ? '#fff' : '#f4f3f4'}
762
+ thumbColor={emailEditable ? '#fff' : '#f4f3f4'}
923
763
  />
924
764
  </View>
925
- ))}
926
- {androidConfig.fields.additional.map((field, index) => (
927
- <View key={`additional-${index}`}>
928
- <Text style={styles.label}>{`Additional ${field.name}`}</Text>
929
- <TextInput
930
- style={styles.input}
931
- value={field.value}
932
- onChangeText={value => updateAndroidConfigFields('additional', index, 'value', value)}
933
- />
934
- <Text style={styles.label}>{`Additional ${field.name} Required`}</Text>
765
+ )}
766
+ {Platform.OS === 'ios' && (
767
+ <View style={styles.toggleContainer}>
768
+ <Text style={styles.label}>Allow Email (iOS)</Text>
935
769
  <Switch
936
- value={field.required}
937
- onValueChange={value => updateAndroidConfigFields('additional', index, 'required', value)}
770
+ value={isEmail}
771
+ onValueChange={setIsEmail}
938
772
  trackColor={{ false: '#ccc', true: '#2563EB' }}
939
- thumbColor={field.required ? '#fff' : '#f4f3f4'}
773
+ thumbColor={isEmail ? '#fff' : '#f4f3f4'}
940
774
  />
941
775
  </View>
942
- ))}
943
- <Text style={styles.sectionTitle}>Android Appearance Settings</Text>
944
- <Text style={styles.label}>Theme</Text>
945
- <TextInput
946
- style={styles.input}
947
- value={androidConfig.appearanceSettings.theme}
948
- onChangeText={value => updateAndroidConfigAppearanceSettings('theme', value)}
949
- />
950
- <Text style={styles.label}>Body Background Color</Text>
951
- <TextInput
952
- style={styles.input}
953
- value={androidConfig.appearanceSettings.bodyBackgroundColor}
954
- onChangeText={value => updateAndroidConfigAppearanceSettings('bodyBackgroundColor', value)}
955
- />
956
- <Text style={styles.label}>Container Background Color</Text>
776
+ )}
777
+
778
+ <Text style={styles.sectionTitle}>Billing Info</Text>
779
+ <Text style={styles.label}>Billing Address</Text>
957
780
  <TextInput
958
781
  style={styles.input}
959
- value={androidConfig.appearanceSettings.containerBackgroundColor}
960
- onChangeText={value => updateAndroidConfigAppearanceSettings('containerBackgroundColor', value)}
782
+ value={billingInfo.billing.address}
783
+ onChangeText={value => updateBillingInfo('billing', 'address', value)}
961
784
  />
962
- <Text style={styles.label}>Primary Font Color</Text>
785
+ <Text style={styles.label}>Billing Country</Text>
963
786
  <TextInput
964
787
  style={styles.input}
965
- value={androidConfig.appearanceSettings.primaryFontColor}
966
- onChangeText={value => updateAndroidConfigAppearanceSettings('primaryFontColor', value)}
788
+ value={billingInfo.billing.country}
789
+ onChangeText={value => updateBillingInfo('billing', 'country', value)}
967
790
  />
968
- <Text style={styles.label}>Secondary Font Color</Text>
791
+ <Text style={styles.label}>Billing State</Text>
969
792
  <TextInput
970
793
  style={styles.input}
971
- value={androidConfig.appearanceSettings.secondaryFontColor}
972
- onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryFontColor', value)}
794
+ value={billingInfo.billing.state}
795
+ onChangeText={value => updateBillingInfo('billing', 'state', value)}
973
796
  />
974
- <Text style={styles.label}>Primary Button Background Color</Text>
797
+ <Text style={styles.label}>Billing City</Text>
975
798
  <TextInput
976
799
  style={styles.input}
977
- value={androidConfig.appearanceSettings.primaryButtonBackgroundColor}
978
- onChangeText={value => updateAndroidConfigAppearanceSettings('primaryButtonBackgroundColor', value)}
800
+ value={billingInfo.billing.city}
801
+ onChangeText={value => updateBillingInfo('billing', 'city', value)}
979
802
  />
980
- <Text style={styles.label}>Primary Button Hover Color</Text>
803
+ <Text style={styles.label}>Billing Postal Code</Text>
981
804
  <TextInput
982
805
  style={styles.input}
983
- value={androidConfig.appearanceSettings.primaryButtonHoverColor}
984
- onChangeText={value => updateAndroidConfigAppearanceSettings('primaryButtonHoverColor', value)}
806
+ value={billingInfo.billing.postal_code}
807
+ onChangeText={value => updateBillingInfo('billing', 'postal_code', value)}
985
808
  />
986
- <Text style={styles.label}>Primary Button Font Color</Text>
987
- <TextInput
988
- style={styles.input}
989
- value={androidConfig.appearanceSettings.primaryButtonFontColor}
990
- onChangeText={value => updateAndroidConfigAppearanceSettings('primaryButtonFontColor', value)}
809
+ <Text style={styles.label}>Billing Required: Address</Text>
810
+ <Switch
811
+ value={billingInfo.billingRequired.address}
812
+ onValueChange={value => updateBillingInfo('billingRequired', 'address', value)}
813
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
814
+ thumbColor={billingInfo.billingRequired.address ? '#fff' : '#f4f3f4'}
991
815
  />
992
- <Text style={styles.label}>Secondary Button Background Color</Text>
993
- <TextInput
994
- style={styles.input}
995
- value={androidConfig.appearanceSettings.secondaryButtonBackgroundColor}
996
- onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryButtonBackgroundColor', value)}
816
+ <Text style={styles.label}>Billing Required: Country</Text>
817
+ <Switch
818
+ value={billingInfo.billingRequired.country}
819
+ onValueChange={value => updateBillingInfo('billingRequired', 'country', value)}
820
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
821
+ thumbColor={billingInfo.billingRequired.country ? '#fff' : '#f4f3f4'}
997
822
  />
998
- <Text style={styles.label}>Secondary Button Hover Color</Text>
999
- <TextInput
1000
- style={styles.input}
1001
- value={androidConfig.appearanceSettings.secondaryButtonHoverColor}
1002
- onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryButtonHoverColor', value)}
823
+ <Text style={styles.label}>Billing Required: State</Text>
824
+ <Switch
825
+ value={billingInfo.billingRequired.state}
826
+ onChangeText={value => updateBillingInfo('billingRequired', 'state', value)}
827
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
828
+ thumbColor={billingInfo.billingRequired.state ? '#fff' : '#f4f3f4'}
1003
829
  />
1004
- <Text style={styles.label}>Secondary Button Font Color</Text>
1005
- <TextInput
1006
- style={styles.input}
1007
- value={androidConfig.appearanceSettings.secondaryButtonFontColor}
1008
- onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryButtonFontColor', value)}
830
+ <Text style={styles.label}>Billing Required: City</Text>
831
+ <Switch
832
+ value={billingInfo.billingRequired.city}
833
+ onValueChange={value => updateBillingInfo('billingRequired', 'city', value)}
834
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
835
+ thumbColor={billingInfo.billingRequired.city ? '#fff' : '#f4f3f4'}
1009
836
  />
1010
- <Text style={styles.label}>Border Radius</Text>
1011
- <TextInput
1012
- style={styles.input}
1013
- value={androidConfig.appearanceSettings.borderRadius}
1014
- onChangeText={value => updateAndroidConfigAppearanceSettings('borderRadius', value)}
837
+ <Text style={styles.label}>Billing Required: Postal Code</Text>
838
+ <Switch
839
+ value={billingInfo.billingRequired.postal_code}
840
+ onValueChange={value => updateBillingInfo('billingRequired', 'postal_code', value)}
841
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
842
+ thumbColor={billingInfo.billingRequired.postal_code ? '#fff' : '#f4f3f4'}
1015
843
  />
1016
- <Text style={styles.label}>Font Size</Text>
844
+ <Text style={styles.label}>Additional: Name</Text>
1017
845
  <TextInput
1018
846
  style={styles.input}
1019
- value={androidConfig.appearanceSettings.fontSize}
1020
- onChangeText={value => updateAndroidConfigAppearanceSettings('fontSize', value)}
847
+ value={billingInfo.additional.name}
848
+ onChangeText={value => updateBillingInfo('additional', 'name', value)}
1021
849
  />
1022
- <Text style={styles.label}>Font Weight</Text>
850
+ <Text style={styles.label}>Additional: Email Address</Text>
1023
851
  <TextInput
1024
852
  style={styles.input}
1025
- value={String(androidConfig.appearanceSettings.fontWeight)}
1026
- onChangeText={value => updateAndroidConfigAppearanceSettings('fontWeight', parseInt(value) || '500')}
853
+ value={billingInfo.additional.email_address}
854
+ onChangeText={value => updateBillingInfo('additional', 'email_address', value)}
1027
855
  />
1028
- <Text style={styles.label}>Font Family</Text>
856
+ <Text style={styles.label}>Additional: Phone Number</Text>
1029
857
  <TextInput
1030
858
  style={styles.input}
1031
- value={androidConfig.appearanceSettings.fontFamily}
1032
- onChangeText={value => updateAndroidConfigAppearanceSettings('fontFamily', value)}
859
+ value={billingInfo.additional.phone_number}
860
+ onChangeText={value => updateBillingInfo('additional', 'phone_number', value)}
1033
861
  />
1034
- </>
1035
- )}
1036
-
1037
- {Platform.OS === 'ios' && (
1038
- <>
1039
- <Text style={styles.sectionTitle}>Theme Configuration (iOS)</Text>
1040
- <Text style={styles.label}>Body Background Color</Text>
862
+ <Text style={styles.label}>Additional: Description</Text>
1041
863
  <TextInput
1042
864
  style={styles.input}
1043
- value={themeConfiguration.bodyBackgroundColor}
1044
- onChangeText={value => updateThemeConfiguration('bodyBackgroundColor', value)}
865
+ value={billingInfo.additional.description}
866
+ onChangeText={value => updateBillingInfo('additional', 'description', value)}
1045
867
  />
1046
- <Text style={styles.label}>Container Background Color</Text>
1047
- <TextInput
1048
- style={styles.input}
1049
- value={themeConfiguration.containerBackgroundColor}
1050
- onChangeText={value => updateThemeConfiguration('containerBackgroundColor', value)}
868
+ <Text style={styles.label}>Additional Required: Name</Text>
869
+ <Switch
870
+ value={billingInfo.additionalRequired.name}
871
+ onValueChange={value => updateBillingInfo('additionalRequired', 'name', value)}
872
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
873
+ thumbColor={billingInfo.additionalRequired.name ? '#fff' : '#f4f3f4'}
1051
874
  />
1052
- <Text style={styles.label}>Primary Font Color</Text>
1053
- <TextInput
1054
- style={styles.input}
1055
- value={themeConfiguration.primaryFontColor}
1056
- onChangeText={value => updateThemeConfiguration('primaryFontColor', value)}
875
+ <Text style={styles.label}>Additional Required: Email Address</Text>
876
+ <Switch
877
+ value={billingInfo.additionalRequired.email_address}
878
+ onValueChange={value => updateBillingInfo('additionalRequired', 'email_address', value)}
879
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
880
+ thumbColor={billingInfo.additionalRequired.email_address ? '#fff' : '#f4f3f4'}
1057
881
  />
1058
- <Text style={styles.label}>Secondary Font Color</Text>
1059
- <TextInput
1060
- style={styles.input}
1061
- value={themeConfiguration.secondaryFontColor}
1062
- onChangeText={value => updateThemeConfiguration('secondaryFontColor', value)}
882
+ <Text style={styles.label}>Additional Required: Phone Number</Text>
883
+ <Switch
884
+ value={billingInfo.additionalRequired.phone_number}
885
+ onValueChange={value => updateBillingInfo('additionalRequired', 'phone_number', value)}
886
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
887
+ thumbColor={billingInfo.additionalRequired.phone_number ? '#fff' : '#f4f3f4'}
1063
888
  />
1064
- <Text style={styles.label}>Primary Button Background Color</Text>
1065
- <TextInput
1066
- style={styles.input}
1067
- value={themeConfiguration.primaryButtonBackgroundColor}
1068
- onChangeText={value => updateThemeConfiguration('primaryButtonBackgroundColor', value)}
889
+ <Text style={styles.label}>Additional Required: Description</Text>
890
+ <Switch
891
+ value={billingInfo.additionalRequired.description}
892
+ onValueChange={value => updateBillingInfo('additionalRequired', 'description', value)}
893
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
894
+ thumbColor={billingInfo.additionalRequired.description ? '#fff' : '#f4f3f4'}
1069
895
  />
1070
- <Text style={styles.label}>Primary Button Hover Color</Text>
896
+
897
+ {/* Android Configuration */}
898
+ {Platform.OS === 'android' && (
899
+ <>
900
+ <Text style={styles.sectionTitle}>Android Configuration</Text>
901
+ <Text style={styles.label}>Currency</Text>
902
+ <TextInput
903
+ style={styles.input}
904
+ value={androidConfig.currency}
905
+ onChangeText={value => updateAndroidConfig('currency', value)}
906
+ />
907
+ <Text style={styles.label}>Save Card</Text>
908
+ <Switch
909
+ value={androidConfig.saveCard}
910
+ onValueChange={value => updateAndroidConfig('saveCard', value)}
911
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
912
+ thumbColor={androidConfig.saveCard ? '#fff' : '#f4f3f4'}
913
+ />
914
+ <Text style={styles.label}>Save Account</Text>
915
+ <Switch
916
+ value={androidConfig.saveAccount}
917
+ onValueChange={value => updateAndroidConfig('saveAccount', value)}
918
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
919
+ thumbColor={androidConfig.saveAccount ? '#fff' : '#f4f3f4'}
920
+ />
921
+ <Text style={styles.label}>Show Receipt</Text>
922
+ <Switch
923
+ value={androidConfig.showReceipt}
924
+ onValueChange={value => updateAndroidConfig('showReceipt', value)}
925
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
926
+ thumbColor={androidConfig.showReceipt ? '#fff' : '#f4f3f4'}
927
+ />
928
+ <Text style={styles.label}>Show Donate</Text>
929
+ <Switch
930
+ value={androidConfig.showDonate}
931
+ onValueChange={value => updateAndroidConfig('showDonate', value)}
932
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
933
+ thumbColor={androidConfig.showDonate ? '#fff' : '#f4f3f4'}
934
+ />
935
+ <Text style={styles.label}>Show Total</Text>
936
+ <Switch
937
+ value={androidConfig.showTotal}
938
+ onValueChange={value => updateAndroidConfig('showTotal', value)}
939
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
940
+ thumbColor={androidConfig.showTotal ? '#fff' : '#f4f3f4'}
941
+ />
942
+ <Text style={styles.label}>Show Submit Button</Text>
943
+ <Switch
944
+ value={androidConfig.showSubmitButton}
945
+ onValueChange={value => updateAndroidConfig('showSubmitButton', value)}
946
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
947
+ thumbColor={androidConfig.showSubmitButton ? '#fff' : '#f4f3f4'}
948
+ />
949
+ <Text style={styles.label}>Name</Text>
950
+ <TextInput
951
+ style={styles.input}
952
+ value={androidConfig.name}
953
+ onChangeText={value => updateAndroidConfig('name', value)}
954
+ />
955
+ <Text style={styles.sectionTitle}>Android Fields</Text>
956
+ {androidConfig.fields.billing.map((field, index) => (
957
+ <View key={`billing-${index}`}>
958
+ <Text style={styles.label}>{`Billing ${field.name}`}</Text>
959
+ <TextInput
960
+ style={styles.input}
961
+ value={field.value}
962
+ onChangeText={value => updateAndroidConfigFields('billing', index, 'value', value)}
963
+ />
964
+ <Text style={styles.label}>{`Billing ${field.name} Required`}</Text>
965
+ <Switch
966
+ value={field.required}
967
+ onValueChange={value => updateAndroidConfigFields('billing', index, 'required', value)}
968
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
969
+ thumbColor={field.required ? '#fff' : '#f4f3f4'}
970
+ />
971
+ </View>
972
+ ))}
973
+ {androidConfig.fields.additional.map((field, index) => (
974
+ <View key={`additional-${index}`}>
975
+ <Text style={styles.label}>{`Additional ${field.name}`}</Text>
976
+ <TextInput
977
+ style={styles.input}
978
+ value={field.value}
979
+ onChangeText={value => updateAndroidConfigFields('additional', index, 'value', value)}
980
+ />
981
+ <Text style={styles.label}>{`Additional ${field.name} Required`}</Text>
982
+ <Switch
983
+ value={field.required}
984
+ onValueChange={value => updateAndroidConfigFields('additional', index, 'required', value)}
985
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
986
+ thumbColor={field.required ? '#fff' : '#f4f3f4'}
987
+ />
988
+ </View>
989
+ ))}
990
+ <Text style={styles.sectionTitle}>Android Appearance Settings</Text>
991
+ <Text style={styles.label}>Theme</Text>
992
+ <TextInput
993
+ style={styles.input}
994
+ value={androidConfig.appearanceSettings.theme}
995
+ onChangeText={value => updateAndroidConfigAppearanceSettings('theme', value)}
996
+ />
997
+ <Text style={styles.label}>Body Background Color</Text>
998
+ <TextInput
999
+ style={styles.input}
1000
+ value={androidConfig.appearanceSettings.bodyBackgroundColor}
1001
+ onChangeText={value => updateAndroidConfigAppearanceSettings('bodyBackgroundColor', value)}
1002
+ />
1003
+ <Text style={styles.label}>Container Background Color</Text>
1004
+ <TextInput
1005
+ style={styles.input}
1006
+ value={androidConfig.appearanceSettings.containerBackgroundColor}
1007
+ onChangeText={value => updateAndroidConfigAppearanceSettings('containerBackgroundColor', value)}
1008
+ />
1009
+ <Text style={styles.label}>Primary Font Color</Text>
1010
+ <TextInput
1011
+ style={styles.input}
1012
+ value={androidConfig.appearanceSettings.primaryFontColor}
1013
+ onChangeText={value => updateAndroidConfigAppearanceSettings('primaryFontColor', value)}
1014
+ />
1015
+ <Text style={styles.label}>Secondary Font Color</Text>
1016
+ <TextInput
1017
+ style={styles.input}
1018
+ value={androidConfig.appearanceSettings.secondaryFontColor}
1019
+ onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryFontColor', value)}
1020
+ />
1021
+ <Text style={styles.label}>Primary Button Background Color</Text>
1022
+ <TextInput
1023
+ style={styles.input}
1024
+ value={androidConfig.appearanceSettings.primaryButtonBackgroundColor}
1025
+ onChangeText={value => updateAndroidConfigAppearanceSettings('primaryButtonBackgroundColor', value)}
1026
+ />
1027
+ <Text style={styles.label}>Primary Button Hover Color</Text>
1028
+ <TextInput
1029
+ style={styles.input}
1030
+ value={androidConfig.appearanceSettings.primaryButtonHoverColor}
1031
+ onChangeText={value => updateAndroidConfigAppearanceSettings('primaryButtonHoverColor', value)}
1032
+ />
1033
+ <Text style={styles.label}>Primary Button Font Color</Text>
1034
+ <TextInput
1035
+ style={styles.input}
1036
+ value={androidConfig.appearanceSettings.primaryButtonFontColor}
1037
+ onChangeText={value => updateAndroidConfigAppearanceSettings('primaryButtonFontColor', value)}
1038
+ />
1039
+ <Text style={styles.label}>Secondary Button Background Color</Text>
1040
+ <TextInput
1041
+ style={styles.input}
1042
+ value={androidConfig.appearanceSettings.secondaryButtonBackgroundColor}
1043
+ onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryButtonBackgroundColor', value)}
1044
+ />
1045
+ <Text style={styles.label}>Secondary Button Hover Color</Text>
1046
+ <TextInput
1047
+ style={styles.input}
1048
+ value={androidConfig.appearanceSettings.secondaryButtonHoverColor}
1049
+ onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryButtonHoverColor', value)}
1050
+ />
1051
+ <Text style={styles.label}>Secondary Button Font Color</Text>
1052
+ <TextInput
1053
+ style={styles.input}
1054
+ value={androidConfig.appearanceSettings.secondaryButtonFontColor}
1055
+ onChangeText={value => updateAndroidConfigAppearanceSettings('secondaryButtonFontColor', value)}
1056
+ />
1057
+ <Text style={styles.label}>Border Radius</Text>
1058
+ <TextInput
1059
+ style={styles.input}
1060
+ value={androidConfig.appearanceSettings.borderRadius}
1061
+ onChangeText={value => updateAndroidConfigAppearanceSettings('borderRadius', value)}
1062
+ />
1063
+ <Text style={styles.label}>Font Size</Text>
1064
+ <TextInput
1065
+ style={styles.input}
1066
+ value={androidConfig.appearanceSettings.fontSize}
1067
+ onChangeText={value => updateAndroidConfigAppearanceSettings('fontSize', value)}
1068
+ />
1069
+ <Text style={styles.label}>Font Weight</Text>
1070
+ <TextInput
1071
+ style={styles.input}
1072
+ value={String(androidConfig.appearanceSettings.fontWeight)}
1073
+ onChangeText={value => updateAndroidConfigAppearanceSettings('fontWeight', parseInt(value) || '500')}
1074
+ />
1075
+ <Text style={styles.label}>Font Family</Text>
1076
+ <TextInput
1077
+ style={styles.input}
1078
+ value={androidConfig.appearanceSettings.fontFamily}
1079
+ onChangeText={value => updateAndroidConfigAppearanceSettings('fontFamily', value)}
1080
+ />
1081
+ </>
1082
+ )}
1083
+
1084
+ {/* iOS Theme Configuration */}
1085
+ {Platform.OS === 'ios' && (
1086
+ <>
1087
+ <Text style={styles.sectionTitle}>Theme Configuration (iOS)</Text>
1088
+ <Text style={styles.label}>Body Background Color</Text>
1089
+ <TextInput
1090
+ style={styles.input}
1091
+ value={themeConfiguration.bodyBackgroundColor}
1092
+ onChangeText={value => updateThemeConfiguration('bodyBackgroundColor', value)}
1093
+ />
1094
+ <Text style={styles.label}>Container Background Color</Text>
1095
+ <TextInput
1096
+ style={styles.input}
1097
+ value={themeConfiguration.containerBackgroundColor}
1098
+ onChangeText={value => updateThemeConfiguration('containerBackgroundColor', value)}
1099
+ />
1100
+ <Text style={styles.label}>Primary Font Color</Text>
1101
+ <TextInput
1102
+ style={styles.input}
1103
+ value={themeConfiguration.primaryFontColor}
1104
+ onChangeText={value => updateThemeConfiguration('primaryFontColor', value)}
1105
+ />
1106
+ <Text style={styles.label}>Secondary Font Color</Text>
1107
+ <TextInput
1108
+ style={styles.input}
1109
+ value={themeConfiguration.secondaryFontColor}
1110
+ onChangeText={value => updateThemeConfiguration('secondaryFontColor', value)}
1111
+ />
1112
+ <Text style={styles.label}>Primary Button Background Color</Text>
1113
+ <TextInput
1114
+ style={styles.input}
1115
+ value={themeConfiguration.primaryButtonBackgroundColor}
1116
+ onChangeText={value => updateThemeConfiguration('primaryButtonBackgroundColor', value)}
1117
+ />
1118
+ <Text style={styles.label}>Primary Button Hover Color</Text>
1119
+ <TextInput
1120
+ style={styles.input}
1121
+ value={themeConfiguration.primaryButtonHoverColor}
1122
+ onChangeText={value => updateThemeConfiguration('primaryButtonHoverColor', value)}
1123
+ />
1124
+ <Text style={styles.label}>Primary Button Font Color</Text>
1125
+ <TextInput
1126
+ style={styles.input}
1127
+ value={themeConfiguration.primaryButtonFontColor}
1128
+ onChangeText={value => updateThemeConfiguration('primaryButtonFontColor', value)}
1129
+ />
1130
+ <Text style={styles.label}>Secondary Button Background Color</Text>
1131
+ <TextInput
1132
+ style={styles.input}
1133
+ value={themeConfiguration.secondaryButtonBackgroundColor}
1134
+ onChangeText={value => updateThemeConfiguration('secondaryButtonBackgroundColor', value)}
1135
+ />
1136
+ <Text style={styles.label}>Secondary Button Hover Color</Text>
1137
+ <TextInput
1138
+ style={styles.input}
1139
+ value={themeConfiguration.secondaryButtonHoverColor}
1140
+ onChangeText={value => updateThemeConfiguration('secondaryButtonHoverColor', value)}
1141
+ />
1142
+ <Text style={styles.label}>Secondary Button Font Color</Text>
1143
+ <TextInput
1144
+ style={styles.input}
1145
+ value={themeConfiguration.secondaryButtonFontColor}
1146
+ onChangeText={value => updateThemeConfiguration('secondaryButtonFontColor', value)}
1147
+ />
1148
+ <Text style={styles.label}>Border Radius</Text>
1149
+ <TextInput
1150
+ style={styles.input}
1151
+ value={themeConfiguration.borderRadius}
1152
+ onChangeText={value => updateThemeConfiguration('borderRadius', value)}
1153
+ />
1154
+ <Text style={styles.label}>Font Size</Text>
1155
+ <TextInput
1156
+ style={styles.input}
1157
+ value={themeConfiguration.fontSize}
1158
+ onChangeText={value => updateThemeConfiguration('fontSize', value)}
1159
+ />
1160
+ <Text style={styles.label}>Font Weight</Text>
1161
+ <TextInput
1162
+ style={styles.input}
1163
+ value={String(themeConfiguration.fontWeight)}
1164
+ onChangeText={value => updateThemeConfiguration('fontWeight', parseInt(value) || 500)}
1165
+ />
1166
+ <Text style={styles.label}>Font Family</Text>
1167
+ <TextInput
1168
+ style={styles.input}
1169
+ value={themeConfiguration.fontFamily}
1170
+ onChangeText={value => updateThemeConfiguration('fontFamily', value)}
1171
+ />
1172
+ </>
1173
+ )}
1174
+
1175
+ {/* GrailPay Parameters */}
1176
+ <Text style={styles.sectionTitle}>GrailPay Parameters</Text>
1177
+ <Text style={styles.label}>Role</Text>
1071
1178
  <TextInput
1072
1179
  style={styles.input}
1073
- value={themeConfiguration.primaryButtonHoverColor}
1074
- onChangeText={value => updateThemeConfiguration('primaryButtonHoverColor', value)}
1180
+ value={grailPayParams.role}
1181
+ onChangeText={value => updateGrailPayParams('role', value)}
1075
1182
  />
1076
- <Text style={styles.label}>Primary Button Font Color</Text>
1183
+ <Text style={styles.label}>Timeout</Text>
1077
1184
  <TextInput
1078
1185
  style={styles.input}
1079
- value={themeConfiguration.primaryButtonFontColor}
1080
- onChangeText={value => updateThemeConfiguration('primaryButtonFontColor', value)}
1186
+ value={String(grailPayParams.timeout)}
1187
+ onChangeText={value => updateGrailPayParams('timeout', parseInt(value) || 10)}
1081
1188
  />
1082
- <Text style={styles.label}>Secondary Button Background Color</Text>
1083
- <TextInput
1084
- style={styles.input}
1085
- value={themeConfiguration.secondaryButtonBackgroundColor}
1086
- onChangeText={value => updateThemeConfiguration('secondaryButtonBackgroundColor', value)}
1189
+ <Text style={styles.label}>Is Sandbox</Text>
1190
+ <Switch
1191
+ value={grailPayParams.isSandbox}
1192
+ onValueChange={value => updateGrailPayParams('isSandbox', value)}
1193
+ trackColor={{ false: '#ccc', true: '#2563EB' }}
1194
+ thumbColor={grailPayParams.isSandbox ? '#fff' : '#f4f3f4'}
1087
1195
  />
1088
- <Text style={styles.label}>Secondary Button Hover Color</Text>
1196
+ <Text style={styles.label}>Branding Name</Text>
1089
1197
  <TextInput
1090
1198
  style={styles.input}
1091
- value={themeConfiguration.secondaryButtonHoverColor}
1092
- onChangeText={value => updateThemeConfiguration('secondaryButtonHoverColor', value)}
1199
+ value={grailPayParams.brandingName}
1200
+ onChangeText={value => updateGrailPayParams('brandingName', value)}
1093
1201
  />
1094
- <Text style={styles.label}>Secondary Button Font Color</Text>
1202
+ <Text style={styles.label}>Finder Subtitle</Text>
1095
1203
  <TextInput
1096
1204
  style={styles.input}
1097
- value={themeConfiguration.secondaryButtonFontColor}
1098
- onChangeText={value => updateThemeConfiguration('secondaryButtonFontColor', value)}
1205
+ value={grailPayParams.finderSubtitle}
1206
+ onChangeText={value => updateGrailPayParams('finderSubtitle', value)}
1099
1207
  />
1100
- <Text style={styles.label}>Border Radius</Text>
1208
+ <Text style={styles.label}>Search Placeholder</Text>
1101
1209
  <TextInput
1102
1210
  style={styles.input}
1103
- value={themeConfiguration.borderRadius}
1104
- onChangeText={value => updateThemeConfiguration('borderRadius', value)}
1211
+ value={grailPayParams.searchPlaceholder}
1212
+ onChangeText={value => updateGrailPayParams('searchPlaceholder', value)}
1105
1213
  />
1106
- <Text style={styles.label}>Font Size</Text>
1214
+
1215
+ {/* Recurring Data */}
1216
+ <Text style={styles.sectionTitle}>Recurring Data</Text>
1217
+ <Text style={styles.label}>Allow Cycles</Text>
1107
1218
  <TextInput
1108
1219
  style={styles.input}
1109
- value={themeConfiguration.fontSize}
1110
- onChangeText={value => updateThemeConfiguration('fontSize', value)}
1220
+ value={String(recurringData.allowCycles)}
1221
+ onChangeText={value => updateRecurringData('allowCycles', parseInt(value) || 2)}
1111
1222
  />
1112
- <Text style={styles.label}>Font Weight</Text>
1223
+ <Text style={styles.label}>Intervals</Text>
1224
+ <View style={styles.buttonGroup}>
1225
+ <Button
1226
+ title="Weekly"
1227
+ onPress={() => toggleInterval('weekly')}
1228
+ color={recurringData.intervals.includes('weekly') ? '#2563EB' : '#ccc'}
1229
+ />
1230
+ <Button
1231
+ title="Monthly"
1232
+ onPress={() => toggleInterval('monthly')}
1233
+ color={recurringData.intervals.includes('monthly') ? '#2563EB' : '#ccc'}
1234
+ />
1235
+ </View>
1236
+ <Text style={styles.label}>Recurring Start Type</Text>
1113
1237
  <TextInput
1114
1238
  style={styles.input}
1115
- value={String(themeConfiguration.fontWeight)}
1116
- onChangeText={value => updateThemeConfiguration('fontWeight', parseInt(value) || 500)}
1239
+ value={recurringData.recurringStartType}
1240
+ onChangeText={value => updateRecurringData('recurringStartType', value)}
1117
1241
  />
1118
- <Text style={styles.label}>Font Family</Text>
1242
+ <Text style={styles.label}>Recurring Start Date</Text>
1119
1243
  <TextInput
1120
1244
  style={styles.input}
1121
- value={themeConfiguration.fontFamily}
1122
- onChangeText={value => updateThemeConfiguration('fontFamily', value)}
1245
+ value={recurringData.recurringStartDate}
1246
+ onChangeText={value => updateRecurringData('recurringStartDate', value)}
1123
1247
  />
1124
1248
  </>
1125
1249
  )}
1126
1250
 
1127
- <Text style={styles.sectionTitle}>GrailPay Parameters</Text>
1128
- <Text style={styles.label}>Role</Text>
1129
- <TextInput
1130
- style={styles.input}
1131
- value={grailPayParams.role}
1132
- onChangeText={value => updateGrailPayParams('role', value)}
1133
- />
1134
- <Text style={styles.label}>Timeout</Text>
1135
- <TextInput
1136
- style={styles.input}
1137
- value={String(grailPayParams.timeout)}
1138
- onChangeText={value => updateGrailPayParams('timeout', parseInt(value) || 10)}
1139
- />
1140
- <Text style={styles.label}>Is Sandbox</Text>
1141
- <Switch
1142
- value={grailPayParams.isSandbox}
1143
- onValueChange={value => updateGrailPayParams('isSandbox', value)}
1144
- trackColor={{ false: '#ccc', true: '#2563EB' }}
1145
- thumbColor={grailPayParams.isSandbox ? '#fff' : '#f4f3f4'}
1146
- />
1147
- <Text style={styles.label}>Branding Name</Text>
1148
- <TextInput
1149
- style={styles.input}
1150
- value={grailPayParams.brandingName}
1151
- onChangeText={value => updateGrailPayParams('brandingName', value)}
1152
- />
1153
- <Text style={styles.label}>Finder Subtitle</Text>
1154
- <TextInput
1155
- style={styles.input}
1156
- value={grailPayParams.finderSubtitle}
1157
- onChangeText={value => updateGrailPayParams('finderSubtitle', value)}
1158
- />
1159
- <Text style={styles.label}>Search Placeholder</Text>
1160
- <TextInput
1161
- style={styles.input}
1162
- value={grailPayParams.searchPlaceholder}
1163
- onChangeText={value => updateGrailPayParams('searchPlaceholder', value)}
1164
- />
1165
-
1166
- <Text style={styles.sectionTitle}>Recurring Data</Text>
1167
- <Text style={styles.label}>Allow Cycles</Text>
1168
- <TextInput
1169
- style={styles.input}
1170
- value={String(recurringData.allowCycles)}
1171
- onChangeText={value => updateRecurringData('allowCycles', parseInt(value) || 2)}
1172
- />
1173
- <Text style={styles.label}>Intervals</Text>
1174
- <View style={styles.buttonGroup}>
1175
- <Button
1176
- title="Weekly"
1177
- onPress={() => toggleInterval('weekly')}
1178
- color={recurringData.intervals.includes('weekly') ? '#2563EB' : '#ccc'}
1179
- />
1180
- <Button
1181
- title="Monthly"
1182
- onPress={() => toggleInterval('monthly')}
1183
- color={recurringData.intervals.includes('monthly') ? '#2563EB' : '#ccc'}
1184
- />
1185
- </View>
1186
- <Text style={styles.label}>Recurring Start Type</Text>
1187
- <TextInput
1188
- style={styles.input}
1189
- value={recurringData.recurringStartType}
1190
- onChangeText={value => updateRecurringData('recurringStartType', value)}
1191
- />
1192
- <Text style={styles.label}>Recurring Start Date</Text>
1193
- <TextInput
1194
- style={styles.input}
1195
- value={recurringData.recurringStartDate}
1196
- onChangeText={value => updateRecurringData('recurringStartDate', value)}
1197
- />
1198
-
1199
- <View style={styles.buttonGroup}>
1200
- <Button title="Pay" onPress={handlePayment} />
1201
- {Platform.OS === 'ios' ? (
1202
- <Button title="Payment Ref" onPress={handlePaymentReference} disabled={loading} />
1203
- ) : (
1204
- <></>
1205
- )
1206
- }
1207
- </View>
1208
-
1209
- <Text selectable style={styles.result}>{result}</Text>
1251
+ <Text style={styles.sectionTitle}>SDK Response</Text>
1252
+ <Text selectable style={styles.result}>{result || 'No response yet'}</Text>
1210
1253
  </ScrollView>
1211
1254
  </View>
1212
1255
  );
1256
+
1213
1257
  };
1214
1258
 
1215
1259
  export default App;