strapi-plugin-payone-provider 4.6.10 → 4.6.11

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 (62) hide show
  1. package/README.md +64 -0
  2. package/admin/src/pages/App/components/AppHeader.jsx +3 -2
  3. package/admin/src/pages/App/components/AppTabs.jsx +34 -88
  4. package/admin/src/pages/App/components/DocsPanel.jsx +1726 -1726
  5. package/admin/src/pages/App/components/GooglePaybutton.jsx +300 -300
  6. package/admin/src/pages/App/components/StatusBadge.jsx +1 -1
  7. package/admin/src/pages/App/components/common/InfoTooltip.jsx +16 -0
  8. package/admin/src/pages/App/components/{ApplePayConfig.jsx → configuration/ApplePayConfig.jsx} +191 -62
  9. package/admin/src/pages/App/components/{ApplePayConfigPanel.jsx → configuration/ApplePayConfigPanel.jsx} +71 -70
  10. package/admin/src/pages/App/components/configuration/ConfigurationFields.jsx +408 -0
  11. package/admin/src/pages/App/components/configuration/ConfigurationPanel.jsx +67 -0
  12. package/admin/src/pages/App/components/{GooglePayConfig.jsx → configuration/GooglePayConfig.jsx} +254 -254
  13. package/admin/src/pages/App/components/{GooglePayConfigPanel.jsx → configuration/GooglePayConfigPanel.jsx} +82 -82
  14. package/admin/src/pages/App/components/configuration/TestConnection.jsx +129 -0
  15. package/admin/src/pages/App/components/paymentActions/ApplePayPanel.jsx +137 -95
  16. package/admin/src/pages/App/components/paymentActions/CaptureForm.jsx +119 -14
  17. package/admin/src/pages/App/components/paymentActions/CardDetailsInput.jsx +85 -24
  18. package/admin/src/pages/App/components/paymentActions/PaymentActionsPanel.jsx +361 -0
  19. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.jsx +22 -4
  20. package/admin/src/pages/App/components/paymentActions/RefundForm.jsx +91 -20
  21. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationForm.jsx +157 -0
  22. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationFormFields.jsx +308 -0
  23. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationFormHeader.jsx +27 -0
  24. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationPaymentButtons.jsx +93 -0
  25. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationForm.jsx +134 -0
  26. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationFormFields.jsx +295 -0
  27. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationFormHeader.jsx +27 -0
  28. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationPaymentButtons.jsx +53 -0
  29. package/admin/src/pages/App/components/transaction-history/FiltersPanel.jsx +182 -0
  30. package/admin/src/pages/App/components/transaction-history/HistoryPanel.jsx +49 -0
  31. package/admin/src/pages/App/components/transaction-history/TransactionTable.jsx +169 -0
  32. package/admin/src/pages/App/components/transaction-history/TransactionTablePagination.jsx +28 -0
  33. package/admin/src/pages/App/components/transaction-history/details/TransactionDetails.jsx +155 -0
  34. package/admin/src/pages/App/index.jsx +5 -29
  35. package/admin/src/pages/hooks/usePaymentActions.js +87 -11
  36. package/admin/src/pages/hooks/useSettings.js +64 -22
  37. package/admin/src/pages/hooks/useTransactionHistory.js +100 -88
  38. package/admin/src/pages/utils/api.js +31 -3
  39. package/admin/src/pages/utils/countryLanguageUtils.js +236 -0
  40. package/admin/src/pages/utils/transactionTableUtils.js +60 -0
  41. package/package.json +1 -1
  42. package/server/bootstrap.js +6 -6
  43. package/server/controllers/payone.js +27 -3
  44. package/server/policies/index.js +2 -1
  45. package/server/policies/is-payone-notification.js +31 -0
  46. package/server/routes/index.js +10 -0
  47. package/server/services/payone.js +11 -4
  48. package/server/services/settingsService.js +8 -2
  49. package/server/services/testConnectionService.js +11 -72
  50. package/server/services/transactionService.js +58 -78
  51. package/server/services/transactionStatusService.js +87 -0
  52. package/admin/src/pages/App/components/ConfigurationPanel.jsx +0 -517
  53. package/admin/src/pages/App/components/CustomerInfoPopover.jsx +0 -147
  54. package/admin/src/pages/App/components/HistoryPanel.jsx +0 -94
  55. package/admin/src/pages/App/components/PaymentActionsPanel.jsx +0 -280
  56. package/admin/src/pages/App/components/RawDataPopover.jsx +0 -113
  57. package/admin/src/pages/App/components/TransactionHistoryItem.jsx +0 -522
  58. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTableFilters.jsx +0 -113
  59. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTablePagination.jsx +0 -180
  60. package/admin/src/pages/App/components/TransactionHistoryTable/index.jsx +0 -225
  61. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +0 -197
  62. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +0 -142
@@ -1,4 +1,4 @@
1
- import { useState, useEffect } from "react";
1
+ import { useState, useEffect, useRef } from "react";
2
2
  import { useNotification } from "@strapi/helper-plugin";
3
3
  import payoneRequests from "../utils/api";
4
4
 
@@ -11,15 +11,31 @@ const useSettings = () => {
11
11
  key: "",
12
12
  mode: "test",
13
13
  api_version: "3.10",
14
- enable3DSecure: false
14
+ merchantName: "",
15
+ displayName: "",
16
+ domainName: "",
17
+ merchantIdentifier: "",
18
+ enable3DSecure: false,
19
+ enableCreditCard: false,
20
+ enablePayPal: false,
21
+ enableGooglePay: false,
22
+ enableApplePay: false,
23
+ enableSepaDirectDebit: false
15
24
  });
25
+
16
26
  const [isLoading, setIsLoading] = useState(false);
17
27
  const [isSaving, setIsSaving] = useState(false);
18
28
  const [isTesting, setIsTesting] = useState(false);
19
29
  const [testResult, setTestResult] = useState(null);
30
+ const saveTimeoutRef = useRef(null);
20
31
 
21
32
  useEffect(() => {
22
33
  loadSettings();
34
+ return () => {
35
+ if (saveTimeoutRef.current) {
36
+ clearTimeout(saveTimeoutRef.current);
37
+ }
38
+ };
23
39
  }, []);
24
40
 
25
41
  const loadSettings = async () => {
@@ -39,6 +55,37 @@ const useSettings = () => {
39
55
 
40
56
  const handleInputChange = (field, value) => {
41
57
  setSettings((prev) => ({ ...prev, [field]: value }));
58
+
59
+ if (saveTimeoutRef.current) {
60
+ clearTimeout(saveTimeoutRef.current);
61
+ }
62
+
63
+ saveTimeoutRef.current = setTimeout(async () => {
64
+ let updatedSettings;
65
+ setSettings((prev) => {
66
+ updatedSettings = { ...prev };
67
+ return prev;
68
+ });
69
+
70
+ setIsSaving(true);
71
+ try {
72
+ await payoneRequests.updateSettings(updatedSettings);
73
+ await loadSettings();
74
+ } catch (error) {
75
+ setSettings((prev) => {
76
+ const previousValue = prev[field];
77
+ return { ...prev, [field]: previousValue };
78
+ });
79
+
80
+ toggleNotification({
81
+ type: "warning",
82
+ message: "Failed to update settings"
83
+ });
84
+
85
+ } finally {
86
+ setIsSaving(false);
87
+ }
88
+ }, 1000);
42
89
  };
43
90
 
44
91
  const handlePaymentMethodToggle = async (field, value) => {
@@ -90,31 +137,26 @@ const useSettings = () => {
90
137
  setTestResult(null);
91
138
  try {
92
139
  const response = await payoneRequests.testConnection();
93
- if (response.data) {
94
- const result = response.data;
95
- setTestResult(result);
96
- if (result.success !== undefined) {
97
- toggleNotification({
98
- type: Boolean(result.success) ? "success" : "warning",
99
- message: result.message || "Test completed"
100
- });
101
- }
140
+ console.log("response test connection", response?.data, response?.data?.error?.ErrorMessage);
141
+ if (response?.data && response?.data?.success) {
142
+ setTestResult(response?.data);
143
+ toggleNotification({
144
+ type: "success",
145
+ message: response?.data?.message || "Test completed"
146
+ });
102
147
  } else {
103
- throw new Error("Invalid response format from server");
148
+ setTestResult(response?.data);
149
+ toggleNotification({
150
+ type: "warning",
151
+ message: response?.data?.error?.ErrorMessage
152
+ });
153
+
154
+ throw new Error(response?.data?.error?.ErrorMessage);
104
155
  }
105
156
  } catch (error) {
106
157
  toggleNotification({
107
158
  type: "warning",
108
- message: "Failed to test connection"
109
- });
110
- setTestResult({
111
- success: false,
112
- message:
113
- "Failed to test connection. Please check your network and server logs for details.",
114
- details: {
115
- errorCode: "NETWORK",
116
- rawResponse: error.message || "Network error"
117
- }
159
+ message: error?.message
118
160
  });
119
161
  } finally {
120
162
  setIsTesting(false);
@@ -1,17 +1,15 @@
1
1
  import { useState, useEffect } from "react";
2
+ import { useLocation, useHistory } from "react-router-dom";
2
3
  import { useNotification } from "@strapi/helper-plugin";
3
4
  import payoneRequests from "../utils/api";
4
5
 
5
- const DEFAULT_PAGE_SIZE = 10;
6
+ const PAGE_SIZE = 10;
6
7
 
7
8
  const useTransactionHistory = () => {
8
9
  const toggleNotification = useNotification();
9
- const [transactionHistory, setTransactionHistory] = useState([]);
10
- const [isLoadingHistory, setIsLoadingHistory] = useState(false);
11
- const [selectedTransaction, setSelectedTransaction] = useState(null);
12
- const [currentPage, setCurrentPage] = useState(1);
13
- const [pageSize, setPageSize] = useState(DEFAULT_PAGE_SIZE);
14
- // Calculate default dates
10
+ const location = useLocation();
11
+ const history = useHistory();
12
+
15
13
  const getDefaultDateFrom = () => {
16
14
  const date = new Date();
17
15
  date.setDate(date.getDate() - 30);
@@ -20,130 +18,144 @@ const useTransactionHistory = () => {
20
18
 
21
19
  const getDefaultDateTo = () => {
22
20
  const date = new Date();
23
- date.setDate(date.getDate() + 1); // Add 1 day to include today's transactions
21
+ date.setDate(date.getDate() + 1);
24
22
  return date.toISOString().split('T')[0];
25
23
  };
26
24
 
25
+ const getQueryParams = () => {
26
+ const searchParams = new URLSearchParams(location.search);
27
+ const page = parseInt(searchParams.get('page') || '1', 10);
28
+ const pageSize = parseInt(searchParams.get('pageSize') || String(PAGE_SIZE), 10);
29
+
30
+ return { page, pageSize };
31
+ };
32
+
27
33
  const [filters, setFilters] = useState({
28
34
  search: "",
35
+ status: "",
29
36
  request_type: "",
30
37
  payment_method: "",
31
38
  date_from: getDefaultDateFrom(),
32
39
  date_to: getDefaultDateTo(),
33
- status: ""
34
40
  });
35
41
 
36
- const [sorting, setSorting] = useState({
37
- sortBy: null,
38
- sortOrder: null // 'asc' or 'desc'
42
+ const initialQueryParams = getQueryParams();
43
+ const [pagination, setPagination] = useState({
44
+ page: initialQueryParams.page,
45
+ pageSize: initialQueryParams.pageSize,
46
+ pageCount: 1,
47
+ total: 0,
39
48
  });
40
49
 
41
- useEffect(() => {
42
- loadTransactionHistory();
43
- }, []);
50
+ const [transactionHistory, setTransactionHistory] = useState([]);
51
+ const [isLoadingHistory, setIsLoadingHistory] = useState(false);
52
+ const [selectedTransaction, setSelectedTransaction] = useState(null);
44
53
 
45
54
  const loadTransactionHistory = async () => {
46
55
  setIsLoadingHistory(true);
47
56
  try {
48
- const params = { ...filters };
49
- if (sorting.sortBy && sorting.sortOrder) {
50
- params.sort_by = sorting.sortBy;
51
- params.sort_order = sorting.sortOrder;
57
+ const response = await payoneRequests.getTransactionHistory({
58
+ filters,
59
+ pagination
60
+ });
61
+
62
+ if (response && response.data && response.pagination) {
63
+ setTransactionHistory(response.data);
64
+ setPagination(response.pagination);
65
+ } else {
66
+ setTransactionHistory([]);
67
+ setPagination((prev) => ({
68
+ ...prev,
69
+ pageCount: 1,
70
+ total: 0,
71
+ }));
52
72
  }
53
- const result = await payoneRequests.getTransactionHistory(params);
54
- setTransactionHistory(result.data || []);
55
- setCurrentPage(1);
56
73
  } catch (error) {
74
+ console.error("Error loading transaction history:", error);
75
+ setTransactionHistory([]);
76
+ setPagination((prev) => ({
77
+ ...prev,
78
+ pageCount: 1,
79
+ total: 0,
80
+ }));
57
81
  toggleNotification({
58
82
  type: "warning",
59
- message: "Failed to load transaction history"
83
+ message: "Failed to load transaction history",
60
84
  });
61
85
  } finally {
62
86
  setIsLoadingHistory(false);
63
87
  }
64
88
  };
65
89
 
66
- const handleFilterChange = (field, value) => {
67
- setFilters((prev) => ({ ...prev, [field]: value }));
68
- };
69
-
70
- const handleFilterApply = () => {
71
- loadTransactionHistory();
72
- };
73
-
74
- const handleSort = (column) => {
75
- setSorting((prev) => {
76
- // If clicking the same column, cycle through: null -> asc -> desc -> null
77
- if (prev.sortBy === column) {
78
- if (!prev.sortOrder) {
79
- return { sortBy: column, sortOrder: "asc" };
80
- } else if (prev.sortOrder === "asc") {
81
- return { sortBy: column, sortOrder: "desc" };
82
- } else {
83
- return { sortBy: null, sortOrder: null };
84
- }
85
- } else {
86
- // If clicking a different column, reset and set new column to asc
87
- return { sortBy: column, sortOrder: "asc" };
88
- }
89
- });
90
- };
90
+ useEffect(() => {
91
+ const params = getQueryParams();
92
+ setPagination((prev) => ({
93
+ ...prev,
94
+ page: params.page,
95
+ pageSize: params.pageSize,
96
+ }));
97
+ }, [location.search]);
91
98
 
92
- // Reload when sorting changes (but not on initial mount)
93
- const [isInitialMount, setIsInitialMount] = useState(true);
94
-
95
99
  useEffect(() => {
96
- if (isInitialMount) {
97
- setIsInitialMount(false);
98
- return;
99
- }
100
- // Only reload if sorting is actually set or cleared
101
100
  loadTransactionHistory();
102
- // eslint-disable-next-line react-hooks/exhaustive-deps
103
- }, [sorting.sortBy, sorting.sortOrder]);
101
+ }, [
102
+ filters.search,
103
+ filters.status,
104
+ filters.request_type,
105
+ filters.payment_method,
106
+ filters.date_from,
107
+ filters.date_to,
108
+ pagination.page,
109
+ pagination.pageSize,
110
+ ]);
104
111
 
105
112
  const handleTransactionSelect = (transaction) => {
106
- if (selectedTransaction?.id === transaction?.id) {
107
- setSelectedTransaction(null);
108
- } else {
109
- setSelectedTransaction(transaction);
110
- }
113
+ setSelectedTransaction(
114
+ selectedTransaction?.id === transaction?.id ? null : transaction
115
+ );
111
116
  };
112
117
 
113
- const handlePageChange = (page) => {
114
- setCurrentPage(page);
115
- setSelectedTransaction(null);
118
+ const handlePaginationChange = (newPagination) => {
119
+ if (newPagination && typeof newPagination === "object") {
120
+ const updatedQuery = new URLSearchParams(location.search);
121
+ if (newPagination.page !== undefined) {
122
+ updatedQuery.set('page', String(newPagination.page));
123
+ }
124
+ if (newPagination.pageSize !== undefined) {
125
+ updatedQuery.set('pageSize', String(newPagination.pageSize));
126
+ updatedQuery.set('page', '1');
127
+ }
128
+ history.push({ search: updatedQuery.toString() });
129
+ }
116
130
  };
117
131
 
118
- const handlePageSizeChange = (newPageSize) => {
119
- setPageSize(newPageSize);
120
- setCurrentPage(1); // Reset to first page when page size changes
121
- setSelectedTransaction(null);
132
+ const handleFiltersChange = (newFilters) => {
133
+ if (newFilters && typeof newFilters === "object") {
134
+ setFilters((prev) => ({
135
+ ...prev,
136
+ ...newFilters,
137
+ }));
138
+ // Reset to first page when filters change
139
+ const updatedQuery = new URLSearchParams(location.search);
140
+ updatedQuery.set('page', '1');
141
+ history.push({ search: updatedQuery.toString() });
142
+ }
122
143
  };
123
144
 
124
- // Pagination calculations
125
- const totalPages = Math.ceil(transactionHistory.length / pageSize);
126
- const startIndex = (currentPage - 1) * pageSize;
127
- const endIndex = startIndex + pageSize;
128
- const paginatedTransactions = transactionHistory.slice(startIndex, endIndex);
145
+ useEffect(() => {
146
+ setSelectedTransaction(null);
147
+ }, [filters, pagination.page]);
129
148
 
130
149
  return {
131
- transactionHistory,
132
- paginatedTransactions,
150
+ transactions: Array.isArray(transactionHistory) ? transactionHistory : [],
133
151
  isLoadingHistory,
134
152
  selectedTransaction,
135
- filters,
136
- sorting,
137
- currentPage,
138
- totalPages,
139
- pageSize,
140
- handleFilterChange,
141
- handleFilterApply,
142
- handleSort,
143
153
  handleTransactionSelect,
144
- handlePageChange,
145
- handlePageSizeChange,
146
- loadTransactionHistory
154
+ loadTransactionHistory,
155
+ filters,
156
+ handleFiltersChange,
157
+ pagination,
158
+ handlePaginationChange,
147
159
  };
148
160
  };
149
161
 
@@ -15,14 +15,42 @@ const payoneRequests = {
15
15
  });
16
16
  },
17
17
 
18
- getTransactionHistory: (params = {}) => {
19
- const queryString = new URLSearchParams(params).toString();
20
- return request(
18
+ getTransactionHistory: async (params = {}) => {
19
+ const queryParams = new URLSearchParams();
20
+
21
+ if (params.filters) {
22
+ Object.keys(params.filters).forEach((key) => {
23
+ const value = params.filters[key];
24
+ if (value !== undefined && value !== null && value !== '') {
25
+ queryParams.append(`filters[${key}]`, String(value));
26
+ }
27
+ });
28
+ }
29
+
30
+ if (params.pagination) {
31
+ if (params.pagination.page) {
32
+ queryParams.append('pagination[page]', String(params.pagination.page));
33
+ }
34
+ if (params.pagination.pageSize) {
35
+ queryParams.append('pagination[pageSize]', String(params.pagination.pageSize));
36
+ }
37
+ }
38
+
39
+ if (params.sort_by) {
40
+ queryParams.append('sort_by', String(params.sort_by));
41
+ }
42
+ if (params.sort_order) {
43
+ queryParams.append('sort_order', String(params.sort_order));
44
+ }
45
+
46
+ const queryString = queryParams.toString();
47
+ const response = await request(
21
48
  `/${pluginId}/transaction-history${queryString ? `?${queryString}` : ""}`,
22
49
  {
23
50
  method: "GET"
24
51
  }
25
52
  );
53
+ return response;
26
54
  },
27
55
 
28
56
  testConnection: () => {
@@ -0,0 +1,236 @@
1
+ export const COUNTRY_LANGUAGE_MAP = {
2
+ US: "en",
3
+ GB: "en",
4
+ CA: "en",
5
+ AU: "en",
6
+ NZ: "en",
7
+ IE: "en",
8
+ DE: "de",
9
+ AT: "de",
10
+ CH: "de",
11
+ FR: "fr",
12
+ BE: "fr",
13
+ IT: "it",
14
+ ES: "es",
15
+ PT: "pt",
16
+ NL: "nl",
17
+ PL: "pl",
18
+ CZ: "cs",
19
+ HU: "hu",
20
+ SE: "sv",
21
+ NO: "no",
22
+ DK: "da",
23
+ FI: "fi",
24
+ GR: "el",
25
+ JP: "ja",
26
+ CN: "zh",
27
+ HK: "zh",
28
+ TW: "zh",
29
+ SG: "en",
30
+ BR: "pt",
31
+ MX: "es",
32
+ AE: "ar",
33
+ SA: "ar",
34
+ RU: "ru",
35
+ UA: "uk",
36
+ TR: "tr",
37
+ ZA: "en",
38
+ IN: "en",
39
+ };
40
+
41
+ export const COUNTRIES = [
42
+ { code: "US", name: "United States" },
43
+ { code: "GB", name: "United Kingdom" },
44
+ { code: "CA", name: "Canada" },
45
+ { code: "AU", name: "Australia" },
46
+ { code: "DE", name: "Germany" },
47
+ { code: "FR", name: "France" },
48
+ { code: "IT", name: "Italy" },
49
+ { code: "ES", name: "Spain" },
50
+ { code: "NL", name: "Netherlands" },
51
+ { code: "BE", name: "Belgium" },
52
+ { code: "CH", name: "Switzerland" },
53
+ { code: "AT", name: "Austria" },
54
+ { code: "IE", name: "Ireland" },
55
+ { code: "SE", name: "Sweden" },
56
+ { code: "NO", name: "Norway" },
57
+ { code: "DK", name: "Denmark" },
58
+ { code: "FI", name: "Finland" },
59
+ { code: "PL", name: "Poland" },
60
+ { code: "CZ", name: "Czech Republic" },
61
+ { code: "HU", name: "Hungary" },
62
+ { code: "PT", name: "Portugal" },
63
+ { code: "GR", name: "Greece" },
64
+ { code: "JP", name: "Japan" },
65
+ { code: "CN", name: "China" },
66
+ { code: "HK", name: "Hong Kong" },
67
+ { code: "TW", name: "Taiwan" },
68
+ { code: "SG", name: "Singapore" },
69
+ { code: "NZ", name: "New Zealand" },
70
+ { code: "BR", name: "Brazil" },
71
+ { code: "MX", name: "Mexico" },
72
+ { code: "AE", name: "United Arab Emirates" },
73
+ { code: "SA", name: "Saudi Arabia" },
74
+ { code: "RU", name: "Russia" },
75
+ { code: "UA", name: "Ukraine" },
76
+ { code: "TR", name: "Turkey" },
77
+ { code: "ZA", name: "South Africa" },
78
+ { code: "IN", name: "India" },
79
+ ];
80
+
81
+ export const getLanguageForCountry = (countryCode) => {
82
+ return COUNTRY_LANGUAGE_MAP[countryCode] || "en";
83
+ };
84
+
85
+ export const SALUTATION_OPTIONS = {
86
+ en: [
87
+ { value: "Mr", label: "Mr" },
88
+ { value: "Mrs", label: "Mrs" },
89
+ { value: "Ms", label: "Ms" },
90
+ { value: "Dr", label: "Dr" },
91
+ ],
92
+ de: [
93
+ { value: "Herr", label: "Herr" },
94
+ { value: "Frau", label: "Frau" },
95
+ { value: "Dr", label: "Dr" },
96
+ ],
97
+ fr: [
98
+ { value: "Monsieur", label: "Monsieur" },
99
+ { value: "Madame", label: "Madame" },
100
+ { value: "Mademoiselle", label: "Mademoiselle" },
101
+ ],
102
+ it: [
103
+ { value: "Signore", label: "Signore" },
104
+ { value: "Signora", label: "Signora" },
105
+ { value: "Signorina", label: "Signorina" },
106
+ ],
107
+ es: [
108
+ { value: "Señor", label: "Señor" },
109
+ { value: "Señora", label: "Señora" },
110
+ { value: "Señorita", label: "Señorita" },
111
+ ],
112
+ nl: [
113
+ { value: "Dhr", label: "Dhr" },
114
+ { value: "Mevr", label: "Mevr" },
115
+ ],
116
+ pt: [
117
+ { value: "Senhor", label: "Senhor" },
118
+ { value: "Senhora", label: "Senhora" },
119
+ ],
120
+ default: [
121
+ { value: "Mr", label: "Mr" },
122
+ { value: "Mrs", label: "Mrs" },
123
+ { value: "Ms", label: "Ms" },
124
+ ],
125
+ };
126
+
127
+ export const GENDER_OPTIONS = {
128
+ en: [
129
+ { value: "m", label: "Male" },
130
+ { value: "f", label: "Female" },
131
+ ],
132
+ de: [
133
+ { value: "m", label: "Männlich" },
134
+ { value: "f", label: "Weiblich" },
135
+ ],
136
+ fr: [
137
+ { value: "m", label: "Masculin" },
138
+ { value: "f", label: "Féminin" },
139
+ ],
140
+ it: [
141
+ { value: "m", label: "Maschio" },
142
+ { value: "f", label: "Femmina" },
143
+ ],
144
+ es: [
145
+ { value: "m", label: "Masculino" },
146
+ { value: "f", label: "Femenino" },
147
+ ],
148
+ nl: [
149
+ { value: "m", label: "Man" },
150
+ { value: "f", label: "Vrouw" },
151
+ ],
152
+ pt: [
153
+ { value: "m", label: "Masculino" },
154
+ { value: "f", label: "Feminino" },
155
+ ],
156
+ default: [
157
+ { value: "m", label: "Male" },
158
+ { value: "f", label: "Female" },
159
+ ],
160
+ };
161
+
162
+ export const getSalutationOptions = (countryCode) => {
163
+ const language = getLanguageForCountry(countryCode);
164
+ return SALUTATION_OPTIONS[language] || SALUTATION_OPTIONS.default;
165
+ };
166
+
167
+ export const getGenderOptions = (countryCode) => {
168
+ const language = getLanguageForCountry(countryCode);
169
+ return GENDER_OPTIONS[language] || GENDER_OPTIONS.default;
170
+ };
171
+
172
+ export const CURRENCIES = [
173
+ { code: "USD", name: "US Dollar", symbol: "$" },
174
+ { code: "EUR", name: "Euro", symbol: "€" },
175
+ { code: "GBP", name: "British Pound", symbol: "£" },
176
+ { code: "CAD", name: "Canadian Dollar", symbol: "C$" },
177
+ { code: "AUD", name: "Australian Dollar", symbol: "A$" },
178
+ { code: "JPY", name: "Japanese Yen", symbol: "¥" },
179
+ { code: "CNY", name: "Chinese Yuan", symbol: "¥" },
180
+ { code: "HKD", name: "Hong Kong Dollar", symbol: "HK$" },
181
+ { code: "TWD", name: "Taiwan Dollar", symbol: "NT$" },
182
+ { code: "SGD", name: "Singapore Dollar", symbol: "S$" },
183
+ { code: "NZD", name: "New Zealand Dollar", symbol: "NZ$" },
184
+ { code: "BRL", name: "Brazilian Real", symbol: "R$" },
185
+ { code: "MXN", name: "Mexican Peso", symbol: "Mex$" },
186
+ { code: "AED", name: "UAE Dirham", symbol: "د.إ" },
187
+ { code: "SAR", name: "Saudi Riyal", symbol: "﷼" },
188
+ { code: "RUB", name: "Russian Ruble", symbol: "₽" },
189
+ { code: "UAH", name: "Ukrainian Hryvnia", symbol: "₴" },
190
+ { code: "TRY", name: "Turkish Lira", symbol: "₺" },
191
+ { code: "ZAR", name: "South African Rand", symbol: "R" },
192
+ { code: "CHF", name: "Swiss Franc", symbol: "CHF" },
193
+ { code: "SEK", name: "Swedish Krona", symbol: "kr" },
194
+ { code: "NOK", name: "Norwegian Krone", symbol: "kr" },
195
+ { code: "DKK", name: "Danish Krone", symbol: "kr" },
196
+ { code: "PLN", name: "Polish Zloty", symbol: "zł" },
197
+ { code: "CZK", name: "Czech Koruna", symbol: "Kč" },
198
+ { code: "HUF", name: "Hungarian Forint", symbol: "Ft" },
199
+ { code: "INR", name: "Indian Rupee", symbol: "₹" },
200
+ ];
201
+
202
+ export const getCurrencyOptions = () => {
203
+ return CURRENCIES.map((c) => ({
204
+ value: c.code,
205
+ label: `${c.name} (${c.code}) ${c.symbol}`,
206
+ }));
207
+ };
208
+
209
+ export const getCountryOptions = (paymentMethod) => {
210
+ let supportedCountryCodes = [];
211
+
212
+ if (paymentMethod === "apl") {
213
+ supportedCountryCodes = [
214
+ "US", "GB", "CA", "AU", "DE", "FR", "IT", "ES", "NL", "BE", "CH", "AT", "IE",
215
+ "SE", "NO", "DK", "FI", "PL", "CZ", "HU", "PT", "GR", "JP", "CN", "HK", "TW",
216
+ "SG", "NZ", "BR", "MX", "AE", "SA", "RU", "UA", "TR", "ZA"
217
+ ];
218
+ } else if (paymentMethod === "gpp") {
219
+ supportedCountryCodes = [
220
+ "US", "GB", "CA", "AU", "DE", "FR", "IT", "ES", "NL", "BE", "CH", "AT", "IE",
221
+ "SE", "NO", "DK", "FI", "PL", "BR", "MX", "JP", "SG", "NZ", "IN"
222
+ ];
223
+ }
224
+
225
+ const hasRestriction = supportedCountryCodes.length > 0;
226
+
227
+ return COUNTRIES.map((country) => {
228
+ const isSupported = !hasRestriction || supportedCountryCodes.includes(country.code);
229
+ return {
230
+ value: country.code,
231
+ label: `${country.name} (${country.code})`,
232
+ disabled: hasRestriction && !isSupported,
233
+ };
234
+ });
235
+ };
236
+