strapi-plugin-payone-provider 5.7.26 → 5.8.26
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/README.md +1191 -1191
- package/admin/src/components/Initializer/index.jsx +16 -16
- package/admin/src/components/PluginIcon/index.jsx +17 -17
- package/admin/src/index.js +57 -57
- package/admin/src/pages/App/components/AppHeader.jsx +45 -45
- package/admin/src/pages/App/components/AppTabs.jsx +105 -105
- package/admin/src/pages/App/components/ApplePayBtn.jsx +355 -355
- package/admin/src/pages/App/components/ApplePayConfig.jsx +357 -357
- package/admin/src/pages/App/components/DocsPanel.jsx +53 -53
- package/admin/src/pages/App/components/RenderInput.jsx +78 -78
- package/admin/src/pages/App/components/StatusBadge.jsx +87 -87
- package/admin/src/pages/App/components/icons/BankIcon.jsx +10 -10
- package/admin/src/pages/App/components/icons/ChevronDownIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/ChevronUpIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/CreditCardIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/ErrorIcon.jsx +10 -10
- package/admin/src/pages/App/components/icons/InfoIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/MarkCircle.jsx +19 -19
- package/admin/src/pages/App/components/icons/PaymentIcon.jsx +10 -10
- package/admin/src/pages/App/components/icons/PendingIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/PersonIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/SuccessIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/WalletIcon.jsx +9 -9
- package/admin/src/pages/App/components/icons/index.jsx +12 -12
- package/admin/src/pages/App/components/payment-actions/AuthorizationForm.jsx +334 -334
- package/admin/src/pages/App/components/payment-actions/CaptureForm.jsx +120 -120
- package/admin/src/pages/App/components/payment-actions/PaymentActionsPanel.jsx +183 -183
- package/admin/src/pages/App/components/payment-actions/PaymentMethodSelector.jsx +315 -315
- package/admin/src/pages/App/components/payment-actions/PaymentResult.jsx +129 -129
- package/admin/src/pages/App/components/payment-actions/PreauthorizationForm.jsx +273 -273
- package/admin/src/pages/App/components/payment-actions/RefundForm.jsx +114 -114
- package/admin/src/pages/App/components/transaction-history/ImportExportBar.jsx +153 -153
- package/admin/src/pages/App/components/transaction-history/details/TransactionHistoryItem.jsx +526 -526
- package/admin/src/pages/App/index.jsx +96 -96
- package/admin/src/pages/App/styles.css +176 -176
- package/admin/src/pages/constants/paymentConstants.js +71 -71
- package/admin/src/pages/hooks/use-system-theme.js +27 -27
- package/admin/src/pages/hooks/usePaymentActions.js +498 -498
- package/admin/src/pages/hooks/usePluginTranslations.js +12 -12
- package/admin/src/pages/hooks/useSettings.js +183 -183
- package/admin/src/pages/hooks/useTransactionHistory.js +148 -148
- package/admin/src/pages/utils/api.js +97 -97
- package/admin/src/pages/utils/applePayConstants.js +196 -196
- package/admin/src/pages/utils/formatTransactionData.js +15 -15
- package/admin/src/pages/utils/getInputComponent.jsx +200 -200
- package/admin/src/pages/utils/paymentUtils.js +661 -661
- package/admin/src/pages/utils/tooltipHelpers.js +18 -18
- package/admin/src/pages/utils/transactionTableUtils.js +71 -71
- package/admin/src/pluginId.js +9 -9
- package/admin/src/translations/de.json +235 -235
- package/admin/src/translations/en.json +235 -235
- package/admin/src/translations/fr.json +235 -235
- package/admin/src/translations/ru.json +235 -235
- package/admin/src/utils/prefixPluginTranslations.js +13 -13
- package/package.json +45 -45
- package/server/bootstrap.js +107 -107
- package/server/config/index.js +83 -83
- package/server/content-types/index.js +4 -4
- package/server/content-types/transactions/index.js +4 -4
- package/server/content-types/transactions/schema.json +86 -86
- package/server/controllers/index.js +7 -7
- package/server/controllers/payone.js +503 -506
- package/server/destroy.js +5 -5
- package/server/index.js +23 -23
- package/server/policies/index.js +7 -7
- package/server/policies/is-auth.js +29 -29
- package/server/policies/isSuperAdmin.js +20 -20
- package/server/register.js +5 -5
- package/server/routes/index.js +218 -218
- package/server/services/applePayService.js +295 -295
- package/server/services/index.js +9 -9
- package/server/services/paymentService.js +264 -223
- package/server/services/payone.js +78 -78
- package/server/services/settingsService.js +59 -59
- package/server/services/testConnectionService.js +115 -115
- package/server/services/transactionService.js +262 -262
- package/server/utils/csvTransactions.js +82 -82
- package/server/utils/normalize.js +39 -39
- package/server/utils/paymentMethodParams.js +288 -288
- package/server/utils/requestBuilder.js +115 -100
- package/server/utils/responseParser.js +141 -141
- package/strapi-admin.js +4 -4
- package/strapi-server.js +3 -3
|
@@ -1,357 +1,357 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
Box,
|
|
4
|
-
Flex,
|
|
5
|
-
Typography,
|
|
6
|
-
Checkbox,
|
|
7
|
-
Divider,
|
|
8
|
-
} from "@strapi/design-system";
|
|
9
|
-
import RenderInput from "./RenderInput";
|
|
10
|
-
import { usePluginTranslations } from "../../hooks/usePluginTranslations";
|
|
11
|
-
import {
|
|
12
|
-
APPLE_PAY_SUPPORTED_COUNTRIES,
|
|
13
|
-
APPLE_PAY_SUPPORTED_NETWORKS,
|
|
14
|
-
APPLE_PAY_MERCHANT_CAPABILITIES,
|
|
15
|
-
getSupportedCurrenciesForCountry,
|
|
16
|
-
getSupportedNetworksForCountry,
|
|
17
|
-
APPLE_PAY_BUTTON_STYLES,
|
|
18
|
-
APPLE_PAY_BUTTON_TYPES,
|
|
19
|
-
DEFAULT_APPLE_PAY_CONFIG,
|
|
20
|
-
} from "../../utils/applePayConstants";
|
|
21
|
-
|
|
22
|
-
const ApplePayConfig = ({ config, onConfigChange, settings }) => {
|
|
23
|
-
const { t } = usePluginTranslations();
|
|
24
|
-
const {
|
|
25
|
-
countryCode = DEFAULT_APPLE_PAY_CONFIG.countryCode,
|
|
26
|
-
currencyCode = DEFAULT_APPLE_PAY_CONFIG.currencyCode,
|
|
27
|
-
merchantCapabilities = DEFAULT_APPLE_PAY_CONFIG.merchantCapabilities,
|
|
28
|
-
supportedNetworks = DEFAULT_APPLE_PAY_CONFIG.supportedNetworks,
|
|
29
|
-
buttonStyle = DEFAULT_APPLE_PAY_CONFIG.buttonStyle,
|
|
30
|
-
buttonType = DEFAULT_APPLE_PAY_CONFIG.buttonType,
|
|
31
|
-
} = config || {};
|
|
32
|
-
|
|
33
|
-
const supportedCurrencies = getSupportedCurrenciesForCountry(countryCode);
|
|
34
|
-
const supportedNetworksForCountry =
|
|
35
|
-
getSupportedNetworksForCountry(countryCode);
|
|
36
|
-
|
|
37
|
-
const handleCountryChange = (value) => {
|
|
38
|
-
const newConfig = {
|
|
39
|
-
...config,
|
|
40
|
-
countryCode: value,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
const newSupportedCurrencies = getSupportedCurrenciesForCountry(value);
|
|
44
|
-
if (!newSupportedCurrencies.find((c) => c.code === currencyCode)) {
|
|
45
|
-
newConfig.currencyCode = newSupportedCurrencies[0]?.code || "USD";
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
newConfig.supportedNetworks = getSupportedNetworksForCountry(value);
|
|
49
|
-
|
|
50
|
-
onConfigChange(newConfig);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const handleCurrencyChange = (value) => {
|
|
54
|
-
onConfigChange({
|
|
55
|
-
...config,
|
|
56
|
-
currencyCode: value,
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
const handleNetworkToggle = (networkCode) => {
|
|
61
|
-
const currentNetworks = supportedNetworks || [];
|
|
62
|
-
const newNetworks = currentNetworks.includes(networkCode)
|
|
63
|
-
? currentNetworks.filter((n) => n !== networkCode)
|
|
64
|
-
: [...currentNetworks, networkCode];
|
|
65
|
-
|
|
66
|
-
onConfigChange({
|
|
67
|
-
...config,
|
|
68
|
-
supportedNetworks: newNetworks,
|
|
69
|
-
});
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const handleCapabilityToggle = (capabilityCode) => {
|
|
73
|
-
const currentCapabilities = merchantCapabilities || [];
|
|
74
|
-
const newCapabilities = currentCapabilities.includes(capabilityCode)
|
|
75
|
-
? currentCapabilities.filter((c) => c !== capabilityCode)
|
|
76
|
-
: [...currentCapabilities, capabilityCode];
|
|
77
|
-
|
|
78
|
-
onConfigChange({
|
|
79
|
-
...config,
|
|
80
|
-
merchantCapabilities: newCapabilities,
|
|
81
|
-
});
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
return (
|
|
85
|
-
<Box>
|
|
86
|
-
<Flex direction="column" gap={6} alignItems="stretch">
|
|
87
|
-
{/* Country and Currency */}
|
|
88
|
-
<Box
|
|
89
|
-
style={{
|
|
90
|
-
display: "grid",
|
|
91
|
-
gridTemplateColumns: "repeat(2, 1fr)",
|
|
92
|
-
gap: "16px",
|
|
93
|
-
width: "100%",
|
|
94
|
-
}}
|
|
95
|
-
>
|
|
96
|
-
<Box>
|
|
97
|
-
<RenderInput
|
|
98
|
-
name="countryCode"
|
|
99
|
-
label={t("applePayConfig.countryCode", "Country Code")}
|
|
100
|
-
value={countryCode || ""}
|
|
101
|
-
onChange={(e) => {
|
|
102
|
-
const value = e.target?.value || e;
|
|
103
|
-
handleCountryChange(value);
|
|
104
|
-
}}
|
|
105
|
-
inputType="select"
|
|
106
|
-
required
|
|
107
|
-
tooltipContent={t("applePayConfig.countryTooltip", "Select the country where your business operates")}
|
|
108
|
-
options={APPLE_PAY_SUPPORTED_COUNTRIES.map((country) => ({
|
|
109
|
-
value: country.code,
|
|
110
|
-
label: `${country.name} (${country.code})`,
|
|
111
|
-
}))}
|
|
112
|
-
/>
|
|
113
|
-
</Box>
|
|
114
|
-
|
|
115
|
-
<Box>
|
|
116
|
-
<RenderInput
|
|
117
|
-
name="currencyCode"
|
|
118
|
-
label={t("applePayConfig.currencyCode", "Currency Code")}
|
|
119
|
-
value={currencyCode || ""}
|
|
120
|
-
onChange={(e) => {
|
|
121
|
-
const value = e.target?.value || e;
|
|
122
|
-
handleCurrencyChange(value);
|
|
123
|
-
}}
|
|
124
|
-
inputType="select"
|
|
125
|
-
required
|
|
126
|
-
tooltipContent={t("applePayConfig.currencyTooltip", "Supported currencies for {{country}}", { country: countryCode })}
|
|
127
|
-
options={supportedCurrencies.map((currency) => ({
|
|
128
|
-
value: currency.code,
|
|
129
|
-
label: `${currency.name} (${currency.code}) ${currency.symbol}`,
|
|
130
|
-
}))}
|
|
131
|
-
/>
|
|
132
|
-
{supportedCurrencies.length === 0 && (
|
|
133
|
-
<Typography
|
|
134
|
-
variant="pi"
|
|
135
|
-
textColor="danger600"
|
|
136
|
-
style={{ marginTop: "4px" }}
|
|
137
|
-
>
|
|
138
|
-
{t("applePayConfig.noCurrencies", "No supported currencies for this country. Please select a different country.")}
|
|
139
|
-
</Typography>
|
|
140
|
-
)}
|
|
141
|
-
</Box>
|
|
142
|
-
<Box>
|
|
143
|
-
<RenderInput
|
|
144
|
-
name="buttonStyle"
|
|
145
|
-
label={t("applePayConfig.buttonStyle", "Button Style")}
|
|
146
|
-
value={buttonStyle || ""}
|
|
147
|
-
onChange={(e) => {
|
|
148
|
-
const value = e.target?.value || e;
|
|
149
|
-
onConfigChange({ ...config, buttonStyle: value });
|
|
150
|
-
}}
|
|
151
|
-
inputType="select"
|
|
152
|
-
tooltipContent={t("applePayConfig.buttonStyleTooltip", "Visual style of the Apple Pay button")}
|
|
153
|
-
options={APPLE_PAY_BUTTON_STYLES.map((style) => ({
|
|
154
|
-
value: style.code,
|
|
155
|
-
label: style.name,
|
|
156
|
-
}))}
|
|
157
|
-
/>
|
|
158
|
-
</Box>
|
|
159
|
-
|
|
160
|
-
<Box>
|
|
161
|
-
<RenderInput
|
|
162
|
-
name="buttonType"
|
|
163
|
-
label={t("applePayConfig.buttonType", "Button Type")}
|
|
164
|
-
value={buttonType || ""}
|
|
165
|
-
onChange={(e) => {
|
|
166
|
-
const value = e.target?.value || e;
|
|
167
|
-
onConfigChange({ ...config, buttonType: value });
|
|
168
|
-
}}
|
|
169
|
-
inputType="select"
|
|
170
|
-
tooltipContent={t("applePayConfig.buttonTypeTooltip", "Type of action the button represents")}
|
|
171
|
-
options={APPLE_PAY_BUTTON_TYPES.map((type) => ({
|
|
172
|
-
value: type.code,
|
|
173
|
-
label: type.name,
|
|
174
|
-
}))}
|
|
175
|
-
/>
|
|
176
|
-
</Box>
|
|
177
|
-
</Box>
|
|
178
|
-
|
|
179
|
-
<Divider />
|
|
180
|
-
{/* Supported Networks */}
|
|
181
|
-
<Box>
|
|
182
|
-
<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
|
183
|
-
<Typography variant="pi" fontWeight="semiBold">
|
|
184
|
-
{t("applePayConfig.supportedNetworks", "Supported Networks")}
|
|
185
|
-
</Typography>
|
|
186
|
-
<Typography variant="pi" textColor="neutral600">
|
|
187
|
-
{t("applePayConfig.supportedNetworksHint", "Select payment networks supported in {{country}}", { country: countryCode })}
|
|
188
|
-
</Typography>
|
|
189
|
-
</div>
|
|
190
|
-
<Flex wrap="wrap" gap={4} style={{ marginTop: "12px" }}>
|
|
191
|
-
{APPLE_PAY_SUPPORTED_NETWORKS.map((network) => {
|
|
192
|
-
const isSupported = supportedNetworksForCountry.includes(
|
|
193
|
-
network.code
|
|
194
|
-
);
|
|
195
|
-
const isSelected = supportedNetworks?.includes(network.code);
|
|
196
|
-
|
|
197
|
-
return (
|
|
198
|
-
<Box
|
|
199
|
-
key={network.code}
|
|
200
|
-
style={{ flex: "0 0 calc(50% - 8px)", minWidth: "250px" }}
|
|
201
|
-
>
|
|
202
|
-
<Checkbox
|
|
203
|
-
name={`network-${network.code}`}
|
|
204
|
-
checked={isSelected}
|
|
205
|
-
onCheckedChange={() => handleNetworkToggle(network.code)}
|
|
206
|
-
disabled={!isSupported}
|
|
207
|
-
>
|
|
208
|
-
{network.name} ({network.code})
|
|
209
|
-
{!isSupported && (
|
|
210
|
-
<Typography
|
|
211
|
-
variant="sigma"
|
|
212
|
-
textColor="neutral500"
|
|
213
|
-
style={{ marginLeft: "8px" }}
|
|
214
|
-
>
|
|
215
|
-
{t("applePayConfig.notAvailable", "(Not available)")}
|
|
216
|
-
</Typography>
|
|
217
|
-
)}
|
|
218
|
-
</Checkbox>
|
|
219
|
-
</Box>
|
|
220
|
-
);
|
|
221
|
-
})}
|
|
222
|
-
</Flex>
|
|
223
|
-
{supportedNetworks?.length === 0 && (
|
|
224
|
-
<Typography
|
|
225
|
-
variant="pi"
|
|
226
|
-
textColor="danger600"
|
|
227
|
-
style={{ marginTop: "8px" }}
|
|
228
|
-
>
|
|
229
|
-
{t("applePayConfig.atLeastOneNetwork", "At least one network must be selected")}
|
|
230
|
-
</Typography>
|
|
231
|
-
)}
|
|
232
|
-
</Box>
|
|
233
|
-
|
|
234
|
-
<Divider />
|
|
235
|
-
|
|
236
|
-
{/* Merchant Capabilities */}
|
|
237
|
-
<Box>
|
|
238
|
-
<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
|
239
|
-
<Typography
|
|
240
|
-
variant="pi"
|
|
241
|
-
fontWeight="semiBold"
|
|
242
|
-
style={{ marginLeft: "2px" }}
|
|
243
|
-
>
|
|
244
|
-
{t("applePayConfig.merchantCapabilities", "Merchant Capabilities")}
|
|
245
|
-
</Typography>
|
|
246
|
-
<Typography
|
|
247
|
-
variant="pi"
|
|
248
|
-
textColor="neutral600"
|
|
249
|
-
style={{ marginLeft: "2px" }}
|
|
250
|
-
>
|
|
251
|
-
{t("applePayConfig.merchantCapabilitiesHint", "Select payment capabilities. \"3D Secure\" is required for most payment methods.")}
|
|
252
|
-
</Typography>
|
|
253
|
-
</div>
|
|
254
|
-
<Flex wrap="wrap" gap={4} style={{ marginTop: "12px" }}>
|
|
255
|
-
{APPLE_PAY_MERCHANT_CAPABILITIES.map((capability) => {
|
|
256
|
-
const isSelected = merchantCapabilities?.includes(
|
|
257
|
-
capability.code
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
return (
|
|
261
|
-
<Box
|
|
262
|
-
key={capability.code}
|
|
263
|
-
style={{ flex: "0 0 calc(50% - 8px)", minWidth: "250px" }}
|
|
264
|
-
>
|
|
265
|
-
<Checkbox
|
|
266
|
-
name={`capability-${capability.code}`}
|
|
267
|
-
checked={isSelected}
|
|
268
|
-
onCheckedChange={() =>
|
|
269
|
-
handleCapabilityToggle(capability.code)
|
|
270
|
-
}
|
|
271
|
-
>
|
|
272
|
-
{capability.name} - {capability.description}
|
|
273
|
-
</Checkbox>
|
|
274
|
-
</Box>
|
|
275
|
-
);
|
|
276
|
-
})}
|
|
277
|
-
</Flex>
|
|
278
|
-
{merchantCapabilities?.length === 0 && (
|
|
279
|
-
<Typography
|
|
280
|
-
variant="pi"
|
|
281
|
-
textColor="danger600"
|
|
282
|
-
style={{ marginTop: "8px" }}
|
|
283
|
-
>
|
|
284
|
-
{t("applePayConfig.atLeastOneCapability", "At least one capability must be selected. \"supports3DS\" is recommended.")}
|
|
285
|
-
</Typography>
|
|
286
|
-
)}
|
|
287
|
-
</Box>
|
|
288
|
-
|
|
289
|
-
<Divider />
|
|
290
|
-
|
|
291
|
-
{/* Domain Verification File Alert */}
|
|
292
|
-
<Flex
|
|
293
|
-
direction="column"
|
|
294
|
-
padding={3}
|
|
295
|
-
background="warning100"
|
|
296
|
-
borderRadius="4px"
|
|
297
|
-
borderColor="warning200"
|
|
298
|
-
borderWidth="1px"
|
|
299
|
-
borderStyle="solid"
|
|
300
|
-
alignItems="stretch"
|
|
301
|
-
gap={4}
|
|
302
|
-
>
|
|
303
|
-
<Typography variant="pi" fontWeight="bold" textColor="warning700">
|
|
304
|
-
⚠️ {t("applePayConfig.domainVerificationTitle", "Domain Verification File Required")}
|
|
305
|
-
</Typography>
|
|
306
|
-
<Typography variant="pi" textColor="neutral700">
|
|
307
|
-
<strong>{t("applePayConfig.domainVerificationDesc", "Download the Apple Pay domain verification file")}</strong>{" "}
|
|
308
|
-
{t("applePayConfig.domainVerificationDescSuffix", "from your Payone documentation:")}
|
|
309
|
-
</Typography>
|
|
310
|
-
<Box padding={2} background="neutral0" borderRadius="4px">
|
|
311
|
-
<Typography variant="pi" style={{ fontSize: "12px" }}>
|
|
312
|
-
<strong>{t("applePayConfig.downloadUrl", "Download URL:")}</strong>{" "}
|
|
313
|
-
<a
|
|
314
|
-
href="https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev"
|
|
315
|
-
target="_blank"
|
|
316
|
-
rel="noopener noreferrer"
|
|
317
|
-
style={{ color: "#0066ff", textDecoration: "underline" }}
|
|
318
|
-
>
|
|
319
|
-
https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev
|
|
320
|
-
</a>
|
|
321
|
-
</Typography>
|
|
322
|
-
</Box>
|
|
323
|
-
<Typography variant="pi" textColor="neutral700">
|
|
324
|
-
<strong>{t("applePayConfig.placeFileAt", "Place the file at:")}</strong>
|
|
325
|
-
</Typography>
|
|
326
|
-
<Box padding={2} background="neutral0" borderRadius="4px">
|
|
327
|
-
<Typography
|
|
328
|
-
variant="pi"
|
|
329
|
-
style={{ fontFamily: "monospace", fontSize: "12px" }}
|
|
330
|
-
>
|
|
331
|
-
<strong>Strapi:</strong>{" "}
|
|
332
|
-
<code>
|
|
333
|
-
public/.well-known/apple-developer-merchantid-domain-association
|
|
334
|
-
</code>
|
|
335
|
-
<br />
|
|
336
|
-
<strong>Frontend:</strong>{" "}
|
|
337
|
-
<code>
|
|
338
|
-
public/.well-known/apple-developer-merchantid-domain-association
|
|
339
|
-
</code>
|
|
340
|
-
</Typography>
|
|
341
|
-
</Box>
|
|
342
|
-
<Typography variant="pi" textColor="neutral700" marginTop={2}>
|
|
343
|
-
{t("applePayConfig.fileMustBeAccessible", "The file must be accessible at:")}{" "}
|
|
344
|
-
<code>
|
|
345
|
-
https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association
|
|
346
|
-
</code>
|
|
347
|
-
</Typography>
|
|
348
|
-
<Typography variant="pi" fontWeight="bold" textColor="danger600">
|
|
349
|
-
{t("applePayConfig.withoutFileWarning", "Without this file, Apple Pay will NOT work on your domain!")}
|
|
350
|
-
</Typography>
|
|
351
|
-
</Flex>
|
|
352
|
-
</Flex>
|
|
353
|
-
</Box>
|
|
354
|
-
);
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
export default ApplePayConfig;
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
Box,
|
|
4
|
+
Flex,
|
|
5
|
+
Typography,
|
|
6
|
+
Checkbox,
|
|
7
|
+
Divider,
|
|
8
|
+
} from "@strapi/design-system";
|
|
9
|
+
import RenderInput from "./RenderInput";
|
|
10
|
+
import { usePluginTranslations } from "../../hooks/usePluginTranslations";
|
|
11
|
+
import {
|
|
12
|
+
APPLE_PAY_SUPPORTED_COUNTRIES,
|
|
13
|
+
APPLE_PAY_SUPPORTED_NETWORKS,
|
|
14
|
+
APPLE_PAY_MERCHANT_CAPABILITIES,
|
|
15
|
+
getSupportedCurrenciesForCountry,
|
|
16
|
+
getSupportedNetworksForCountry,
|
|
17
|
+
APPLE_PAY_BUTTON_STYLES,
|
|
18
|
+
APPLE_PAY_BUTTON_TYPES,
|
|
19
|
+
DEFAULT_APPLE_PAY_CONFIG,
|
|
20
|
+
} from "../../utils/applePayConstants";
|
|
21
|
+
|
|
22
|
+
const ApplePayConfig = ({ config, onConfigChange, settings }) => {
|
|
23
|
+
const { t } = usePluginTranslations();
|
|
24
|
+
const {
|
|
25
|
+
countryCode = DEFAULT_APPLE_PAY_CONFIG.countryCode,
|
|
26
|
+
currencyCode = DEFAULT_APPLE_PAY_CONFIG.currencyCode,
|
|
27
|
+
merchantCapabilities = DEFAULT_APPLE_PAY_CONFIG.merchantCapabilities,
|
|
28
|
+
supportedNetworks = DEFAULT_APPLE_PAY_CONFIG.supportedNetworks,
|
|
29
|
+
buttonStyle = DEFAULT_APPLE_PAY_CONFIG.buttonStyle,
|
|
30
|
+
buttonType = DEFAULT_APPLE_PAY_CONFIG.buttonType,
|
|
31
|
+
} = config || {};
|
|
32
|
+
|
|
33
|
+
const supportedCurrencies = getSupportedCurrenciesForCountry(countryCode);
|
|
34
|
+
const supportedNetworksForCountry =
|
|
35
|
+
getSupportedNetworksForCountry(countryCode);
|
|
36
|
+
|
|
37
|
+
const handleCountryChange = (value) => {
|
|
38
|
+
const newConfig = {
|
|
39
|
+
...config,
|
|
40
|
+
countryCode: value,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const newSupportedCurrencies = getSupportedCurrenciesForCountry(value);
|
|
44
|
+
if (!newSupportedCurrencies.find((c) => c.code === currencyCode)) {
|
|
45
|
+
newConfig.currencyCode = newSupportedCurrencies[0]?.code || "USD";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
newConfig.supportedNetworks = getSupportedNetworksForCountry(value);
|
|
49
|
+
|
|
50
|
+
onConfigChange(newConfig);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const handleCurrencyChange = (value) => {
|
|
54
|
+
onConfigChange({
|
|
55
|
+
...config,
|
|
56
|
+
currencyCode: value,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleNetworkToggle = (networkCode) => {
|
|
61
|
+
const currentNetworks = supportedNetworks || [];
|
|
62
|
+
const newNetworks = currentNetworks.includes(networkCode)
|
|
63
|
+
? currentNetworks.filter((n) => n !== networkCode)
|
|
64
|
+
: [...currentNetworks, networkCode];
|
|
65
|
+
|
|
66
|
+
onConfigChange({
|
|
67
|
+
...config,
|
|
68
|
+
supportedNetworks: newNetworks,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const handleCapabilityToggle = (capabilityCode) => {
|
|
73
|
+
const currentCapabilities = merchantCapabilities || [];
|
|
74
|
+
const newCapabilities = currentCapabilities.includes(capabilityCode)
|
|
75
|
+
? currentCapabilities.filter((c) => c !== capabilityCode)
|
|
76
|
+
: [...currentCapabilities, capabilityCode];
|
|
77
|
+
|
|
78
|
+
onConfigChange({
|
|
79
|
+
...config,
|
|
80
|
+
merchantCapabilities: newCapabilities,
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
return (
|
|
85
|
+
<Box>
|
|
86
|
+
<Flex direction="column" gap={6} alignItems="stretch">
|
|
87
|
+
{/* Country and Currency */}
|
|
88
|
+
<Box
|
|
89
|
+
style={{
|
|
90
|
+
display: "grid",
|
|
91
|
+
gridTemplateColumns: "repeat(2, 1fr)",
|
|
92
|
+
gap: "16px",
|
|
93
|
+
width: "100%",
|
|
94
|
+
}}
|
|
95
|
+
>
|
|
96
|
+
<Box>
|
|
97
|
+
<RenderInput
|
|
98
|
+
name="countryCode"
|
|
99
|
+
label={t("applePayConfig.countryCode", "Country Code")}
|
|
100
|
+
value={countryCode || ""}
|
|
101
|
+
onChange={(e) => {
|
|
102
|
+
const value = e.target?.value || e;
|
|
103
|
+
handleCountryChange(value);
|
|
104
|
+
}}
|
|
105
|
+
inputType="select"
|
|
106
|
+
required
|
|
107
|
+
tooltipContent={t("applePayConfig.countryTooltip", "Select the country where your business operates")}
|
|
108
|
+
options={APPLE_PAY_SUPPORTED_COUNTRIES.map((country) => ({
|
|
109
|
+
value: country.code,
|
|
110
|
+
label: `${country.name} (${country.code})`,
|
|
111
|
+
}))}
|
|
112
|
+
/>
|
|
113
|
+
</Box>
|
|
114
|
+
|
|
115
|
+
<Box>
|
|
116
|
+
<RenderInput
|
|
117
|
+
name="currencyCode"
|
|
118
|
+
label={t("applePayConfig.currencyCode", "Currency Code")}
|
|
119
|
+
value={currencyCode || ""}
|
|
120
|
+
onChange={(e) => {
|
|
121
|
+
const value = e.target?.value || e;
|
|
122
|
+
handleCurrencyChange(value);
|
|
123
|
+
}}
|
|
124
|
+
inputType="select"
|
|
125
|
+
required
|
|
126
|
+
tooltipContent={t("applePayConfig.currencyTooltip", "Supported currencies for {{country}}", { country: countryCode })}
|
|
127
|
+
options={supportedCurrencies.map((currency) => ({
|
|
128
|
+
value: currency.code,
|
|
129
|
+
label: `${currency.name} (${currency.code}) ${currency.symbol}`,
|
|
130
|
+
}))}
|
|
131
|
+
/>
|
|
132
|
+
{supportedCurrencies.length === 0 && (
|
|
133
|
+
<Typography
|
|
134
|
+
variant="pi"
|
|
135
|
+
textColor="danger600"
|
|
136
|
+
style={{ marginTop: "4px" }}
|
|
137
|
+
>
|
|
138
|
+
{t("applePayConfig.noCurrencies", "No supported currencies for this country. Please select a different country.")}
|
|
139
|
+
</Typography>
|
|
140
|
+
)}
|
|
141
|
+
</Box>
|
|
142
|
+
<Box>
|
|
143
|
+
<RenderInput
|
|
144
|
+
name="buttonStyle"
|
|
145
|
+
label={t("applePayConfig.buttonStyle", "Button Style")}
|
|
146
|
+
value={buttonStyle || ""}
|
|
147
|
+
onChange={(e) => {
|
|
148
|
+
const value = e.target?.value || e;
|
|
149
|
+
onConfigChange({ ...config, buttonStyle: value });
|
|
150
|
+
}}
|
|
151
|
+
inputType="select"
|
|
152
|
+
tooltipContent={t("applePayConfig.buttonStyleTooltip", "Visual style of the Apple Pay button")}
|
|
153
|
+
options={APPLE_PAY_BUTTON_STYLES.map((style) => ({
|
|
154
|
+
value: style.code,
|
|
155
|
+
label: style.name,
|
|
156
|
+
}))}
|
|
157
|
+
/>
|
|
158
|
+
</Box>
|
|
159
|
+
|
|
160
|
+
<Box>
|
|
161
|
+
<RenderInput
|
|
162
|
+
name="buttonType"
|
|
163
|
+
label={t("applePayConfig.buttonType", "Button Type")}
|
|
164
|
+
value={buttonType || ""}
|
|
165
|
+
onChange={(e) => {
|
|
166
|
+
const value = e.target?.value || e;
|
|
167
|
+
onConfigChange({ ...config, buttonType: value });
|
|
168
|
+
}}
|
|
169
|
+
inputType="select"
|
|
170
|
+
tooltipContent={t("applePayConfig.buttonTypeTooltip", "Type of action the button represents")}
|
|
171
|
+
options={APPLE_PAY_BUTTON_TYPES.map((type) => ({
|
|
172
|
+
value: type.code,
|
|
173
|
+
label: type.name,
|
|
174
|
+
}))}
|
|
175
|
+
/>
|
|
176
|
+
</Box>
|
|
177
|
+
</Box>
|
|
178
|
+
|
|
179
|
+
<Divider />
|
|
180
|
+
{/* Supported Networks */}
|
|
181
|
+
<Box>
|
|
182
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
|
183
|
+
<Typography variant="pi" fontWeight="semiBold">
|
|
184
|
+
{t("applePayConfig.supportedNetworks", "Supported Networks")}
|
|
185
|
+
</Typography>
|
|
186
|
+
<Typography variant="pi" textColor="neutral600">
|
|
187
|
+
{t("applePayConfig.supportedNetworksHint", "Select payment networks supported in {{country}}", { country: countryCode })}
|
|
188
|
+
</Typography>
|
|
189
|
+
</div>
|
|
190
|
+
<Flex wrap="wrap" gap={4} style={{ marginTop: "12px" }}>
|
|
191
|
+
{APPLE_PAY_SUPPORTED_NETWORKS.map((network) => {
|
|
192
|
+
const isSupported = supportedNetworksForCountry.includes(
|
|
193
|
+
network.code
|
|
194
|
+
);
|
|
195
|
+
const isSelected = supportedNetworks?.includes(network.code);
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<Box
|
|
199
|
+
key={network.code}
|
|
200
|
+
style={{ flex: "0 0 calc(50% - 8px)", minWidth: "250px" }}
|
|
201
|
+
>
|
|
202
|
+
<Checkbox
|
|
203
|
+
name={`network-${network.code}`}
|
|
204
|
+
checked={isSelected}
|
|
205
|
+
onCheckedChange={() => handleNetworkToggle(network.code)}
|
|
206
|
+
disabled={!isSupported}
|
|
207
|
+
>
|
|
208
|
+
{network.name} ({network.code})
|
|
209
|
+
{!isSupported && (
|
|
210
|
+
<Typography
|
|
211
|
+
variant="sigma"
|
|
212
|
+
textColor="neutral500"
|
|
213
|
+
style={{ marginLeft: "8px" }}
|
|
214
|
+
>
|
|
215
|
+
{t("applePayConfig.notAvailable", "(Not available)")}
|
|
216
|
+
</Typography>
|
|
217
|
+
)}
|
|
218
|
+
</Checkbox>
|
|
219
|
+
</Box>
|
|
220
|
+
);
|
|
221
|
+
})}
|
|
222
|
+
</Flex>
|
|
223
|
+
{supportedNetworks?.length === 0 && (
|
|
224
|
+
<Typography
|
|
225
|
+
variant="pi"
|
|
226
|
+
textColor="danger600"
|
|
227
|
+
style={{ marginTop: "8px" }}
|
|
228
|
+
>
|
|
229
|
+
{t("applePayConfig.atLeastOneNetwork", "At least one network must be selected")}
|
|
230
|
+
</Typography>
|
|
231
|
+
)}
|
|
232
|
+
</Box>
|
|
233
|
+
|
|
234
|
+
<Divider />
|
|
235
|
+
|
|
236
|
+
{/* Merchant Capabilities */}
|
|
237
|
+
<Box>
|
|
238
|
+
<div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
|
|
239
|
+
<Typography
|
|
240
|
+
variant="pi"
|
|
241
|
+
fontWeight="semiBold"
|
|
242
|
+
style={{ marginLeft: "2px" }}
|
|
243
|
+
>
|
|
244
|
+
{t("applePayConfig.merchantCapabilities", "Merchant Capabilities")}
|
|
245
|
+
</Typography>
|
|
246
|
+
<Typography
|
|
247
|
+
variant="pi"
|
|
248
|
+
textColor="neutral600"
|
|
249
|
+
style={{ marginLeft: "2px" }}
|
|
250
|
+
>
|
|
251
|
+
{t("applePayConfig.merchantCapabilitiesHint", "Select payment capabilities. \"3D Secure\" is required for most payment methods.")}
|
|
252
|
+
</Typography>
|
|
253
|
+
</div>
|
|
254
|
+
<Flex wrap="wrap" gap={4} style={{ marginTop: "12px" }}>
|
|
255
|
+
{APPLE_PAY_MERCHANT_CAPABILITIES.map((capability) => {
|
|
256
|
+
const isSelected = merchantCapabilities?.includes(
|
|
257
|
+
capability.code
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
return (
|
|
261
|
+
<Box
|
|
262
|
+
key={capability.code}
|
|
263
|
+
style={{ flex: "0 0 calc(50% - 8px)", minWidth: "250px" }}
|
|
264
|
+
>
|
|
265
|
+
<Checkbox
|
|
266
|
+
name={`capability-${capability.code}`}
|
|
267
|
+
checked={isSelected}
|
|
268
|
+
onCheckedChange={() =>
|
|
269
|
+
handleCapabilityToggle(capability.code)
|
|
270
|
+
}
|
|
271
|
+
>
|
|
272
|
+
{capability.name} - {capability.description}
|
|
273
|
+
</Checkbox>
|
|
274
|
+
</Box>
|
|
275
|
+
);
|
|
276
|
+
})}
|
|
277
|
+
</Flex>
|
|
278
|
+
{merchantCapabilities?.length === 0 && (
|
|
279
|
+
<Typography
|
|
280
|
+
variant="pi"
|
|
281
|
+
textColor="danger600"
|
|
282
|
+
style={{ marginTop: "8px" }}
|
|
283
|
+
>
|
|
284
|
+
{t("applePayConfig.atLeastOneCapability", "At least one capability must be selected. \"supports3DS\" is recommended.")}
|
|
285
|
+
</Typography>
|
|
286
|
+
)}
|
|
287
|
+
</Box>
|
|
288
|
+
|
|
289
|
+
<Divider />
|
|
290
|
+
|
|
291
|
+
{/* Domain Verification File Alert */}
|
|
292
|
+
<Flex
|
|
293
|
+
direction="column"
|
|
294
|
+
padding={3}
|
|
295
|
+
background="warning100"
|
|
296
|
+
borderRadius="4px"
|
|
297
|
+
borderColor="warning200"
|
|
298
|
+
borderWidth="1px"
|
|
299
|
+
borderStyle="solid"
|
|
300
|
+
alignItems="stretch"
|
|
301
|
+
gap={4}
|
|
302
|
+
>
|
|
303
|
+
<Typography variant="pi" fontWeight="bold" textColor="warning700">
|
|
304
|
+
⚠️ {t("applePayConfig.domainVerificationTitle", "Domain Verification File Required")}
|
|
305
|
+
</Typography>
|
|
306
|
+
<Typography variant="pi" textColor="neutral700">
|
|
307
|
+
<strong>{t("applePayConfig.domainVerificationDesc", "Download the Apple Pay domain verification file")}</strong>{" "}
|
|
308
|
+
{t("applePayConfig.domainVerificationDescSuffix", "from your Payone documentation:")}
|
|
309
|
+
</Typography>
|
|
310
|
+
<Box padding={2} background="neutral0" borderRadius="4px">
|
|
311
|
+
<Typography variant="pi" style={{ fontSize: "12px" }}>
|
|
312
|
+
<strong>{t("applePayConfig.downloadUrl", "Download URL:")}</strong>{" "}
|
|
313
|
+
<a
|
|
314
|
+
href="https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev"
|
|
315
|
+
target="_blank"
|
|
316
|
+
rel="noopener noreferrer"
|
|
317
|
+
style={{ color: "#0066ff", textDecoration: "underline" }}
|
|
318
|
+
>
|
|
319
|
+
https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev
|
|
320
|
+
</a>
|
|
321
|
+
</Typography>
|
|
322
|
+
</Box>
|
|
323
|
+
<Typography variant="pi" textColor="neutral700">
|
|
324
|
+
<strong>{t("applePayConfig.placeFileAt", "Place the file at:")}</strong>
|
|
325
|
+
</Typography>
|
|
326
|
+
<Box padding={2} background="neutral0" borderRadius="4px">
|
|
327
|
+
<Typography
|
|
328
|
+
variant="pi"
|
|
329
|
+
style={{ fontFamily: "monospace", fontSize: "12px" }}
|
|
330
|
+
>
|
|
331
|
+
<strong>Strapi:</strong>{" "}
|
|
332
|
+
<code>
|
|
333
|
+
public/.well-known/apple-developer-merchantid-domain-association
|
|
334
|
+
</code>
|
|
335
|
+
<br />
|
|
336
|
+
<strong>Frontend:</strong>{" "}
|
|
337
|
+
<code>
|
|
338
|
+
public/.well-known/apple-developer-merchantid-domain-association
|
|
339
|
+
</code>
|
|
340
|
+
</Typography>
|
|
341
|
+
</Box>
|
|
342
|
+
<Typography variant="pi" textColor="neutral700" marginTop={2}>
|
|
343
|
+
{t("applePayConfig.fileMustBeAccessible", "The file must be accessible at:")}{" "}
|
|
344
|
+
<code>
|
|
345
|
+
https://yourdomain.com/.well-known/apple-developer-merchantid-domain-association
|
|
346
|
+
</code>
|
|
347
|
+
</Typography>
|
|
348
|
+
<Typography variant="pi" fontWeight="bold" textColor="danger600">
|
|
349
|
+
{t("applePayConfig.withoutFileWarning", "Without this file, Apple Pay will NOT work on your domain!")}
|
|
350
|
+
</Typography>
|
|
351
|
+
</Flex>
|
|
352
|
+
</Flex>
|
|
353
|
+
</Box>
|
|
354
|
+
);
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
export default ApplePayConfig;
|