strapi-plugin-payone-provider 1.6.1 → 1.6.3

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 (50) hide show
  1. package/admin/src/index.js +2 -0
  2. package/admin/src/pages/App/components/ApplePayBtn.jsx +15 -13
  3. package/admin/src/pages/App/components/PaymentActionsPanel.jsx +68 -17
  4. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +4 -12
  5. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.jsx +163 -86
  6. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +21 -11
  7. package/admin/src/pages/App/index.jsx +15 -7
  8. package/admin/src/pages/hooks/usePaymentActions.js +0 -172
  9. package/admin/src/pages/utils/injectApplePayScript.js +34 -0
  10. package/admin/src/pages/utils/paymentUtils.js +2 -2
  11. package/package.json +2 -1
  12. package/server/bootstrap.js +0 -19
  13. package/server/services/transactionService.js +0 -28
  14. package/admin/src/components/Initializer/index.js +0 -16
  15. package/admin/src/components/PluginIcon/index.js +0 -6
  16. package/admin/src/pages/App/components/AppHeader.js +0 -55
  17. package/admin/src/pages/App/components/AppTabs.js +0 -158
  18. package/admin/src/pages/App/components/ApplePayButton.js +0 -950
  19. package/admin/src/pages/App/components/ApplePayButton.jsx +0 -908
  20. package/admin/src/pages/App/components/ApplePayConfig.js +0 -364
  21. package/admin/src/pages/App/components/ApplePayConfigPanel.js +0 -81
  22. package/admin/src/pages/App/components/ConfigurationPanel.js +0 -280
  23. package/admin/src/pages/App/components/DocsPanel.js +0 -1057
  24. package/admin/src/pages/App/components/GooglePayConfig.js +0 -217
  25. package/admin/src/pages/App/components/GooglePayConfigPanel.js +0 -82
  26. package/admin/src/pages/App/components/GooglePaybutton.js +0 -300
  27. package/admin/src/pages/App/components/HistoryPanel.js +0 -285
  28. package/admin/src/pages/App/components/PaymentActionsPanel.js +0 -190
  29. package/admin/src/pages/App/components/StatusBadge.js +0 -24
  30. package/admin/src/pages/App/components/TransactionHistoryItem.js +0 -377
  31. package/admin/src/pages/App/components/icons/BankIcon.js +0 -10
  32. package/admin/src/pages/App/components/icons/ChevronDownIcon.js +0 -9
  33. package/admin/src/pages/App/components/icons/ChevronUpIcon.js +0 -9
  34. package/admin/src/pages/App/components/icons/CreditCardIcon.js +0 -9
  35. package/admin/src/pages/App/components/icons/ErrorIcon.js +0 -10
  36. package/admin/src/pages/App/components/icons/InfoIcon.js +0 -9
  37. package/admin/src/pages/App/components/icons/PaymentIcon.js +0 -10
  38. package/admin/src/pages/App/components/icons/PendingIcon.js +0 -9
  39. package/admin/src/pages/App/components/icons/PersonIcon.js +0 -9
  40. package/admin/src/pages/App/components/icons/SuccessIcon.js +0 -9
  41. package/admin/src/pages/App/components/icons/WalletIcon.js +0 -9
  42. package/admin/src/pages/App/components/icons/index.js +0 -11
  43. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.js +0 -195
  44. package/admin/src/pages/App/components/paymentActions/CaptureForm.js +0 -65
  45. package/admin/src/pages/App/components/paymentActions/CardDetailsInput.js +0 -191
  46. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.js +0 -156
  47. package/admin/src/pages/App/components/paymentActions/PaymentResult.js +0 -148
  48. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.js +0 -199
  49. package/admin/src/pages/App/components/paymentActions/RefundForm.js +0 -90
  50. package/admin/src/pages/App/index.js +0 -127
@@ -1,195 +0,0 @@
1
- import React from "react";
2
- import { Box, Flex, Typography, TextInput, Button } from "@strapi/design-system";
3
- import { Play } from "@strapi/icons";
4
- import GooglePayButton from "../GooglePaybutton";
5
- import ApplePayButton from "../ApplePayButton";
6
- import CardDetailsInput from "./CardDetailsInput";
7
-
8
- const AuthorizationForm = ({
9
- paymentAmount,
10
- setPaymentAmount,
11
- authReference,
12
- setAuthReference,
13
- isProcessingPayment,
14
- onAuthorization,
15
- paymentMethod,
16
- settings,
17
- googlePayToken,
18
- setGooglePayToken,
19
- applePayToken,
20
- setApplePayToken,
21
- cardtype,
22
- setCardtype,
23
- cardpan,
24
- setCardpan,
25
- cardexpiredate,
26
- setCardexpiredate,
27
- cardcvc2,
28
- setCardcvc2,
29
- isLiveMode = false
30
- }) => {
31
- const handleGooglePayToken = (token, paymentData) => {
32
- if (!token) {
33
- return;
34
- }
35
- setGooglePayToken(token);
36
- onAuthorization(token);
37
- };
38
-
39
- const handleGooglePayError = (error) => {
40
- if (onError) {
41
- onError(error);
42
- }
43
- };
44
-
45
- const handleApplePayToken = async (token, paymentData) => {
46
- if (!token) {
47
- console.error("[Apple Pay] Token is missing in handleApplePayToken");
48
- return Promise.reject(new Error("Token is missing"));
49
- }
50
-
51
- console.log("[Apple Pay] handleApplePayToken called with token:", {
52
- hasToken: !!token,
53
- tokenLength: token?.length,
54
- paymentData: !!paymentData
55
- });
56
-
57
- // IMPORTANT: Set token in state immediately (synchronously)
58
- // This ensures the token is saved before the dialog closes
59
- setApplePayToken(token);
60
-
61
- console.log("[Apple Pay] Token saved to state successfully");
62
-
63
- // Don't call onAuthorization immediately
64
- // Let the user manually trigger the payment using the button
65
- // This prevents the dialog from closing prematurely if there's an error
66
- // The dialog will close with success, and the user will see the "Process Authorization" button
67
-
68
- // Return success immediately so the dialog closes properly
69
- // The actual payment processing will happen when the user clicks the button
70
- return Promise.resolve({
71
- success: true,
72
- message: "Token received successfully. Please click 'Process Authorization' to complete the payment."
73
- });
74
- };
75
-
76
- const handleApplePayError = (error) => {
77
- if (onError) {
78
- onError(error);
79
- }
80
- };
81
-
82
-
83
- return (
84
- <Flex direction="column" alignItems="stretch" gap={4}>
85
- <Flex direction="row" gap={2}>
86
- <Typography variant="omega" fontWeight="semiBold" textColor="neutral800" className="payment-form-title">
87
- Authorization
88
- </Typography>
89
- <Typography variant="pi" textColor="neutral600" className="payment-form-description">
90
- Authorize and capture an amount immediately.
91
- </Typography>
92
- </Flex>
93
-
94
- <Flex gap={4} wrap="wrap">
95
- <TextInput
96
- label="Amount (in cents) *"
97
- name="authAmount"
98
- value={paymentAmount}
99
- onChange={(e) => setPaymentAmount(e.target.value)}
100
- placeholder="Enter amount (e.g., 1000 for €10.00)"
101
- hint="Amount in cents (e.g., 1000 = €10.00)"
102
- required
103
- className="payment-input"
104
- style={{ flex: 1, minWidth: "250px" }}
105
- />
106
-
107
- <TextInput
108
- label="Reference *"
109
- name="authReference"
110
- value={authReference}
111
- onChange={(e) => setAuthReference(e.target.value)}
112
- placeholder="Auto-generated if empty"
113
- hint="Reference will be auto-generated if left empty"
114
- className="payment-input"
115
- style={{ flex: 1, minWidth: "250px" }}
116
- />
117
- </Flex>
118
-
119
- {paymentMethod === "cc" && settings?.enable3DSecure && (
120
- <Box marginTop={4}>
121
- <CardDetailsInput
122
- cardtype={cardtype}
123
- setCardtype={setCardtype}
124
- cardpan={cardpan}
125
- setCardpan={setCardpan}
126
- cardexpiredate={cardexpiredate}
127
- setCardexpiredate={setCardexpiredate}
128
- cardcvc2={cardcvc2}
129
- setCardcvc2={setCardcvc2}
130
- />
131
- </Box>
132
- )}
133
-
134
- {paymentMethod === "gpp" ? (
135
- <GooglePayButton
136
- amount={paymentAmount}
137
- currency="EUR"
138
- onTokenReceived={handleGooglePayToken}
139
- onError={handleGooglePayError}
140
- settings={settings}
141
- />
142
- ) : paymentMethod === "apl" ? (
143
- <Box>
144
- <ApplePayButton
145
- amount={paymentAmount}
146
- currency="EUR"
147
- onTokenReceived={handleApplePayToken}
148
- onError={handleApplePayError}
149
- settings={settings}
150
- />
151
- {applePayToken && (
152
- <Box marginTop={3} style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "flex-start", gap: "8px" }}>
153
- <Typography variant="pi" textColor="success600" style={{ marginBottom: "8px", fontWeight: "bold" }}>
154
- ✓ Apple Pay token received. You can now process the authorization:
155
- </Typography>
156
- <Button
157
- variant="default"
158
- onClick={() => onAuthorization(applePayToken)}
159
- loading={isProcessingPayment}
160
- startIcon={<Play />}
161
- style={{ maxWidth: '200px' }}
162
- disabled={!paymentAmount.trim() || !authReference.trim() || isLiveMode}
163
- className="payment-button payment-button-primary"
164
- >
165
- Process Authorization
166
- </Button>
167
- </Box>
168
- )}
169
- </Box>
170
- ) : (
171
- <Button
172
- variant="default"
173
- onClick={onAuthorization}
174
- loading={isProcessingPayment}
175
- startIcon={<Play />}
176
- style={{ maxWidth: '200px' }}
177
- className="payment-button payment-button-primary"
178
- disabled={
179
- !paymentAmount.trim() ||
180
- (paymentMethod === "cc" &&
181
- settings?.enable3DSecure !== false &&
182
- (!cardtype || !cardpan || !cardexpiredate || !cardcvc2)) ||
183
- (paymentMethod === "apl" && !applePayToken) ||
184
- isLiveMode
185
- }
186
- >
187
- Process Authorization
188
- </Button>
189
- )}
190
- </Flex>
191
- );
192
- };
193
-
194
- export default AuthorizationForm;
195
-
@@ -1,65 +0,0 @@
1
- import React from "react";
2
- import { Box, Flex, Typography, TextInput, Button } from "@strapi/design-system";
3
- import { Play } from "@strapi/icons";
4
-
5
- const CaptureForm = ({
6
- paymentAmount,
7
- setPaymentAmount,
8
- captureTxid,
9
- setCaptureTxid,
10
- isProcessingPayment,
11
- onCapture
12
- }) => {
13
- return (
14
- <Flex direction="column" alignItems="stretch" gap={4}>
15
- <Flex direction="row" gap={2}>
16
- <Typography variant="omega" fontWeight="semiBold" textColor="neutral800" className="payment-form-title">
17
- Capture
18
- </Typography>
19
- <Typography variant="pi" textColor="neutral600" className="payment-form-description">
20
- Capture a previously authorized amount. Note: Reference parameter is
21
- not supported by Payone capture.
22
- </Typography>
23
- </Flex>
24
-
25
- <Flex gap={4} wrap="wrap">
26
- <TextInput
27
- label="Transaction ID"
28
- name="captureTxid"
29
- value={captureTxid}
30
- onChange={(e) => setCaptureTxid(e.target.value)}
31
- placeholder="Enter TxId from preauthorization"
32
- hint="Transaction ID from a previous preauthorization"
33
- className="payment-input"
34
- style={{ flex: 1, minWidth: "250px" }}
35
- />
36
-
37
- <TextInput
38
- label="Amount (in cents)"
39
- name="captureAmount"
40
- value={paymentAmount}
41
- onChange={(e) => setPaymentAmount(e.target.value)}
42
- placeholder="1000"
43
- hint="Amount in cents to capture"
44
- className="payment-input"
45
- style={{ flex: 1, minWidth: "250px" }}
46
- />
47
- </Flex>
48
-
49
- <Button
50
- variant="default"
51
- onClick={onCapture}
52
- loading={isProcessingPayment}
53
- startIcon={<Play />}
54
- style={{ maxWidth: '200px' }}
55
- className="payment-button payment-button-primary"
56
- disabled={!captureTxid.trim() || !paymentAmount.trim()}
57
- >
58
- Process Capture
59
- </Button>
60
- </Flex>
61
- );
62
- };
63
-
64
- export default CaptureForm;
65
-
@@ -1,191 +0,0 @@
1
- import React, { useEffect, useRef } from "react";
2
- import {
3
- Box,
4
- Flex,
5
- Typography,
6
- TextInput,
7
- Select,
8
- Option,
9
- Link
10
- } from "@strapi/design-system";
11
-
12
- // 3DS Test Cards that require redirect (challenge workflow)
13
- const TEST_3DS_CARDS = [
14
- {
15
- name: "VISA - 3DS 2.0 (Challenge)",
16
- cardtype: "V",
17
- cardpan: "4716971940353559",
18
- cardexpiredate: "2512",
19
- cardcvc2: "123",
20
- description: "3DS 2.0 with challenge - Password: 12345"
21
- },
22
- {
23
- name: "Mastercard - 3DS 2.0 (Challenge)",
24
- cardtype: "M",
25
- cardpan: "5404127720739582",
26
- cardexpiredate: "2512",
27
- cardcvc2: "123",
28
- description: "3DS 2.0 with challenge - Password: 12345"
29
- },
30
- // {
31
- // name: "AMEX - 3DS 2.0 (Challenge)",
32
- // cardtype: "A",
33
- // cardpan: "375144726036141",
34
- // cardexpiredate: "2512",
35
- // cardcvc2: "1234",
36
- // description: "3DS 2.0 with challenge - Password: 12345"
37
- // }
38
- ];
39
-
40
- const CardDetailsInput = ({
41
- cardtype,
42
- setCardtype,
43
- cardpan,
44
- setCardpan,
45
- cardexpiredate,
46
- setCardexpiredate,
47
- cardcvc2,
48
- setCardcvc2
49
- }) => {
50
- const [selectedTestCard, setSelectedTestCard] = React.useState("");
51
- const isUpdatingFromTestCard = useRef(false);
52
-
53
- useEffect(() => {
54
- if (isUpdatingFromTestCard.current) {
55
- isUpdatingFromTestCard.current = false;
56
- return;
57
- }
58
-
59
- const matchingCard = TEST_3DS_CARDS.find(
60
- card => card.cardtype === cardtype && card.cardpan === cardpan
61
- );
62
-
63
- if (matchingCard) {
64
- const testCardValue = `${matchingCard.cardtype}-${matchingCard.cardpan}`;
65
- if (selectedTestCard !== testCardValue) {
66
- setSelectedTestCard(testCardValue);
67
- }
68
- } else if (selectedTestCard) {
69
- setSelectedTestCard("");
70
- }
71
- }, [cardtype, cardpan, selectedTestCard]);
72
-
73
- const handleTestCardSelect = (value) => {
74
- if (!value || value === "") {
75
- setSelectedTestCard("");
76
- return;
77
- }
78
-
79
- const selectedCard = TEST_3DS_CARDS.find(card =>
80
- `${card.cardtype}-${card.cardpan}` === value
81
- );
82
-
83
- if (selectedCard) {
84
- isUpdatingFromTestCard.current = true;
85
-
86
- setCardtype(selectedCard.cardtype);
87
- setCardpan(selectedCard.cardpan);
88
- setCardexpiredate(selectedCard.cardexpiredate);
89
- setCardcvc2(selectedCard.cardcvc2);
90
- setSelectedTestCard(value);
91
- }
92
- };
93
-
94
- return (
95
- <Box>
96
- <Flex direction="column" alignItems="stretch" gap={4}>
97
- <Flex direction="row" gap={2} alignItems="flex-start">
98
- <Select
99
- label="3D Secure Test Cards"
100
- name="testCard"
101
- value={selectedTestCard}
102
- placeholder="Select a 3DS test card to auto-fill"
103
- hint="These cards will trigger 3DS authentication redirect. Password: 12345"
104
- onChange={handleTestCardSelect}
105
- className="payment-input"
106
- >
107
- <Option value="">-- Select a test card --</Option>
108
- {TEST_3DS_CARDS.map((card, index) => (
109
- <Option key={index} value={`${card.cardtype}-${card.cardpan}`}>
110
- {card.name} - {card.description}
111
- </Option>
112
- ))}
113
- </Select>
114
- </Flex>
115
-
116
- <Flex gap={4} wrap="wrap" alignItems="flex-start">
117
- <Select
118
- label="Card Type *"
119
- name="cardtype"
120
- value={cardtype || ""}
121
- onChange={(value) => setCardtype(value)}
122
- required
123
- hint="Select credit card type"
124
- className="payment-input"
125
- style={{ flex: 1, minWidth: "200px" }}
126
- >
127
- <Option value="V">VISA</Option>
128
- <Option value="M">Mastercard</Option>
129
- <Option value="A">American Express</Option>
130
- <Option value="J">JCB</Option>
131
- <Option value="O">Maestro International</Option>
132
- <Option value="D">Diners Club</Option>
133
- </Select>
134
-
135
- <TextInput
136
- label="Card Number (PAN) *"
137
- name="cardpan"
138
- value={cardpan || ""}
139
- onChange={(e) => setCardpan(e.target.value)}
140
- placeholder="Enter card number"
141
- hint="Credit card number (PAN)"
142
- required
143
- className="payment-input"
144
- style={{ flex: 2, minWidth: "300px" }}
145
- />
146
- </Flex>
147
-
148
- <Flex gap={4} wrap="wrap" alignItems="flex-start">
149
- <TextInput
150
- label="Expiry Date *"
151
- name="cardexpiredate"
152
- value={cardexpiredate || ""}
153
- onChange={(e) => setCardexpiredate(e.target.value)}
154
- placeholder="YYMM (e.g., 2512)"
155
- hint="Format: YYMM (e.g., 2512 = December 2025)"
156
- required
157
- maxLength={4}
158
- className="payment-input"
159
- style={{ flex: 1, minWidth: "150px" }}
160
- />
161
-
162
- <TextInput
163
- label="CVC/CVV *"
164
- name="cardcvc2"
165
- value={cardcvc2 || ""}
166
- onChange={(e) => setCardcvc2(e.target.value)}
167
- placeholder="123 or 1234"
168
- hint={cardtype === "A" ? "4 digits for AMEX" : "3 digits for other cards"}
169
- required
170
- maxLength={4}
171
- className="payment-input"
172
- style={{ flex: 1, minWidth: "150px" }}
173
- />
174
- </Flex>
175
-
176
- <Box paddingTop={2}>
177
- <Typography variant="pi" textColor="neutral600" style={{ textAlign: "left" }}>
178
- For all test card numbers (positive, negative, frictionless 3DS), 3D Secure test data, and detailed documentation, please refer to the{" "}
179
- <Link href="https://docs.payone.com/security-risk-management/3d-secure#/" target="_blank" rel="noopener noreferrer">
180
- Payone 3D Secure Documentation
181
- </Link>
182
- .
183
- </Typography>
184
- </Box>
185
- </Flex>
186
- </Box>
187
- );
188
- };
189
-
190
- export default CardDetailsInput;
191
-
@@ -1,156 +0,0 @@
1
- import React from "react";
2
- import { Box, Flex, Select, Option, Typography, Link, Alert } from "@strapi/design-system";
3
- import pluginId from "../../../../pluginId";
4
- import {
5
- getPaymentMethodOptions,
6
- supportsCaptureMode,
7
- getCaptureModeOptions,
8
- getPaymentMethodDisplayName
9
- } from "../../../utils/paymentUtils";
10
-
11
- const PaymentMethodSelector = ({
12
- paymentMethod,
13
- setPaymentMethod,
14
- captureMode,
15
- setCaptureMode,
16
- onNavigateToConfig
17
- }) => {
18
- return (
19
- <Box>
20
- <Flex direction="column" alignItems="stretch" gap={4}>
21
- <Select
22
- label="Select Payment Method"
23
- name="paymentMethod"
24
- value={paymentMethod}
25
- onChange={(value) => setPaymentMethod(value)}
26
- hint={`Current: ${getPaymentMethodDisplayName(paymentMethod)}`}
27
- >
28
- {getPaymentMethodOptions().map((option) => (
29
- <Option key={option.value} value={option.value}>
30
- {option.label}
31
- </Option>
32
- ))}
33
- </Select>
34
- {paymentMethod === "apl" && onNavigateToConfig && (
35
- <>
36
- <Alert closeLabel="Close" title="⚠️ Important: Middleware Configuration Required" variant="warning">
37
- <Typography variant="pi" marginTop={2}>
38
- <strong>Apple Pay requires middleware configuration</strong> to work properly. You must configure Content Security Policy (CSP) in <code>config/middlewares.js</code> to allow Apple Pay scripts, otherwise Apple Pay will NOT work.
39
- </Typography>
40
- <Typography variant="pi" marginTop={2}>
41
- Required CSP directives for Apple Pay:
42
- </Typography>
43
- <Box marginTop={2} padding={2} background="neutral100" borderRadius="4px">
44
- <Typography variant="pi" style={{ fontFamily: "monospace", fontSize: "12px" }}>
45
- 'script-src': ['https://applepay.cdn-apple.com', 'https://www.apple.com']<br/>
46
- 'connect-src': ['https://applepay.cdn-apple.com', 'https://www.apple.com']<br/>
47
- 'frame-src': ['https://applepay.cdn-apple.com']
48
- </Typography>
49
- </Box>
50
- <Typography variant="pi" marginTop={2} fontWeight="bold">
51
- ⚠️ Without this configuration, Apple Pay will NOT work!
52
- </Typography>
53
- </Alert>
54
- <Alert closeLabel="Close" title="📥 Apple Pay Domain Verification File Required" variant="default">
55
- <Typography variant="pi" marginTop={2}>
56
- <strong>Download the Apple Pay domain verification file</strong> from your Payone merchant portal and place it in:
57
- </Typography>
58
- <Box marginTop={2} padding={2} background="neutral100" borderRadius="4px">
59
- <Typography variant="pi" style={{ fontFamily: "monospace", fontSize: "12px" }}>
60
- <strong>Strapi:</strong> <code>public/.well-known/apple-developer-merchantid-domain-association</code><br/>
61
- <strong>Frontend:</strong> <code>public/.well-known/apple-developer-merchantid-domain-association</code>
62
- </Typography>
63
- </Box>
64
- <Typography variant="pi" marginTop={2}>
65
- <strong>Download URL:</strong> Download the domain verification file from Payone documentation:{" "}
66
- <Link
67
- href="https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev"
68
- target="_blank"
69
- rel="noopener noreferrer"
70
- style={{ color: "#0066ff", textDecoration: "underline" }}
71
- >
72
- https://docs.payone.com/payment-methods/apple-pay/apple-pay-without-dev
73
- </Link>
74
- </Typography>
75
- <Typography variant="pi" marginTop={2}>
76
- <strong>Alternative:</strong> Log into your Payone Merchant Interface (PMI) → Configuration → Payment Portals → Apple Pay → Download domain verification file
77
- </Typography>
78
- <Typography variant="pi" marginTop={2} fontWeight="bold" textColor="danger600">
79
- ⚠️ Without this file, Apple Pay will NOT work on your domain!
80
- </Typography>
81
- </Alert>
82
- <Box padding={3} background="neutral100" borderRadius="4px">
83
- <Typography variant="pi" textColor="neutral600">
84
- Configure Apple Pay settings:{" "}
85
- <Link
86
- href={`/plugins/${pluginId}/apple-pay-config`}
87
- onClick={(e) => {
88
- e.preventDefault();
89
- onNavigateToConfig("apple-pay");
90
- }}
91
- style={{ cursor: "pointer", textDecoration: "underline", color: "#0066ff" }}
92
- >
93
- /plugins/{pluginId}/apple-pay-config
94
- </Link>
95
- </Typography>
96
- </Box>
97
- </>
98
- )}
99
- {paymentMethod === "gpp" && onNavigateToConfig && (
100
- <>
101
- <Alert closeLabel="Close" title="⚠️ Important: Middleware Configuration Required" variant="warning">
102
- <Typography variant="pi" marginTop={2}>
103
- <strong>Google Pay requires middleware configuration</strong> to work properly. You must configure Content Security Policy (CSP) in <code>config/middlewares.js</code> to allow Google Pay scripts, otherwise Google Pay will NOT work.
104
- </Typography>
105
- <Typography variant="pi" marginTop={2}>
106
- Required CSP directives for Google Pay:
107
- </Typography>
108
- <Box marginTop={2} padding={2} background="neutral100" borderRadius="4px">
109
- <Typography variant="pi" style={{ fontFamily: "monospace", fontSize: "12px" }}>
110
- 'script-src': ['https://pay.google.com']<br/>
111
- 'connect-src': ['https://pay.google.com']<br/>
112
- 'frame-src': ['https://pay.google.com']
113
- </Typography>
114
- </Box>
115
- <Typography variant="pi" marginTop={2} fontWeight="bold">
116
- ⚠️ Without this configuration, Google Pay will NOT work!
117
- </Typography>
118
- </Alert>
119
- <Box padding={3} background="neutral100" borderRadius="4px">
120
- <Typography variant="pi" textColor="neutral600">
121
- Configure Google Pay settings:{" "}
122
- <Link
123
- href={`/plugins/${pluginId}/google-pay-config`}
124
- onClick={(e) => {
125
- e.preventDefault();
126
- onNavigateToConfig("google-pay");
127
- }}
128
- style={{ cursor: "pointer", textDecoration: "underline", color: "#0066ff" }}
129
- >
130
- /plugins/{pluginId}/google-pay-config
131
- </Link>
132
- </Typography>
133
- </Box>
134
- </>
135
- )}
136
- {supportsCaptureMode(paymentMethod) && (
137
- <Select
138
- label="Capture Mode"
139
- name="captureMode"
140
- value={captureMode}
141
- onChange={(value) => setCaptureMode(value)}
142
- hint="Select capture mode for wallet payments"
143
- >
144
- {getCaptureModeOptions().map((option) => (
145
- <Option key={option.value} value={option.value}>
146
- {option.label}
147
- </Option>
148
- ))}
149
- </Select>
150
- )}
151
- </Flex>
152
- </Box>
153
- );
154
- };
155
-
156
- export default PaymentMethodSelector;