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,361 @@
1
+ import React, { useState } from "react";
2
+ import {
3
+ Box,
4
+ Flex,
5
+ Typography,
6
+ Accordion,
7
+ AccordionToggle,
8
+ AccordionContent,
9
+ } from "@strapi/design-system";
10
+ import PaymentMethodSelector from "./PaymentMethodSelector";
11
+ import PreauthorizationForm from "./preauthorization/PreauthorizationForm";
12
+ import AuthorizationForm from "./authorization/AuthorizationForm";
13
+ import CaptureForm from "./CaptureForm";
14
+ import RefundForm from "./RefundForm";
15
+ import PaymentResult from "./PaymentResult";
16
+ import ApplePayPanel from "./ApplePayPanel";
17
+
18
+ const PaymentActionsPanel = ({
19
+ paymentActions,
20
+ settings,
21
+ onNavigateToConfig,
22
+ }) => {
23
+ const mode = (settings?.mode || "test").toLowerCase();
24
+ const isLiveMode = mode === "live";
25
+
26
+ const [expandedAccordions, setExpandedAccordions] = useState({
27
+ preauthorization: false,
28
+ authorization: false,
29
+ capture: false,
30
+ refund: false,
31
+ });
32
+
33
+ const toggleAccordion = (key) => {
34
+ setExpandedAccordions((prev) => ({
35
+ ...prev,
36
+ [key]: !prev[key],
37
+ }));
38
+ };
39
+
40
+ React.useEffect(() => {
41
+ if (isLiveMode && paymentActions.paymentMethod !== "apl") {
42
+ paymentActions.setPaymentMethod("apl");
43
+ }
44
+ }, [isLiveMode, paymentActions.paymentMethod]);
45
+
46
+ if (isLiveMode && paymentActions.paymentMethod !== "apl") {
47
+ return (
48
+ <Box
49
+ style={{
50
+ display: "flex",
51
+ flexDirection: "column",
52
+ alignItems: "center",
53
+ justifyContent: "center",
54
+ gap: "8px",
55
+ marginTop: "44px",
56
+ }}
57
+ >
58
+ <Typography variant="pi" textColor="neutral600">
59
+ Test Payments are only works in test mode.
60
+ </Typography>
61
+ <Typography variant="pi" textColor="neutral600">
62
+ Please switch to test mode in plugin settings to use test payments.
63
+ </Typography>
64
+ </Box>
65
+ );
66
+ }
67
+
68
+ if (paymentActions.paymentMethod === "apl") {
69
+ return (
70
+ <ApplePayPanel
71
+ paymentAmount={paymentActions.paymentAmount}
72
+ setPaymentAmount={paymentActions.setPaymentAmount}
73
+ authReference={paymentActions.authReference}
74
+ setAuthReference={paymentActions.setAuthReference}
75
+ isProcessingPayment={paymentActions.isProcessingPayment}
76
+ onAuthorization={paymentActions.handleAuthorization}
77
+ paymentMethod={paymentActions.paymentMethod}
78
+ setPaymentMethod={paymentActions.setPaymentMethod}
79
+ captureMode={paymentActions.captureMode}
80
+ setCaptureMode={paymentActions.setCaptureMode}
81
+ settings={settings}
82
+ setGooglePayToken={paymentActions.setGooglePayToken}
83
+ applePayToken={paymentActions.applePayToken}
84
+ setApplePayToken={paymentActions.setApplePayToken}
85
+ cardtype={paymentActions.cardtype}
86
+ setCardtype={paymentActions.setCardtype}
87
+ cardpan={paymentActions.cardpan}
88
+ setCardpan={paymentActions.setCardpan}
89
+ cardexpiredate={paymentActions.cardexpiredate}
90
+ setCardexpiredate={paymentActions.setCardexpiredate}
91
+ cardcvc2={paymentActions.cardcvc2}
92
+ setCardcvc2={paymentActions.setCardcvc2}
93
+ onNavigateToConfig={onNavigateToConfig}
94
+ isLiveMode={isLiveMode}
95
+ firstname={paymentActions.firstname}
96
+ setFirstname={paymentActions.setFirstname}
97
+ lastname={paymentActions.lastname}
98
+ setLastname={paymentActions.setLastname}
99
+ email={paymentActions.email}
100
+ setEmail={paymentActions.setEmail}
101
+ telephonenumber={paymentActions.telephonenumber}
102
+ setTelephonenumber={paymentActions.setTelephonenumber}
103
+ gender={paymentActions.gender}
104
+ setGender={paymentActions.setGender}
105
+ salutation={paymentActions.salutation}
106
+ setSalutation={paymentActions.setSalutation}
107
+ country={paymentActions.country}
108
+ setCountry={paymentActions.setCountry}
109
+ currency={paymentActions.currency}
110
+ setCurrency={paymentActions.setCurrency}
111
+ city={paymentActions.city}
112
+ setCity={paymentActions.setCity}
113
+ street={paymentActions.street}
114
+ setStreet={paymentActions.setStreet}
115
+ zip={paymentActions.zip}
116
+ setZip={paymentActions.setZip}
117
+ />
118
+ );
119
+ }
120
+
121
+ return (
122
+ <Box
123
+ className="payment-container"
124
+ paddingTop={8}
125
+ paddingBottom={8}
126
+ paddingLeft={8}
127
+ paddingRight={8}
128
+ >
129
+ <Flex direction="column" alignItems="stretch" gap={6}>
130
+ <Box
131
+ style={{
132
+ display: "flex",
133
+ flexDirection: "column",
134
+ alignItems: "flex-start",
135
+ gap: "8px",
136
+ }}
137
+ >
138
+ <Typography
139
+ variant="beta"
140
+ as="h2"
141
+ className="payment-title"
142
+ style={{ fontSize: "20px", marginBottom: "4px" }}
143
+ >
144
+ Payment Actions
145
+ </Typography>
146
+ <Typography
147
+ variant="pi"
148
+ textColor="neutral600"
149
+ className="payment-subtitle"
150
+ style={{ fontSize: "14px" }}
151
+ >
152
+ Process payments, captures, and refunds with multiple payment
153
+ methods
154
+ </Typography>
155
+ </Box>
156
+
157
+ <PaymentMethodSelector
158
+ paymentMethod={paymentActions.paymentMethod}
159
+ setPaymentMethod={paymentActions.setPaymentMethod}
160
+ captureMode={paymentActions.captureMode}
161
+ setCaptureMode={paymentActions.setCaptureMode}
162
+ onNavigateToConfig={onNavigateToConfig}
163
+ isLiveMode={isLiveMode}
164
+ />
165
+
166
+ <Accordion
167
+ expanded={expandedAccordions.preauthorization}
168
+ onToggle={() => toggleAccordion("preauthorization")}
169
+ >
170
+ <AccordionToggle title="Preauthorization" />
171
+ <AccordionContent>
172
+ <Box
173
+ className="payment-form-section"
174
+ style={{
175
+ opacity: isLiveMode ? 0.5 : 1,
176
+ pointerEvents: isLiveMode ? "none" : "auto",
177
+ }}
178
+ >
179
+ <PreauthorizationForm
180
+ paymentAmount={paymentActions.paymentAmount}
181
+ setPaymentAmount={paymentActions.setPaymentAmount}
182
+ preauthReference={paymentActions.preauthReference}
183
+ setPreauthReference={paymentActions.setPreauthReference}
184
+ isProcessingPayment={paymentActions.isProcessingPayment}
185
+ onPreauthorization={paymentActions.handlePreauthorization}
186
+ paymentMethod={paymentActions.paymentMethod}
187
+ settings={settings}
188
+ setGooglePayToken={paymentActions.setGooglePayToken}
189
+ cardtype={paymentActions.cardtype}
190
+ setCardtype={paymentActions.setCardtype}
191
+ cardpan={paymentActions.cardpan}
192
+ setCardpan={paymentActions.setCardpan}
193
+ cardexpiredate={paymentActions.cardexpiredate}
194
+ setCardexpiredate={paymentActions.setCardexpiredate}
195
+ cardcvc2={paymentActions.cardcvc2}
196
+ setCardcvc2={paymentActions.setCardcvc2}
197
+ isLiveMode={isLiveMode}
198
+ firstname={paymentActions.firstname}
199
+ setFirstname={paymentActions.setFirstname}
200
+ lastname={paymentActions.lastname}
201
+ setLastname={paymentActions.setLastname}
202
+ email={paymentActions.email}
203
+ setEmail={paymentActions.setEmail}
204
+ telephonenumber={paymentActions.telephonenumber}
205
+ setTelephonenumber={paymentActions.setTelephonenumber}
206
+ gender={paymentActions.gender}
207
+ setGender={paymentActions.setGender}
208
+ salutation={paymentActions.salutation}
209
+ setSalutation={paymentActions.setSalutation}
210
+ country={paymentActions.country}
211
+ setCountry={paymentActions.setCountry}
212
+ currency={paymentActions.currency}
213
+ setCurrency={paymentActions.setCurrency}
214
+ city={paymentActions.city}
215
+ setCity={paymentActions.setCity}
216
+ street={paymentActions.street}
217
+ setStreet={paymentActions.setStreet}
218
+ zip={paymentActions.zip}
219
+ setZip={paymentActions.setZip}
220
+ />
221
+ </Box>
222
+ </AccordionContent>
223
+ </Accordion>
224
+
225
+ <Accordion
226
+ expanded={expandedAccordions.authorization}
227
+ onToggle={() => toggleAccordion("authorization")}
228
+ >
229
+ <AccordionToggle title="Authorization" />
230
+ <AccordionContent>
231
+ <Box className="payment-form-section">
232
+ <AuthorizationForm
233
+ paymentAmount={paymentActions.paymentAmount}
234
+ setPaymentAmount={paymentActions.setPaymentAmount}
235
+ authReference={paymentActions.authReference}
236
+ setAuthReference={paymentActions.setAuthReference}
237
+ isProcessingPayment={paymentActions.isProcessingPayment}
238
+ onAuthorization={paymentActions.handleAuthorization}
239
+ paymentMethod={paymentActions.paymentMethod}
240
+ settings={settings}
241
+ setGooglePayToken={paymentActions.setGooglePayToken}
242
+ applePayToken={paymentActions.applePayToken}
243
+ setApplePayToken={paymentActions.setApplePayToken}
244
+ cardtype={paymentActions.cardtype}
245
+ setCardtype={paymentActions.setCardtype}
246
+ cardpan={paymentActions.cardpan}
247
+ setCardpan={paymentActions.setCardpan}
248
+ cardexpiredate={paymentActions.cardexpiredate}
249
+ setCardexpiredate={paymentActions.setCardexpiredate}
250
+ cardcvc2={paymentActions.cardcvc2}
251
+ setCardcvc2={paymentActions.setCardcvc2}
252
+ firstname={paymentActions.firstname}
253
+ setFirstname={paymentActions.setFirstname}
254
+ lastname={paymentActions.lastname}
255
+ setLastname={paymentActions.setLastname}
256
+ email={paymentActions.email}
257
+ setEmail={paymentActions.setEmail}
258
+ telephonenumber={paymentActions.telephonenumber}
259
+ setTelephonenumber={paymentActions.setTelephonenumber}
260
+ gender={paymentActions.gender}
261
+ setGender={paymentActions.setGender}
262
+ salutation={paymentActions.salutation}
263
+ setSalutation={paymentActions.setSalutation}
264
+ country={paymentActions.country}
265
+ setCountry={paymentActions.setCountry}
266
+ currency={paymentActions.currency}
267
+ setCurrency={paymentActions.setCurrency}
268
+ city={paymentActions.city}
269
+ setCity={paymentActions.setCity}
270
+ street={paymentActions.street}
271
+ setStreet={paymentActions.setStreet}
272
+ zip={paymentActions.zip}
273
+ setZip={paymentActions.setZip}
274
+ />
275
+ </Box>
276
+ </AccordionContent>
277
+ </Accordion>
278
+
279
+ <Accordion
280
+ expanded={expandedAccordions.capture}
281
+ onToggle={() => toggleAccordion("capture")}
282
+ >
283
+ <AccordionToggle title="Capture" />
284
+ <AccordionContent>
285
+ <Box
286
+ className="payment-form-section"
287
+ style={{
288
+ opacity: isLiveMode ? 0.5 : 1,
289
+ pointerEvents: isLiveMode ? "none" : "auto",
290
+ }}
291
+ >
292
+ <CaptureForm
293
+ paymentAmount={paymentActions.paymentAmount}
294
+ setPaymentAmount={paymentActions.setPaymentAmount}
295
+ captureTxid={paymentActions.captureTxid}
296
+ setCaptureTxid={paymentActions.setCaptureTxid}
297
+ captureCurrency={paymentActions.captureCurrency}
298
+ setCaptureCurrency={paymentActions.setCaptureCurrency}
299
+ captureSequenceNumber={paymentActions.captureSequenceNumber}
300
+ setCaptureSequenceNumber={
301
+ paymentActions.setCaptureSequenceNumber
302
+ }
303
+ captureMode={paymentActions.captureMode}
304
+ setCaptureMode={paymentActions.setCaptureMode}
305
+ paymentMethod={paymentActions.paymentMethod}
306
+ isProcessingPayment={paymentActions.isProcessingPayment}
307
+ onCapture={paymentActions.handleCapture}
308
+ />
309
+ </Box>
310
+ </AccordionContent>
311
+ </Accordion>
312
+
313
+ <Accordion
314
+ expanded={expandedAccordions.refund}
315
+ onToggle={() => toggleAccordion("refund")}
316
+ >
317
+ <AccordionToggle title="Refund" />
318
+ <AccordionContent>
319
+ <Box
320
+ className="payment-form-section"
321
+ style={{
322
+ opacity: isLiveMode ? 0.5 : 1,
323
+ pointerEvents: isLiveMode ? "none" : "auto",
324
+ }}
325
+ >
326
+ <RefundForm
327
+ paymentAmount={paymentActions.paymentAmount}
328
+ setPaymentAmount={paymentActions.setPaymentAmount}
329
+ refundTxid={paymentActions.refundTxid}
330
+ setRefundTxid={paymentActions.setRefundTxid}
331
+ refundSequenceNumber={paymentActions.refundSequenceNumber}
332
+ setRefundSequenceNumber={paymentActions.setRefundSequenceNumber}
333
+ refundReference={paymentActions.refundReference}
334
+ setRefundReference={paymentActions.setRefundReference}
335
+ refundCurrency={paymentActions.refundCurrency}
336
+ setRefundCurrency={paymentActions.setRefundCurrency}
337
+ isProcessingPayment={paymentActions.isProcessingPayment}
338
+ onRefund={paymentActions.handleRefund}
339
+ />
340
+ </Box>
341
+ </AccordionContent>
342
+ </Accordion>
343
+
344
+ <PaymentResult
345
+ paymentError={paymentActions.paymentError}
346
+ paymentResult={paymentActions.paymentResult}
347
+ />
348
+
349
+ <Box paddingTop={4}>
350
+ <Typography variant="sigma" textColor="neutral600">
351
+ Note: These payment actions allow you to test the complete payment
352
+ flow: Preauthorization → Capture → Refund. Make sure to use valid
353
+ Transaction IDs for capture and refund operations.
354
+ </Typography>
355
+ </Box>
356
+ </Flex>
357
+ </Box>
358
+ );
359
+ };
360
+
361
+ export default PaymentActionsPanel;
@@ -9,6 +9,7 @@ import {
9
9
  Alert,
10
10
  } from "@strapi/design-system";
11
11
  import pluginId from "../../../../pluginId";
12
+ import InfoTooltip from "../common/InfoTooltip";
12
13
  import {
13
14
  getPaymentMethodOptions,
14
15
  supportsCaptureMode,
@@ -32,10 +33,18 @@ const PaymentMethodSelector = ({
32
33
  name="paymentMethod"
33
34
  value={paymentMethod}
34
35
  onChange={(value) => setPaymentMethod(value)}
35
- hint={`Current: ${getPaymentMethodDisplayName(paymentMethod)}`}
36
+ labelAction={
37
+ <InfoTooltip
38
+ label="Payment Method"
39
+ description={`Current: ${getPaymentMethodDisplayName(
40
+ paymentMethod
41
+ )}`}
42
+ id="paymentMethod-tooltip"
43
+ />
44
+ }
36
45
  >
37
46
  {getPaymentMethodOptions(isLiveMode).map((option) => (
38
- <Option key={option.value} value={option.value}>
47
+ <Option key={option.value} value={option.value} multi={false}>
39
48
  {option.label}
40
49
  </Option>
41
50
  ))}
@@ -231,6 +240,9 @@ const PaymentMethodSelector = ({
231
240
  closeLabel="Close"
232
241
  title="⚠️ Important: Middleware Configuration Required"
233
242
  variant="warning"
243
+ onClose={() => {}}
244
+ action={null}
245
+ titleAs="h2"
234
246
  >
235
247
  <Typography variant="pi" marginTop={2}>
236
248
  <strong>Google Pay requires middleware configuration</strong> to
@@ -289,10 +301,16 @@ const PaymentMethodSelector = ({
289
301
  name="captureMode"
290
302
  value={captureMode}
291
303
  onChange={(value) => setCaptureMode(value)}
292
- hint="Select capture mode for wallet payments"
304
+ labelAction={
305
+ <InfoTooltip
306
+ label="Capture Mode"
307
+ description="Select capture mode for wallet payments"
308
+ id="captureMode-tooltip"
309
+ />
310
+ }
293
311
  >
294
312
  {getCaptureModeOptions().map((option) => (
295
- <Option key={option.value} value={option.value}>
313
+ <Option key={option.value} value={option.value} multi={false}>
296
314
  {option.label}
297
315
  </Option>
298
316
  ))}
@@ -1,6 +1,16 @@
1
1
  import React from "react";
2
- import { Box, Flex, Typography, TextInput, Button } from "@strapi/design-system";
2
+ import {
3
+ Box,
4
+ Flex,
5
+ Typography,
6
+ TextInput,
7
+ Button,
8
+ Select,
9
+ Option,
10
+ } from "@strapi/design-system";
3
11
  import { Play } from "@strapi/icons";
12
+ import { getCurrencyOptions } from "../../../utils/countryLanguageUtils";
13
+ import InfoTooltip from "../common/InfoTooltip";
4
14
 
5
15
  const RefundForm = ({
6
16
  paymentAmount,
@@ -11,72 +21,134 @@ const RefundForm = ({
11
21
  setRefundSequenceNumber,
12
22
  refundReference,
13
23
  setRefundReference,
24
+ refundCurrency,
25
+ setRefundCurrency,
14
26
  isProcessingPayment,
15
- onRefund
27
+ onRefund,
16
28
  }) => {
29
+ const currencyOptions = getCurrencyOptions();
30
+
17
31
  return (
18
32
  <Flex direction="column" alignItems="stretch" gap={4}>
19
33
  <Flex direction="row" gap={2}>
20
- <Typography variant="omega" fontWeight="semiBold" textColor="neutral800" className="payment-form-title">
34
+ <Typography
35
+ variant="omega"
36
+ fontWeight="semiBold"
37
+ textColor="neutral800"
38
+ className="payment-form-title"
39
+ >
21
40
  Refund
22
41
  </Typography>
23
- <Typography variant="pi" textColor="neutral600" className="payment-form-description">
42
+ <Typography
43
+ variant="pi"
44
+ textColor="neutral600"
45
+ className="payment-form-description"
46
+ >
24
47
  Refund a previously captured amount.
25
48
  </Typography>
26
49
  </Flex>
27
50
 
28
- <Flex gap={4} wrap="wrap">
51
+ <Box
52
+ style={{
53
+ display: "grid",
54
+ gridTemplateColumns: "repeat(auto-fit, minmax(250px, 1fr))",
55
+ gap: "16px",
56
+ }}
57
+ >
29
58
  <TextInput
30
- label="Transaction ID"
59
+ label="Transaction ID *"
31
60
  name="refundTxid"
32
61
  value={refundTxid}
33
62
  onChange={(e) => setRefundTxid(e.target.value)}
34
63
  placeholder="Enter TxId from capture"
35
- hint="Transaction ID from a previous capture"
64
+ required
36
65
  className="payment-input"
37
- style={{ flex: 1, minWidth: "200px" }}
66
+ endAction={
67
+ <InfoTooltip
68
+ label="Transaction ID"
69
+ description="Transaction ID (TxId) from a previous capture. This is required to refund the captured amount."
70
+ id="refundTxid-tooltip"
71
+ />
72
+ }
38
73
  />
39
74
 
40
75
  <TextInput
41
76
  label="Sequence Number"
42
77
  name="refundSequenceNumber"
43
- value={refundSequenceNumber}
78
+ value={refundSequenceNumber || "2"}
44
79
  onChange={(e) => setRefundSequenceNumber(e.target.value)}
45
80
  placeholder="2"
46
- hint="Sequence number for this refund (1-127) and by default for first 2"
47
81
  className="payment-input"
48
- style={{ flex: 1, minWidth: "200px" }}
82
+ endAction={
83
+ <InfoTooltip
84
+ label="Sequence Number"
85
+ description="Sequence number for this refund (1-127). Default is 2 for the first refund. Increment for multiple refunds."
86
+ id="refundSequenceNumber-tooltip"
87
+ />
88
+ }
49
89
  />
50
90
 
51
91
  <TextInput
52
- label="Amount (in cents)"
92
+ label="Amount *"
53
93
  name="refundAmount"
54
94
  value={paymentAmount}
55
95
  onChange={(e) => setPaymentAmount(e.target.value)}
56
96
  placeholder="1000"
57
- hint="Amount in cents to refund (will be negative)"
97
+ required
58
98
  className="payment-input"
59
- style={{ flex: 1, minWidth: "200px" }}
99
+ endAction={
100
+ <InfoTooltip
101
+ label="Amount"
102
+ description="Amount in cents to refund (e.g., 1000 = €10.00). The amount will be automatically converted to negative. Cannot exceed the captured amount."
103
+ id="refundAmount-tooltip"
104
+ />
105
+ }
60
106
  />
61
107
 
108
+ <Select
109
+ label="Currency"
110
+ name="refundCurrency"
111
+ value={refundCurrency || "EUR"}
112
+ onChange={(value) => setRefundCurrency(value)}
113
+ placeholder="EUR"
114
+ labelAction={
115
+ <InfoTooltip
116
+ label="Currency"
117
+ description="Currency code (e.g., EUR, USD, GBP). Must match the currency used in the original capture transaction."
118
+ id="refundCurrency-tooltip"
119
+ />
120
+ }
121
+ >
122
+ {currencyOptions.map((option) => (
123
+ <Option key={option.value} value={option.value} multi={false}>
124
+ {option.label}
125
+ </Option>
126
+ ))}
127
+ </Select>
128
+
62
129
  <TextInput
63
130
  label="Reference"
64
131
  name="refundReference"
65
- value={refundReference}
132
+ value={refundReference || ""}
66
133
  onChange={(e) => setRefundReference(e.target.value)}
67
134
  placeholder="Optional reference"
68
- hint="Optional reference for this refund"
69
135
  className="payment-input"
70
- style={{ flex: 1, minWidth: "200px" }}
136
+ endAction={
137
+ <InfoTooltip
138
+ label="Reference"
139
+ description="Optional reference for this refund. Useful for tracking and reconciliation purposes."
140
+ id="refundReference-tooltip"
141
+ />
142
+ }
71
143
  />
72
- </Flex>
144
+ </Box>
73
145
 
74
146
  <Button
75
147
  variant="default"
76
148
  onClick={onRefund}
77
149
  loading={isProcessingPayment}
78
150
  startIcon={<Play />}
79
- style={{ maxWidth: '200px' }}
151
+ style={{ maxWidth: "200px" }}
80
152
  className="payment-button payment-button-primary"
81
153
  disabled={!refundTxid.trim() || !paymentAmount.trim()}
82
154
  >
@@ -87,4 +159,3 @@ const RefundForm = ({
87
159
  };
88
160
 
89
161
  export default RefundForm;
90
-