strapi-plugin-payone-provider 4.6.10 → 4.6.12

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 (68) 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 +199 -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 +121 -85
  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 +2 -2
  42. package/server/bootstrap.js +6 -6
  43. package/server/content-types/index.js +5 -0
  44. package/server/content-types/transactions/index.js +5 -0
  45. package/server/content-types/transactions/schema.json +87 -0
  46. package/server/controllers/payone.js +29 -3
  47. package/server/index.js +2 -1
  48. package/server/policies/index.js +2 -1
  49. package/server/policies/is-payone-notification.js +31 -0
  50. package/server/routes/index.js +10 -0
  51. package/server/services/applePayService.js +0 -2
  52. package/server/services/payone.js +16 -4
  53. package/server/services/settingsService.js +8 -2
  54. package/server/services/testConnectionService.js +11 -72
  55. package/server/services/transactionService.js +147 -154
  56. package/server/services/transactionStatusService.js +63 -0
  57. package/server/utils/sanitize.js +41 -0
  58. package/admin/src/pages/App/components/ConfigurationPanel.jsx +0 -517
  59. package/admin/src/pages/App/components/CustomerInfoPopover.jsx +0 -147
  60. package/admin/src/pages/App/components/HistoryPanel.jsx +0 -94
  61. package/admin/src/pages/App/components/PaymentActionsPanel.jsx +0 -280
  62. package/admin/src/pages/App/components/RawDataPopover.jsx +0 -113
  63. package/admin/src/pages/App/components/TransactionHistoryItem.jsx +0 -522
  64. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTableFilters.jsx +0 -113
  65. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTablePagination.jsx +0 -180
  66. package/admin/src/pages/App/components/TransactionHistoryTable/index.jsx +0 -225
  67. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +0 -197
  68. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +0 -142
@@ -0,0 +1,157 @@
1
+ import { Box, Flex } from "@strapi/design-system";
2
+ import AuthorizationFormHeader from "./AuthorizationFormHeader";
3
+ import AuthorizationFormFields from "./AuthorizationFormFields";
4
+ import AuthorizationPaymentButtons from "./AuthorizationPaymentButtons";
5
+ import CardDetailsInput from "../CardDetailsInput";
6
+
7
+ const AuthorizationForm = ({
8
+ paymentAmount,
9
+ setPaymentAmount,
10
+ authReference,
11
+ setAuthReference,
12
+ isProcessingPayment,
13
+ onAuthorization,
14
+ paymentMethod,
15
+ settings,
16
+ setGooglePayToken,
17
+ applePayToken,
18
+ setApplePayToken,
19
+ cardtype,
20
+ setCardtype,
21
+ cardpan,
22
+ setCardpan,
23
+ cardexpiredate,
24
+ setCardexpiredate,
25
+ cardcvc2,
26
+ setCardcvc2,
27
+ firstname,
28
+ setFirstname,
29
+ lastname,
30
+ setLastname,
31
+ email,
32
+ setEmail,
33
+ telephonenumber,
34
+ setTelephonenumber,
35
+ gender,
36
+ setGender,
37
+ salutation,
38
+ setSalutation,
39
+ country,
40
+ setCountry,
41
+ currency,
42
+ setCurrency,
43
+ city,
44
+ setCity,
45
+ street,
46
+ setStreet,
47
+ zip,
48
+ setZip,
49
+ }) => {
50
+ const handleGooglePayToken = (token, paymentData) => {
51
+ if (!token) {
52
+ return;
53
+ }
54
+ setGooglePayToken(token);
55
+ onAuthorization(token);
56
+ };
57
+
58
+ const handleGooglePayError = (error) => {
59
+ console.error("[AuthorizationForm] Google Pay error:", error);
60
+ };
61
+
62
+ const handleApplePayToken = async (token, paymentData) => {
63
+ if (!token) {
64
+ return Promise.reject(new Error("Token is missing"));
65
+ }
66
+
67
+ setApplePayToken(token);
68
+
69
+ return Promise.resolve({
70
+ success: true,
71
+ message:
72
+ "Token received successfully. Please click 'Process Authorization' to complete the payment.",
73
+ });
74
+ };
75
+
76
+ const handleApplePayError = (error) => {
77
+ console.error("[AuthorizationForm] Apple Pay error:", error);
78
+ };
79
+
80
+ const isCardDetailsValid =
81
+ !!cardtype && !!cardpan && !!cardexpiredate && !!cardcvc2;
82
+
83
+ const isDisabled =
84
+ !paymentAmount.trim() ||
85
+ (paymentMethod === "cc" &&
86
+ settings?.enable3DSecure !== false &&
87
+ !isCardDetailsValid) ||
88
+ (paymentMethod === "apl" && !applePayToken);
89
+
90
+ return (
91
+ <Flex direction="column" alignItems="stretch" gap={4}>
92
+ <AuthorizationFormHeader />
93
+
94
+ <AuthorizationFormFields
95
+ paymentAmount={paymentAmount}
96
+ setPaymentAmount={setPaymentAmount}
97
+ authReference={authReference}
98
+ setAuthReference={setAuthReference}
99
+ firstname={firstname}
100
+ setFirstname={setFirstname}
101
+ lastname={lastname}
102
+ setLastname={setLastname}
103
+ email={email}
104
+ setEmail={setEmail}
105
+ telephonenumber={telephonenumber}
106
+ setTelephonenumber={setTelephonenumber}
107
+ gender={gender}
108
+ setGender={setGender}
109
+ salutation={salutation}
110
+ setSalutation={setSalutation}
111
+ country={country}
112
+ setCountry={setCountry}
113
+ currency={currency}
114
+ setCurrency={setCurrency}
115
+ city={city}
116
+ setCity={setCity}
117
+ street={street}
118
+ setStreet={setStreet}
119
+ zip={zip}
120
+ setZip={setZip}
121
+ paymentMethod={paymentMethod}
122
+ />
123
+
124
+ {paymentMethod === "cc" && settings?.enable3DSecure && (
125
+ <Box marginTop={4}>
126
+ <CardDetailsInput
127
+ cardtype={cardtype}
128
+ setCardtype={setCardtype}
129
+ cardpan={cardpan}
130
+ setCardpan={setCardpan}
131
+ cardexpiredate={cardexpiredate}
132
+ setCardexpiredate={setCardexpiredate}
133
+ cardcvc2={cardcvc2}
134
+ setCardcvc2={setCardcvc2}
135
+ />
136
+ </Box>
137
+ )}
138
+
139
+ <AuthorizationPaymentButtons
140
+ paymentMethod={paymentMethod}
141
+ paymentAmount={paymentAmount}
142
+ authReference={authReference}
143
+ isProcessingPayment={isProcessingPayment}
144
+ onAuthorization={onAuthorization}
145
+ settings={settings}
146
+ handleGooglePayToken={handleGooglePayToken}
147
+ handleGooglePayError={handleGooglePayError}
148
+ handleApplePayToken={handleApplePayToken}
149
+ handleApplePayError={handleApplePayError}
150
+ applePayToken={applePayToken}
151
+ isDisabled={isDisabled}
152
+ />
153
+ </Flex>
154
+ );
155
+ };
156
+
157
+ export default AuthorizationForm;
@@ -0,0 +1,308 @@
1
+ import { Box, Flex, TextInput, Select, Option } from "@strapi/design-system";
2
+ import {
3
+ getSalutationOptions,
4
+ getGenderOptions,
5
+ getCurrencyOptions,
6
+ getCountryOptions,
7
+ } from "../../../../utils/countryLanguageUtils";
8
+ import InfoTooltip from "../../common/InfoTooltip";
9
+
10
+ const AuthorizationFormFields = ({
11
+ paymentAmount,
12
+ setPaymentAmount,
13
+ authReference,
14
+ setAuthReference,
15
+ firstname,
16
+ setFirstname,
17
+ lastname,
18
+ setLastname,
19
+ email,
20
+ setEmail,
21
+ telephonenumber,
22
+ setTelephonenumber,
23
+ gender,
24
+ setGender,
25
+ salutation,
26
+ setSalutation,
27
+ country,
28
+ setCountry,
29
+ currency,
30
+ setCurrency,
31
+ city,
32
+ setCity,
33
+ street,
34
+ setStreet,
35
+ zip,
36
+ setZip,
37
+ paymentMethod,
38
+ }) => {
39
+ const countryOptions = getCountryOptions(paymentMethod);
40
+ const salutationOptions = getSalutationOptions(country || "US");
41
+ const genderOptions = getGenderOptions(country || "US");
42
+ const currencyOptions = getCurrencyOptions();
43
+
44
+ return (
45
+ <Box
46
+ style={{
47
+ display: "grid",
48
+ gridTemplateColumns: "repeat(auto-fit, minmax(250px, 1fr))",
49
+ gap: "16px",
50
+ }}
51
+ >
52
+ <TextInput
53
+ label="Amount *"
54
+ name="authAmount"
55
+ value={paymentAmount}
56
+ onChange={(e) => setPaymentAmount(e.target.value)}
57
+ placeholder="Enter amount (e.g., 1000 for €10.00)"
58
+ required
59
+ className="payment-input"
60
+ endAction={
61
+ <InfoTooltip
62
+ label="Amount"
63
+ description="Amount in cents (e.g., 1000 = €10.00)"
64
+ id="authAmount-tooltip"
65
+ />
66
+ }
67
+ />
68
+
69
+ <TextInput
70
+ label="Reference *"
71
+ name="authReference"
72
+ value={authReference}
73
+ onChange={(e) => setAuthReference(e.target.value)}
74
+ placeholder="Auto-generated if empty"
75
+ className="payment-input"
76
+ endAction={
77
+ <InfoTooltip
78
+ label="Reference"
79
+ description="Reference will be auto-generated if left empty"
80
+ id="authReference-tooltip"
81
+ />
82
+ }
83
+ />
84
+
85
+ <TextInput
86
+ label="First Name"
87
+ name="firstname"
88
+ value={firstname || ""}
89
+ onChange={(e) => setFirstname(e.target.value)}
90
+ placeholder="John"
91
+ className="payment-input"
92
+ endAction={
93
+ <InfoTooltip
94
+ label="First Name"
95
+ description="Customer first name"
96
+ id="firstname-tooltip"
97
+ />
98
+ }
99
+ />
100
+
101
+ <TextInput
102
+ label="Last Name"
103
+ name="lastname"
104
+ value={lastname || ""}
105
+ onChange={(e) => setLastname(e.target.value)}
106
+ placeholder="Doe"
107
+ className="payment-input"
108
+ endAction={
109
+ <InfoTooltip
110
+ label="Last Name"
111
+ description="Customer last name"
112
+ id="lastname-tooltip"
113
+ />
114
+ }
115
+ />
116
+
117
+ <TextInput
118
+ label="Email"
119
+ name="email"
120
+ value={email || ""}
121
+ onChange={(e) => setEmail(e.target.value)}
122
+ placeholder="john.doe@example.com"
123
+ className="payment-input"
124
+ endAction={
125
+ <InfoTooltip
126
+ label="Email"
127
+ description="Customer email address"
128
+ id="email-tooltip"
129
+ />
130
+ }
131
+ />
132
+
133
+ <TextInput
134
+ label="Phone Number"
135
+ name="telephonenumber"
136
+ value={telephonenumber || ""}
137
+ onChange={(e) => setTelephonenumber(e.target.value)}
138
+ placeholder="+4917512345678"
139
+ className="payment-input"
140
+ endAction={
141
+ <InfoTooltip
142
+ label="Phone Number"
143
+ description={`Customer phone number. Format should match selected country: ${
144
+ country || "US"
145
+ } (e.g., +4917512345678 for Germany, +12125551234 for US)`}
146
+ id="telephonenumber-tooltip"
147
+ />
148
+ }
149
+ />
150
+
151
+ <Select
152
+ label="Gender"
153
+ name="gender"
154
+ value={gender || ""}
155
+ onChange={(value) => setGender(value)}
156
+ placeholder="Select gender"
157
+ labelAction={
158
+ <InfoTooltip
159
+ label="Gender"
160
+ description={`Customer gender. Options depend on selected country: ${
161
+ country || "US"
162
+ }`}
163
+ id="gender-tooltip"
164
+ />
165
+ }
166
+ >
167
+ <Option value="" multi={false}>
168
+ Select gender
169
+ </Option>
170
+ {genderOptions.map((option) => (
171
+ <Option key={option.value} value={option.value} multi={false}>
172
+ {option.label}
173
+ </Option>
174
+ ))}
175
+ </Select>
176
+
177
+ <Select
178
+ label="Salutation"
179
+ name="salutation"
180
+ value={salutation || ""}
181
+ onChange={(value) => setSalutation(value)}
182
+ placeholder="Select salutation"
183
+ labelAction={
184
+ <InfoTooltip
185
+ label="Salutation"
186
+ description={`Customer salutation (e.g., Mr., Mrs., Ms.). Options depend on selected country: ${
187
+ country || "US"
188
+ }`}
189
+ id="salutation-tooltip"
190
+ />
191
+ }
192
+ >
193
+ <Option value="" multi={false}>
194
+ Select salutation
195
+ </Option>
196
+ {salutationOptions.map((option) => (
197
+ <Option key={option.value} value={option.value} multi={false}>
198
+ {option.label}
199
+ </Option>
200
+ ))}
201
+ </Select>
202
+
203
+ <Select
204
+ label="Country"
205
+ name="country"
206
+ value={country || ""}
207
+ onChange={(value) => setCountry(value)}
208
+ placeholder="Select country"
209
+ labelAction={
210
+ <InfoTooltip
211
+ label="Country"
212
+ description="Billing address country. This affects available currencies, phone number formats, and ZIP code formats."
213
+ id="country-tooltip"
214
+ />
215
+ }
216
+ >
217
+ <Option value="" multi={false}>
218
+ Select country
219
+ </Option>
220
+ {countryOptions.map((option) => (
221
+ <Option
222
+ key={option.value}
223
+ value={option.value}
224
+ disabled={option.disabled}
225
+ multi={false}
226
+ >
227
+ {option.label}
228
+ </Option>
229
+ ))}
230
+ </Select>
231
+
232
+ <Select
233
+ label="Currency"
234
+ name="currency"
235
+ value={currency || "EUR"}
236
+ onChange={(value) => setCurrency(value)}
237
+ placeholder="Select currency"
238
+ labelAction={
239
+ <InfoTooltip
240
+ label="Currency"
241
+ description={`Currency code (e.g., EUR, USD, GBP). Should match the selected country: ${
242
+ country || "US"
243
+ }`}
244
+ id="currency-tooltip"
245
+ />
246
+ }
247
+ >
248
+ {currencyOptions.map((option) => (
249
+ <Option key={option.value} value={option.value} multi={false}>
250
+ {option.label}
251
+ </Option>
252
+ ))}
253
+ </Select>
254
+
255
+ <TextInput
256
+ label="City"
257
+ name="city"
258
+ value={city || ""}
259
+ onChange={(e) => setCity(e.target.value)}
260
+ placeholder="Berlin"
261
+ className="payment-input"
262
+ endAction={
263
+ <InfoTooltip
264
+ label="City"
265
+ description={`Billing address city for country: ${country || "US"}`}
266
+ id="city-tooltip"
267
+ />
268
+ }
269
+ />
270
+
271
+ <TextInput
272
+ label="Street"
273
+ name="street"
274
+ value={street || ""}
275
+ onChange={(e) => setStreet(e.target.value)}
276
+ placeholder="Main Street 123"
277
+ className="payment-input"
278
+ endAction={
279
+ <InfoTooltip
280
+ label="Street"
281
+ description="Billing address street"
282
+ id="street-tooltip"
283
+ />
284
+ }
285
+ />
286
+
287
+ <TextInput
288
+ label="ZIP Code"
289
+ name="zip"
290
+ value={zip || ""}
291
+ onChange={(e) => setZip(e.target.value)}
292
+ placeholder="12345"
293
+ className="payment-input"
294
+ endAction={
295
+ <InfoTooltip
296
+ label="ZIP Code"
297
+ description={`Billing address ZIP/postal code. Format should match selected country: ${
298
+ country || "US"
299
+ } (e.g., 12345 for US, 10115 for Germany)`}
300
+ id="zip-tooltip"
301
+ />
302
+ }
303
+ />
304
+ </Box>
305
+ );
306
+ };
307
+
308
+ export default AuthorizationFormFields;
@@ -0,0 +1,27 @@
1
+ import { Flex, Typography } from "@strapi/design-system";
2
+
3
+ const AuthorizationFormHeader = () => {
4
+ return (
5
+ <Flex direction="row" gap={2}>
6
+ <Typography
7
+ variant="omega"
8
+ fontWeight="semiBold"
9
+ textColor="neutral800"
10
+ className="payment-form-title"
11
+ >
12
+ Authorization
13
+ </Typography>
14
+ <Typography
15
+ variant="pi"
16
+ textColor="neutral600"
17
+ className="payment-form-description"
18
+ >
19
+ Authorize and capture an amount immediately.
20
+ </Typography>
21
+ </Flex>
22
+ );
23
+ };
24
+
25
+ export default AuthorizationFormHeader;
26
+
27
+
@@ -0,0 +1,93 @@
1
+ import { Box, Button, Typography } from "@strapi/design-system";
2
+ import { Play } from "@strapi/icons";
3
+ import GooglePayButton from "../../GooglePaybutton";
4
+ import ApplePayBtn from "../../ApplePayBtn";
5
+
6
+ const AuthorizationPaymentButtons = ({
7
+ paymentMethod,
8
+ paymentAmount,
9
+ authReference,
10
+ isProcessingPayment,
11
+ onAuthorization,
12
+ settings,
13
+ handleGooglePayToken,
14
+ handleGooglePayError,
15
+ handleApplePayToken,
16
+ handleApplePayError,
17
+ applePayToken,
18
+ isDisabled,
19
+ }) => {
20
+ if (paymentMethod === "gpp") {
21
+ return (
22
+ <GooglePayButton
23
+ amount={paymentAmount}
24
+ currency="EUR"
25
+ onTokenReceived={handleGooglePayToken}
26
+ onError={handleGooglePayError}
27
+ settings={settings}
28
+ />
29
+ );
30
+ }
31
+
32
+ if (paymentMethod === "apl") {
33
+ return (
34
+ <Box>
35
+ <ApplePayBtn
36
+ amount={paymentAmount}
37
+ onTokenReceived={handleApplePayToken}
38
+ onError={handleApplePayError}
39
+ settings={settings}
40
+ />
41
+ {applePayToken && (
42
+ <Box
43
+ marginTop={3}
44
+ style={{
45
+ width: "100%",
46
+ display: "flex",
47
+ flexDirection: "column",
48
+ alignItems: "flex-start",
49
+ gap: "8px",
50
+ }}
51
+ >
52
+ <Typography
53
+ variant="pi"
54
+ textColor="success600"
55
+ style={{ marginBottom: "8px", fontWeight: "bold" }}
56
+ >
57
+ ✓ Apple Pay token received. You can now process the
58
+ authorization:
59
+ </Typography>
60
+ <Button
61
+ variant="default"
62
+ onClick={() => onAuthorization(applePayToken)}
63
+ loading={isProcessingPayment}
64
+ startIcon={<Play />}
65
+ style={{ maxWidth: "200px" }}
66
+ disabled={!paymentAmount.trim() || !authReference.trim()}
67
+ className="payment-button payment-button-primary"
68
+ >
69
+ Process Authorization
70
+ </Button>
71
+ </Box>
72
+ )}
73
+ </Box>
74
+ );
75
+ }
76
+
77
+ return (
78
+ <Button
79
+ variant="default"
80
+ onClick={onAuthorization}
81
+ loading={isProcessingPayment}
82
+ startIcon={<Play />}
83
+ style={{ maxWidth: "200px" }}
84
+ className="payment-button payment-button-primary"
85
+ disabled={isDisabled}
86
+ >
87
+ Process Authorization
88
+ </Button>
89
+ );
90
+ };
91
+
92
+ export default AuthorizationPaymentButtons;
93
+