strapi-plugin-payone-provider 1.0.1

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 (42) hide show
  1. package/README.md +571 -0
  2. package/admin/src/components/Initializer/index.js +16 -0
  3. package/admin/src/components/PluginIcon/index.js +6 -0
  4. package/admin/src/index.js +37 -0
  5. package/admin/src/pages/App/components/ConfigurationPanel.js +265 -0
  6. package/admin/src/pages/App/components/HistoryPanel.js +298 -0
  7. package/admin/src/pages/App/components/PaymentActionsPanel.js +333 -0
  8. package/admin/src/pages/App/components/StatusBadge.js +22 -0
  9. package/admin/src/pages/App/components/TransactionHistoryItem.js +374 -0
  10. package/admin/src/pages/App/components/icons/BankIcon.js +10 -0
  11. package/admin/src/pages/App/components/icons/ChevronDownIcon.js +9 -0
  12. package/admin/src/pages/App/components/icons/ChevronUpIcon.js +9 -0
  13. package/admin/src/pages/App/components/icons/CreditCardIcon.js +9 -0
  14. package/admin/src/pages/App/components/icons/ErrorIcon.js +10 -0
  15. package/admin/src/pages/App/components/icons/InfoIcon.js +9 -0
  16. package/admin/src/pages/App/components/icons/PaymentIcon.js +10 -0
  17. package/admin/src/pages/App/components/icons/PendingIcon.js +9 -0
  18. package/admin/src/pages/App/components/icons/PersonIcon.js +9 -0
  19. package/admin/src/pages/App/components/icons/SuccessIcon.js +9 -0
  20. package/admin/src/pages/App/components/icons/WalletIcon.js +9 -0
  21. package/admin/src/pages/App/components/icons/index.js +11 -0
  22. package/admin/src/pages/App/index.js +483 -0
  23. package/admin/src/pages/utils/api.js +75 -0
  24. package/admin/src/pages/utils/formatTransactionData.js +16 -0
  25. package/admin/src/pages/utils/paymentUtils.js +528 -0
  26. package/admin/src/pluginId.js +5 -0
  27. package/package.json +43 -0
  28. package/server/bootstrap.js +26 -0
  29. package/server/config/index.js +42 -0
  30. package/server/controllers/index.js +7 -0
  31. package/server/controllers/payone.js +134 -0
  32. package/server/destroy.js +5 -0
  33. package/server/index.js +21 -0
  34. package/server/policies/index.js +6 -0
  35. package/server/policies/isAuth.js +23 -0
  36. package/server/policies/isSuperAdmin.js +18 -0
  37. package/server/register.js +5 -0
  38. package/server/routes/index.js +124 -0
  39. package/server/services/index.js +7 -0
  40. package/server/services/payone.js +679 -0
  41. package/strapi-admin.js +3 -0
  42. package/strapi-server.js +3 -0
@@ -0,0 +1,265 @@
1
+ import React from "react";
2
+ import {
3
+ Box,
4
+ Button,
5
+ Card,
6
+ CardBody,
7
+ Flex,
8
+ Stack,
9
+ Typography,
10
+ TextInput,
11
+ Select,
12
+ Option,
13
+ Alert
14
+ } from "@strapi/design-system";
15
+ import { Play } from "@strapi/icons";
16
+
17
+ const ConfigurationPanel = ({
18
+ settings,
19
+ isSaving,
20
+ isTesting,
21
+ testResult,
22
+ onSave,
23
+ onTestConnection,
24
+ onInputChange
25
+ }) => {
26
+ return (
27
+ <Box
28
+ hasRadius
29
+ shadow="filterShadow"
30
+ paddingTop={8}
31
+ paddingBottom={8}
32
+ paddingLeft={8}
33
+ paddingRight={8}
34
+ style={{
35
+ borderRadius: "12px",
36
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.08)",
37
+ border: "1px solid #f6f6f9"
38
+ }}
39
+ >
40
+ <Flex direction="column" alignItems="stretch" gap={8}>
41
+ <Box>
42
+ <Typography variant="beta" as="h2" fontWeight="bold">
43
+ Payone API Configuration
44
+ </Typography>
45
+ <Typography variant="pi" marginTop={2}>
46
+ Configure your Payone payment gateway settings
47
+ </Typography>
48
+ </Box>
49
+
50
+ <Box>
51
+ <Card style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}>
52
+ <CardBody padding={6}>
53
+ <Stack spacing={6}>
54
+ <Flex gap={4} wrap="wrap">
55
+ <TextInput
56
+ label="Account ID (aid)"
57
+ name="aid"
58
+ value={settings.aid || ""}
59
+ onChange={(e) => onInputChange("aid", e.target.value)}
60
+ required
61
+ hint="Your Payone account ID"
62
+ style={{ flex: 1, minWidth: "300px" }}
63
+ />
64
+
65
+ <TextInput
66
+ label="Portal ID"
67
+ name="portalid"
68
+ value={settings.portalid || ""}
69
+ onChange={(e) => onInputChange("portalid", e.target.value)}
70
+ required
71
+ hint="Your Payone portal ID"
72
+ style={{ flex: 1, minWidth: "300px" }}
73
+ />
74
+ </Flex>
75
+
76
+ <Flex gap={4} wrap="wrap">
77
+ <TextInput
78
+ label="Merchant ID (mid)"
79
+ name="mid"
80
+ value={settings.mid || ""}
81
+ onChange={(e) => onInputChange("mid", e.target.value)}
82
+ required
83
+ hint="Your Payone merchant ID"
84
+ style={{ flex: 1, minWidth: "300px" }}
85
+ />
86
+
87
+ <TextInput
88
+ label="Portal Key"
89
+ name="key"
90
+ type="password"
91
+ value={settings.key || ""}
92
+ onChange={(e) => onInputChange("key", e.target.value)}
93
+ required
94
+ hint="Your Payone portal key (will be encrypted)"
95
+ style={{ flex: 1, minWidth: "300px" }}
96
+ />
97
+ </Flex>
98
+
99
+ <Flex gap={4} wrap="wrap">
100
+ <Select
101
+ label="Mode"
102
+ name="mode"
103
+ value={settings.mode || "test"}
104
+ onChange={(value) => onInputChange("mode", value)}
105
+ hint="Select the API mode"
106
+ style={{ flex: 1, minWidth: "300px" }}
107
+ >
108
+ <Option value="test">Test Environment</Option>
109
+ <Option value="live">Live Environment</Option>
110
+ </Select>
111
+
112
+ <TextInput
113
+ label="API Version"
114
+ name="api_version"
115
+ value={settings.api_version || "3.10"}
116
+ onChange={(e) =>
117
+ onInputChange("api_version", e.target.value)
118
+ }
119
+ hint="Payone API version"
120
+ style={{ flex: 1, minWidth: "300px" }}
121
+ />
122
+ </Flex>
123
+ </Stack>
124
+ </CardBody>
125
+ </Card>
126
+ </Box>
127
+
128
+ <Box paddingTop={6}>
129
+ <Card style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}>
130
+ <CardBody padding={6}>
131
+ <Stack spacing={6}>
132
+ <Box>
133
+ <Typography
134
+ variant="delta"
135
+ as="h3"
136
+ fontWeight="bold"
137
+ marginBottom={2}
138
+ >
139
+ Test Connection
140
+ </Typography>
141
+ <Typography variant="pi" textColor="neutral600">
142
+ Verify your Payone configuration by testing the API
143
+ connection
144
+ </Typography>
145
+ </Box>
146
+
147
+ <Button
148
+ variant="default"
149
+ onClick={onTestConnection}
150
+ loading={isTesting}
151
+ startIcon={<Play />}
152
+ style={{
153
+ background: "#28a745",
154
+ border: "none",
155
+ color: "white",
156
+ fontWeight: "600",
157
+ borderRadius: "8px"
158
+ }}
159
+ >
160
+ {isTesting ? "Testing Connection..." : "Test Connection"}
161
+ </Button>
162
+
163
+ {testResult && (
164
+ <Alert
165
+ variant={Boolean(testResult.success) ? "success" : "danger"}
166
+ title={
167
+ Boolean(testResult.success)
168
+ ? "Connection Successful"
169
+ : "Connection Failed"
170
+ }
171
+ style={{
172
+ borderRadius: "8px",
173
+ border: Boolean(testResult.success)
174
+ ? "1px solid #d4edda"
175
+ : "1px solid #f8d7da"
176
+ }}
177
+ >
178
+ <Typography
179
+ variant="pi"
180
+ fontWeight="medium"
181
+ marginBottom={2}
182
+ >
183
+ {testResult.message}
184
+ </Typography>
185
+ {testResult.details && (
186
+ <Box paddingTop={3}>
187
+ {Boolean(testResult.success) ? (
188
+ <Card
189
+ style={{
190
+ border: "1px solid #e9ecef"
191
+ }}
192
+ >
193
+ <CardBody padding={4}>
194
+ <Typography variant="pi">
195
+ <strong>Mode:</strong> {testResult.details.mode}{" "}
196
+ |<strong> AID:</strong> {testResult.details.aid}{" "}
197
+ |<strong> Portal ID:</strong>{" "}
198
+ {testResult.details.portalid} |
199
+ <strong> Merchant ID:</strong>{" "}
200
+ {testResult.details.mid || ""}
201
+ </Typography>
202
+ </CardBody>
203
+ </Card>
204
+ ) : (
205
+ <Card
206
+ style={{
207
+ background: "#fff5f5",
208
+ border: "1px solid #fed7d7"
209
+ }}
210
+ >
211
+ <CardBody padding={4}>
212
+ <Stack spacing={2}>
213
+ {testResult.errorcode && (
214
+ <Typography
215
+ variant="pi"
216
+ textColor="neutral600"
217
+ >
218
+ <strong>Error Code:</strong>{" "}
219
+ {testResult.errorcode}
220
+ </Typography>
221
+ )}
222
+ {testResult.details.errorCode && (
223
+ <Typography
224
+ variant="pi"
225
+ textColor="neutral600"
226
+ >
227
+ <strong>Error Code:</strong>{" "}
228
+ {testResult.details.errorCode}
229
+ </Typography>
230
+ )}
231
+ {testResult.details &&
232
+ testResult.details.rawResponse && (
233
+ <Typography
234
+ variant="pi"
235
+ textColor="neutral600"
236
+ >
237
+ <strong>Debug Info:</strong>{" "}
238
+ {testResult.details.rawResponse}
239
+ </Typography>
240
+ )}
241
+ </Stack>
242
+ </CardBody>
243
+ </Card>
244
+ )}
245
+ </Box>
246
+ )}
247
+ </Alert>
248
+ )}
249
+ </Stack>
250
+ </CardBody>
251
+ </Card>
252
+ </Box>
253
+
254
+ <Box paddingTop={4}>
255
+ <Typography variant="sigma" textColor="neutral600">
256
+ Note: These settings are used for all Payone API requests. Make sure
257
+ to use the correct credentials for your selected mode.
258
+ </Typography>
259
+ </Box>
260
+ </Flex>
261
+ </Box>
262
+ );
263
+ };
264
+
265
+ export default ConfigurationPanel;
@@ -0,0 +1,298 @@
1
+ import React from "react";
2
+ import {
3
+ Box,
4
+ Button,
5
+ Card,
6
+ CardBody,
7
+ Flex,
8
+ Stack,
9
+ Typography,
10
+ TextInput,
11
+ Divider
12
+ } from "@strapi/design-system";
13
+ import { Search } from "@strapi/icons";
14
+ import TransactionHistoryItem from "./TransactionHistoryItem";
15
+
16
+ const HistoryPanel = ({
17
+ filters,
18
+ onFilterChange,
19
+ onFilterApply,
20
+ isLoadingHistory,
21
+ transactionHistory,
22
+ paginatedTransactions,
23
+ currentPage,
24
+ totalPages,
25
+ pageSize,
26
+ onRefresh,
27
+ onPageChange
28
+ }) => {
29
+
30
+ return (
31
+ <Box
32
+ hasRadius
33
+ shadow="filterShadow"
34
+ paddingTop={8}
35
+ paddingBottom={8}
36
+ paddingLeft={8}
37
+ paddingRight={8}
38
+ style={{
39
+ borderRadius: "12px",
40
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.08)",
41
+ border: "1px solid #f6f6f9"
42
+ }}
43
+ >
44
+ <Flex direction="column" alignItems="stretch" gap={8}>
45
+ <Typography variant="beta" as="h2" marginBottom={2}>
46
+ Transaction Management
47
+ </Typography>
48
+ {/* Filters */}
49
+ <Box>
50
+ <Box marginBottom={4}>
51
+ <Typography variant="delta" as="h3" fontWeight="bold">
52
+ Transaction Filters
53
+ </Typography>
54
+ <Typography variant="pi" textColor="neutral600" marginTop={2}>
55
+ Filter transactions by status, type, date range, and more
56
+ </Typography>
57
+ </Box>
58
+ <Card style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}>
59
+ <CardBody padding={6}>
60
+ <Stack spacing={4}>
61
+ <Flex gap={4} wrap="wrap" alignItems="center">
62
+ <TextInput
63
+ label="Status"
64
+ name="status"
65
+ value={filters.status}
66
+ onChange={(e) => onFilterChange("status", e.target.value)}
67
+ placeholder="APPROVED, ERROR, etc."
68
+ style={{ flex: 1, minWidth: "200px" }}
69
+ />
70
+ <TextInput
71
+ label="Request Type"
72
+ name="request_type"
73
+ value={filters.request_type}
74
+ onChange={(e) =>
75
+ onFilterChange("request_type", e.target.value)
76
+ }
77
+ placeholder="preauthorization, authorization, etc."
78
+ style={{ flex: 1, minWidth: "200px" }}
79
+ />
80
+ <TextInput
81
+ label="Transaction ID"
82
+ name="txid"
83
+ value={filters.txid}
84
+ onChange={(e) => onFilterChange("txid", e.target.value)}
85
+ placeholder="Enter TxId"
86
+ style={{ flex: 1, minWidth: "200px" }}
87
+ />
88
+ <TextInput
89
+ label="Reference"
90
+ name="reference"
91
+ value={filters.reference}
92
+ onChange={(e) =>
93
+ onFilterChange("reference", e.target.value)
94
+ }
95
+ placeholder="Enter reference"
96
+ style={{ flex: 1, minWidth: "200px" }}
97
+ />
98
+ <TextInput
99
+ label="Date From"
100
+ name="date_from"
101
+ value={filters.date_from}
102
+ onChange={(e) =>
103
+ onFilterChange("date_from", e.target.value)
104
+ }
105
+ placeholder="YYYY-MM-DD"
106
+ type="date"
107
+ style={{ flex: 1, minWidth: "200px" }}
108
+ />
109
+ <TextInput
110
+ label="Date To"
111
+ name="date_to"
112
+ value={filters.date_to}
113
+ onChange={(e) => onFilterChange("date_to", e.target.value)}
114
+ placeholder="YYYY-MM-DD"
115
+ type="date"
116
+ style={{ flex: 1, minWidth: "200px" }}
117
+ />
118
+ <Button
119
+ variant="default"
120
+ onClick={onFilterApply}
121
+ loading={isLoadingHistory}
122
+ startIcon={<Search />}
123
+ >
124
+ Apply Filters
125
+ </Button>
126
+ </Flex>
127
+ </Stack>
128
+ </CardBody>
129
+ </Card>
130
+ </Box>
131
+
132
+ <Divider />
133
+
134
+ {/* Transaction History */}
135
+ <Box>
136
+ <Box marginBottom={6}>
137
+ <Flex
138
+ justifyContent="space-between"
139
+ alignItems="center"
140
+ marginBottom={4}
141
+ >
142
+ <Box>
143
+ <Typography variant="delta" as="h3" fontWeight="bold">
144
+ Transaction History
145
+ </Typography>
146
+ <Typography variant="pi" textColor="neutral600" marginTop={2}>
147
+ {transactionHistory.length} total transactions •{" "}
148
+ {paginatedTransactions.length} on page {currentPage} of{" "}
149
+ {totalPages}
150
+ </Typography>
151
+ </Box>
152
+ <Button
153
+ variant="default"
154
+ onClick={onRefresh}
155
+ loading={isLoadingHistory}
156
+ startIcon={<Search />}
157
+ size="S"
158
+ style={{
159
+ background: "#28a745",
160
+ border: "none",
161
+ color: "white",
162
+ fontWeight: "600",
163
+ borderRadius: "8px"
164
+ }}
165
+ >
166
+ Refresh
167
+ </Button>
168
+ </Flex>
169
+ </Box>
170
+
171
+ {isLoadingHistory ? (
172
+ <Box padding={4} textAlign="center">
173
+ <Typography>Loading transactions...</Typography>
174
+ </Box>
175
+ ) : transactionHistory.length === 0 ? (
176
+ <Box padding={4} textAlign="center">
177
+ <Typography textColor="neutral600">
178
+ No transactions found
179
+ </Typography>
180
+ </Box>
181
+ ) : (
182
+ <Box>
183
+ {paginatedTransactions.map((transaction) => (
184
+ <TransactionHistoryItem
185
+ key={transaction.id}
186
+ transaction={transaction}
187
+ />
188
+ ))}
189
+
190
+ {/* Pagination */}
191
+ <Box paddingTop={6} paddingBottom={4}>
192
+ <Card
193
+ style={{ borderRadius: "8px", border: "1px solid #e4e2e7" }}
194
+ >
195
+ <CardBody padding={4}>
196
+ <Flex justifyContent="space-between" alignItems="center">
197
+ {transactionHistory.length > pageSize &&
198
+ totalPages > 1 ? (
199
+ <Flex gap={3} alignItems="center">
200
+ <Button
201
+ variant="default"
202
+ size="S"
203
+ onClick={() =>
204
+ onPageChange(Math.max(1, currentPage - 1))
205
+ }
206
+ disabled={currentPage === 1}
207
+ style={{
208
+ background:
209
+ currentPage === 1 ? "#f6f6f9" : "#28a745",
210
+ border: "none",
211
+ color: currentPage === 1 ? "#666687" : "white",
212
+ fontWeight: "600",
213
+ borderRadius: "6px"
214
+ }}
215
+ >
216
+ ← Previous
217
+ </Button>
218
+
219
+ <Box
220
+ padding={2}
221
+ background="#f6f6f9"
222
+ borderRadius="6px"
223
+ >
224
+ <Typography
225
+ variant="pi"
226
+ textColor="neutral600"
227
+ fontWeight="bold"
228
+ >
229
+ Page {currentPage} of {totalPages}
230
+ </Typography>
231
+ </Box>
232
+
233
+ <Button
234
+ variant="default"
235
+ size="S"
236
+ onClick={() =>
237
+ onPageChange(
238
+ Math.min(totalPages, currentPage + 1)
239
+ )
240
+ }
241
+ disabled={currentPage === totalPages}
242
+ style={{
243
+ background:
244
+ currentPage === totalPages
245
+ ? "#f6f6f9"
246
+ : "#28a745",
247
+ border: "none",
248
+ color:
249
+ currentPage === totalPages
250
+ ? "#666687"
251
+ : "white",
252
+ fontWeight: "600",
253
+ borderRadius: "6px"
254
+ }}
255
+ >
256
+ Next →
257
+ </Button>
258
+ </Flex>
259
+ ) : (
260
+ <Typography
261
+ variant="pi"
262
+ textColor="neutral600"
263
+ fontWeight="medium"
264
+ >
265
+ {transactionHistory.length <= pageSize
266
+ ? "All transactions shown"
267
+ : "No pagination needed"}
268
+ </Typography>
269
+ )}
270
+ </Flex>
271
+ </CardBody>
272
+ </Card>
273
+ <Typography
274
+ variant="pi"
275
+ textColor="neutral600"
276
+ fontWeight="medium"
277
+ >
278
+ Showing {paginatedTransactions.length} of{" "}
279
+ {transactionHistory.length} transactions
280
+ </Typography>
281
+ </Box>
282
+ </Box>
283
+ )}
284
+ </Box>
285
+
286
+ <Box paddingTop={4}>
287
+ <Typography variant="sigma" textColor="neutral600">
288
+ Note: This shows all Payone transactions processed through this
289
+ plugin. Transactions are automatically logged with detailed
290
+ request/response data.
291
+ </Typography>
292
+ </Box>
293
+ </Flex>
294
+ </Box>
295
+ );
296
+ };
297
+
298
+ export default HistoryPanel;