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.
- package/admin/src/index.js +2 -0
- package/admin/src/pages/App/components/ApplePayBtn.jsx +15 -13
- package/admin/src/pages/App/components/PaymentActionsPanel.jsx +68 -17
- package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +4 -12
- package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.jsx +163 -86
- package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +21 -11
- package/admin/src/pages/App/index.jsx +15 -7
- package/admin/src/pages/hooks/usePaymentActions.js +0 -172
- package/admin/src/pages/utils/injectApplePayScript.js +34 -0
- package/admin/src/pages/utils/paymentUtils.js +2 -2
- package/package.json +2 -1
- package/server/bootstrap.js +0 -19
- package/server/services/transactionService.js +0 -28
- package/admin/src/components/Initializer/index.js +0 -16
- package/admin/src/components/PluginIcon/index.js +0 -6
- package/admin/src/pages/App/components/AppHeader.js +0 -55
- package/admin/src/pages/App/components/AppTabs.js +0 -158
- package/admin/src/pages/App/components/ApplePayButton.js +0 -950
- package/admin/src/pages/App/components/ApplePayButton.jsx +0 -908
- package/admin/src/pages/App/components/ApplePayConfig.js +0 -364
- package/admin/src/pages/App/components/ApplePayConfigPanel.js +0 -81
- package/admin/src/pages/App/components/ConfigurationPanel.js +0 -280
- package/admin/src/pages/App/components/DocsPanel.js +0 -1057
- package/admin/src/pages/App/components/GooglePayConfig.js +0 -217
- package/admin/src/pages/App/components/GooglePayConfigPanel.js +0 -82
- package/admin/src/pages/App/components/GooglePaybutton.js +0 -300
- package/admin/src/pages/App/components/HistoryPanel.js +0 -285
- package/admin/src/pages/App/components/PaymentActionsPanel.js +0 -190
- package/admin/src/pages/App/components/StatusBadge.js +0 -24
- package/admin/src/pages/App/components/TransactionHistoryItem.js +0 -377
- package/admin/src/pages/App/components/icons/BankIcon.js +0 -10
- package/admin/src/pages/App/components/icons/ChevronDownIcon.js +0 -9
- package/admin/src/pages/App/components/icons/ChevronUpIcon.js +0 -9
- package/admin/src/pages/App/components/icons/CreditCardIcon.js +0 -9
- package/admin/src/pages/App/components/icons/ErrorIcon.js +0 -10
- package/admin/src/pages/App/components/icons/InfoIcon.js +0 -9
- package/admin/src/pages/App/components/icons/PaymentIcon.js +0 -10
- package/admin/src/pages/App/components/icons/PendingIcon.js +0 -9
- package/admin/src/pages/App/components/icons/PersonIcon.js +0 -9
- package/admin/src/pages/App/components/icons/SuccessIcon.js +0 -9
- package/admin/src/pages/App/components/icons/WalletIcon.js +0 -9
- package/admin/src/pages/App/components/icons/index.js +0 -11
- package/admin/src/pages/App/components/paymentActions/AuthorizationForm.js +0 -195
- package/admin/src/pages/App/components/paymentActions/CaptureForm.js +0 -65
- package/admin/src/pages/App/components/paymentActions/CardDetailsInput.js +0 -191
- package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.js +0 -156
- package/admin/src/pages/App/components/paymentActions/PaymentResult.js +0 -148
- package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.js +0 -199
- package/admin/src/pages/App/components/paymentActions/RefundForm.js +0 -90
- 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;
|