strapi-plugin-payone-provider 5.6.10 → 5.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.
@@ -1,6 +1,17 @@
1
- import * as React from '@strapi/strapi/admin';
2
- import { PuzzlePiece } from "@strapi/icons";
3
1
 
4
- const PluginIcon = () => <PuzzlePiece />;
2
+ const PluginIcon = () => (
3
+ <svg
4
+ xmlns="http://www.w3.org/2000/svg"
5
+ xmlSpace="preserve"
6
+ width={18}
7
+ height={18}
8
+ fill="currentColor"
9
+ version="1.1"
10
+ viewBox="0 0 438.254 438.254"
11
+ >
12
+ <path d="M402.612 177.546H368.25V63.187c0-19.652-15.988-35.64-35.64-35.64H35.641C15.988 27.547 0 43.535 0 63.187v161.88c0 19.652 15.988 35.64 35.641 35.64h34.357v114.358c0 19.653 15.989 35.642 35.642 35.642h296.973c19.652 0 35.642-15.989 35.642-35.642V213.188c-.001-19.653-15.99-35.642-35.643-35.642m-64.362-45.839H30v-20h308.25zM35.641 57.547h296.97c3.109 0 5.64 2.53 5.64 5.64v28.52H30v-28.52c0-3.11 2.53-5.64 5.641-5.64m0 173.16a5.647 5.647 0 0 1-5.641-5.64v-73.36h308.25v25.839H105.64c-19.652 0-35.642 15.989-35.642 35.642v17.519zm372.613 144.358a5.65 5.65 0 0 1-5.642 5.642H105.64a5.65 5.65 0 0 1-5.642-5.642V213.188a5.65 5.65 0 0 1 5.642-5.642h296.973a5.65 5.65 0 0 1 5.642 5.642z"></path>
13
+ <path d="M358.585 287.966c-6.941 0-13.48 1.74-19.216 4.797-5.885-3.15-12.429-4.797-19.265-4.797-22.607 0-41 18.393-41 41s18.393 41 41 41c6.835 0 13.379-1.647 19.265-4.796a40.74 40.74 0 0 0 19.216 4.796c22.607 0 41-18.393 41-41s-18.393-41-41-41m-59.481 41c0-11.579 9.421-21 21-21 1.065 0 2.113.09 3.145.243-3.593 6.093-5.664 13.186-5.664 20.757s2.071 14.664 5.664 20.757c-1.032.153-2.08.243-3.145.243-11.58 0-21-9.42-21-21m59.481 21c-11.579 0-21-9.421-21-21s9.421-21 21-21 21 9.421 21 21-9.421 21-21 21M177.126 241.707h-28c-5.522 0-10 4.477-10 10s4.478 10 10 10h28c5.522 0 10-4.477 10-10s-4.478-10-10-10M237.793 241.707h-28c-5.522 0-10 4.477-10 10s4.478 10 10 10h28c5.522 0 10-4.477 10-10s-4.478-10-10-10M308.459 251.707c0-5.523-4.478-10-10-10h-28c-5.522 0-10 4.477-10 10s4.478 10 10 10h28c5.522 0 10-4.477 10-10M331.126 261.707h28c5.522 0 10-4.477 10-10s-4.478-10-10-10h-28c-5.522 0-10 4.477-10 10s4.478 10 10 10"></path>
14
+ </svg>
15
+ );
5
16
 
6
17
  export default PluginIcon;
@@ -26,7 +26,7 @@ const AppHeader = ({ activeTab, isSaving, onSave, title, onBack }) => {
26
26
  >
27
27
  Back to Main
28
28
  </Button>
29
- ) : activeTab === 1 ? (
29
+ ) : activeTab === 2 ? (
30
30
  <Button
31
31
  loading={isSaving}
32
32
  onClick={onSave}
@@ -22,19 +22,22 @@ const AppTabs = ({
22
22
  }
23
23
  >
24
24
  <Tabs.List style={{ width: "100%" }}>
25
- <Tabs.Trigger value="tab-1">Configuration</Tabs.Trigger>
26
- <Tabs.Trigger value="tab-2">Transaction History</Tabs.Trigger>
25
+ <Tabs.Trigger value="tab-1">Transaction History</Tabs.Trigger>
26
+ <Tabs.Trigger value="tab-2">Configuration</Tabs.Trigger>
27
27
  <Tabs.Trigger value="tab-3">Payment Actions</Tabs.Trigger>
28
28
  <Tabs.Trigger value="tab-4">Documentation</Tabs.Trigger>
29
29
  </Tabs.List>
30
30
  <Tabs.Content value="tab-1">
31
- <ConfigurationPanel settings={settings} />
31
+ <HistoryPanel />
32
32
  </Tabs.Content>
33
-
34
33
  <Tabs.Content value="tab-2">
35
- <HistoryPanel />
34
+ <ConfigurationPanel
35
+ settings={settings}
36
+ onNavigateToConfig={onNavigateToConfig}
37
+ />
36
38
  </Tabs.Content>
37
39
 
40
+
38
41
  <Tabs.Content value="tab-3">
39
42
  <PaymentActionsPanel
40
43
  onNavigateToConfig={onNavigateToConfig}
@@ -1,13 +1,15 @@
1
- import * as React from "@strapi/strapi/admin";
1
+ import * as React from "react";
2
2
  import {
3
3
  Badge,
4
- DesignSystemProvider,
5
- darkTheme,
6
- lightTheme,
4
+ Box,
5
+ Flex,
6
+ Typography,
7
7
  } from "@strapi/design-system";
8
- import { useSystemTheme } from "../../hooks/use-system-theme";
8
+ import { MarkCircle } from "./icons";
9
+
10
+ const StatusBadge = ({ status, transaction }) => {
11
+ const [isHovered, setIsHovered] = React.useState(false);
9
12
 
10
- const StatusBadge = ({ status, size = "S" }) => {
11
13
  const statusColors = {
12
14
  APPROVED: "success200",
13
15
  PENDING: "warning200",
@@ -16,19 +18,69 @@ const StatusBadge = ({ status, size = "S" }) => {
16
18
  INVALID: "danger200",
17
19
  REDIRECT: "success100",
18
20
  };
19
- const systemTheme = useSystemTheme();
20
- const theme = systemTheme === "dark" ? darkTheme : lightTheme;
21
+
22
+ const getDisplayText = () => {
23
+ if (status === "ERROR" && transaction?.raw_response?.Error?.ErrorCode) {
24
+ return `${status} - ${transaction.raw_response.Error.ErrorCode}`;
25
+ }
26
+ return status;
27
+ };
28
+
29
+ const displayText = getDisplayText();
30
+ const errorMessage = status === "ERROR" && transaction?.raw_response?.Error?.ErrorMessage
31
+ ? transaction.raw_response.Error.ErrorMessage
32
+ : null;
33
+
34
+ const errorCode = status === "ERROR" && transaction?.raw_response?.Error?.ErrorCode
35
+ ? transaction.raw_response.Error.ErrorCode
36
+ : null;
37
+
38
+ const showExclamationIcon = status === "ERROR" && !errorCode && !errorMessage;
39
+
21
40
  return (
22
- <DesignSystemProvider theme={theme}>
23
- <Badge
24
- borderColor={statusColors[status]}
25
- background={"transparent"}
26
- textColor={statusColors[status]}
27
- size={size}
28
- >
29
- {status || "UNKNOWN"}
41
+ <Box
42
+ position="relative"
43
+ onMouseEnter={() => setIsHovered(true)}
44
+ onMouseLeave={() => setIsHovered(false)}
45
+ style={{ display: "inline-block", cursor: status === "ERROR" ? "pointer" : "default" }}
46
+ >
47
+ <Flex gap={2} alignItems="center">
48
+ <Badge backgroundColor={statusColors[status] || "warning100"}>
49
+ {displayText}
30
50
  </Badge>
31
- </DesignSystemProvider>
51
+ {showExclamationIcon && (
52
+ <MarkCircle color="danger500"
53
+ style={{
54
+ width: "16px",
55
+ height: "16px"
56
+ }}
57
+ />
58
+ )}
59
+ </Flex>
60
+ {isHovered && errorMessage && (
61
+ <Box
62
+ position="absolute"
63
+ zIndex={1000}
64
+ bottom="100%"
65
+ left="50%"
66
+ transform="translateX(-50%)"
67
+ marginBottom={2}
68
+ padding={3}
69
+ background="neutral900"
70
+ hasRadius
71
+ style={{
72
+ whiteSpace: "pre-line",
73
+ minWidth: "200px",
74
+ maxWidth: "300px",
75
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
76
+ }}
77
+ >
78
+ <Typography variant="pi" textColor="neutral0" style={{ fontSize: "12px" }}>
79
+ Error: {errorMessage}
80
+ </Typography>
81
+ </Box>
82
+ )}
83
+ </Box>
32
84
  );
33
85
  };
34
86
 
@@ -3,7 +3,7 @@ import { Box, Flex, Typography } from "@strapi/design-system";
3
3
  import ConfigurationFields from "./ConfigurationFields";
4
4
  import TestConnection from "./TestConnection";
5
5
 
6
- const ConfigurationPanel = ({ settings }) => {
6
+ const ConfigurationPanel = ({ settings, onNavigateToConfig }) => {
7
7
  return (
8
8
  <Flex direction="column" alignItems="stretch" gap={8} paddingTop={8}>
9
9
  <Box>
@@ -31,7 +31,7 @@ const ConfigurationPanel = ({ settings }) => {
31
31
  settings={settings.settings}
32
32
  onInputChange={settings.handleInputChange}
33
33
  onPaymentMethodToggle={settings.handlePaymentMethodToggle}
34
- onNavigateToConfig={settings.onNavigateToConfig}
34
+ onNavigateToConfig={onNavigateToConfig}
35
35
  />
36
36
 
37
37
  <TestConnection
@@ -9,3 +9,4 @@ export { default as PendingIcon } from './PendingIcon.jsx';
9
9
  export { default as InfoIcon } from './InfoIcon.jsx';
10
10
  export { default as ChevronDownIcon } from './ChevronDownIcon.jsx';
11
11
  export { default as ChevronUpIcon } from './ChevronUpIcon.jsx';
12
+ export { default as MarkCircle } from './MarkCircle.jsx';
@@ -95,12 +95,13 @@ const FiltersPanel = ({ filters, handleFiltersChange }) => {
95
95
  <RenderInput
96
96
  key={filter.name}
97
97
  name={filter.name}
98
- value={filters[filter.name] || ""}
98
+ value={filters[filter.name] ?? ""}
99
99
  onChange={(e) => {
100
- const value =
100
+ const raw =
101
101
  filter.inputType === "textInput"
102
102
  ? e.target.value
103
- : e.target?.value || e;
103
+ : e.target?.value ?? e;
104
+ const value = raw === "all" || raw === undefined ? "" : String(raw);
104
105
  handleFiltersChange({ [filter.name]: value });
105
106
  }}
106
107
  inputType={filter.inputType}
@@ -11,6 +11,7 @@ import TransactionDetails from "./details/TransactionDetails";
11
11
  import FiltersPanel from "./FiltersPanel";
12
12
  import useTransactionHistory from "../../../hooks/useTransactionHistory";
13
13
  import StatusBadge from "../StatusBadge";
14
+
14
15
  const TransactionTable = () => {
15
16
  const {
16
17
  transactions,
@@ -87,8 +88,8 @@ const TransactionTable = () => {
87
88
  <Table.Cell>
88
89
  <Typography variant="pi">
89
90
  {getPaymentMethodName(
90
- transaction.raw_request?.clearingtype,
91
- transaction.raw_request?.wallettype
91
+ (transaction.raw_request?.clearingtype || transaction.body?.raw_request?.clearingtype),
92
+ (transaction.raw_request?.wallettype || transaction.body?.raw_request?.wallettype)
92
93
  )}
93
94
  </Typography>
94
95
  </Table.Cell>
@@ -98,16 +99,16 @@ const TransactionTable = () => {
98
99
  </Typography>
99
100
  </Table.Cell>
100
101
  <Table.Cell>
101
- <StatusBadge status={transaction?.status} size="M" />
102
+ <StatusBadge status={transaction?.status} transaction={transaction} />
102
103
  </Table.Cell>
103
104
  <Table.Cell>
104
105
  <Typography variant="pi" textColor="neutral600">
105
- {formatDate(transaction.created_at)}
106
+ {formatDate(transaction.created_at ?? transaction.createdAt)}
106
107
  </Typography>
107
108
  </Table.Cell>
108
109
  <Table.Cell>
109
110
  <Typography variant="pi" textColor="neutral600">
110
- {formatDate(transaction.updated_at)}
111
+ {formatDate(transaction.updated_at ?? transaction.updatedAt)}
111
112
  </Typography>
112
113
  </Table.Cell>
113
114
  <Table.Cell>
@@ -47,8 +47,8 @@ const TransactionDetails = ({ transaction }) => {
47
47
  Name:
48
48
  </Typography>
49
49
  <Typography variant="pi" textColor="neutral800">
50
- {transaction.raw_request?.firstname}{" "}
51
- {transaction.raw_request?.lastname}
50
+ {transaction.raw_request?.firstname || transaction.body?.raw_request?.firstname }{" "}
51
+ {transaction.raw_request?.lastname || transaction.body?.raw_request?.lastname}
52
52
  </Typography>
53
53
  </Flex>
54
54
  <Flex gap={3}>
@@ -56,7 +56,7 @@ const TransactionDetails = ({ transaction }) => {
56
56
  Email:
57
57
  </Typography>
58
58
  <Typography variant="pi" textColor="neutral800">
59
- {transaction.raw_request?.email || "N/A"}
59
+ {transaction.raw_request?.email || transaction.body?.raw_request?.email || "N/A"}
60
60
  </Typography>
61
61
  </Flex>
62
62
  <Flex gap={3}>
@@ -64,7 +64,7 @@ const TransactionDetails = ({ transaction }) => {
64
64
  Phone:
65
65
  </Typography>
66
66
  <Typography variant="pi" textColor="neutral800">
67
- {transaction.raw_request?.telephonenumber || "N/A"}
67
+ {transaction.raw_request?.telephonenumber || transaction.body?.raw_request?.telephonenumber || "N/A"}
68
68
  </Typography>
69
69
  </Flex>
70
70
  <Flex gap={3}>
@@ -72,8 +72,8 @@ const TransactionDetails = ({ transaction }) => {
72
72
  Address:
73
73
  </Typography>
74
74
  <Typography variant="pi" textColor="neutral800">
75
- {transaction.raw_request?.street}, {transaction.raw_request?.zip}{" "}
76
- {transaction.raw_request?.city}
75
+ {transaction.raw_request?.street || transaction.body?.raw_request?.street}, {transaction.raw_request?.zip || transaction.body?.raw_request?.zip}{" "}
76
+ {transaction.raw_request?.city || transaction.body?.raw_request?.city}
77
77
  </Typography>
78
78
  </Flex>
79
79
  </Flex>
@@ -94,7 +94,7 @@ const TransactionDetails = ({ transaction }) => {
94
94
  {transaction.txid || "N/A"}
95
95
  </Typography>
96
96
  </Flex>
97
- {transaction.raw_request?.clearingtype === "cc" && (
97
+ {transaction.raw_request?.clearingtype === "cc" || transaction.body?.raw_request?.clearingtype === "cc" && (
98
98
  <>
99
99
  <Flex gap={3}>
100
100
  <Typography
@@ -105,7 +105,7 @@ const TransactionDetails = ({ transaction }) => {
105
105
  Card Type:
106
106
  </Typography>
107
107
  <Typography variant="pi" textColor="neutral800">
108
- {getCardTypeName(transaction.raw_request?.cardtype)}
108
+ {getCardTypeName(transaction.raw_request?.cardtype || transaction.body?.raw_request?.cardtype)}
109
109
  </Typography>
110
110
  </Flex>
111
111
  <Flex gap={3}>
@@ -118,7 +118,7 @@ const TransactionDetails = ({ transaction }) => {
118
118
  </Typography>
119
119
  <Typography variant="pi" textColor="neutral800">
120
120
  **** **** ****{" "}
121
- {transaction.raw_request?.cardpan?.slice(-4) || "****"}
121
+ {transaction.raw_request?.cardpan?.slice(-4) || transaction.body?.raw_request?.cardpan?.slice(-4) || "****"}
122
122
  </Typography>
123
123
  </Flex>
124
124
  </>
@@ -128,7 +128,7 @@ const TransactionDetails = ({ transaction }) => {
128
128
  Mode:
129
129
  </Typography>
130
130
  <Typography variant="pi" textColor="neutral800">
131
- {transaction.raw_request?.mode || "N/A"}
131
+ {transaction.raw_request?.mode || transaction.body?.raw_request?.mode || "N/A"}
132
132
  </Typography>
133
133
  </Flex>
134
134
  </Flex>
@@ -137,7 +137,6 @@ const useSettings = () => {
137
137
  setTestResult(null);
138
138
  try {
139
139
  const response = await testConnection();
140
- console.log("response in handleTestConnection:", response.data);
141
140
  if (response.data && response.data.success) {
142
141
  setTestResult(response.data);
143
142
  toggleNotification({
@@ -12,10 +12,11 @@ const usePayoneRequests = () => {
12
12
  const getTransactionHistory = (params = {}) => {
13
13
  const queryParams = new URLSearchParams();
14
14
 
15
- if (params.filters) {
15
+ if (params.filters && typeof params.filters === "object") {
16
16
  Object.keys(params.filters).forEach((key) => {
17
17
  const value = params.filters[key];
18
- if (value !== undefined && value !== null && value !== '') {
18
+ const v = value == null ? "" : String(value).trim();
19
+ if (v !== "" && v.toLowerCase() !== "all") {
19
20
  queryParams.append(`filters[${key}]`, String(value));
20
21
  }
21
22
  });
@@ -31,8 +31,9 @@ export const formatDate = (dateString) => {
31
31
  };
32
32
 
33
33
  export const getPaymentMethodName = (clearingtype, wallettype) => {
34
+
34
35
  switch (clearingtype) {
35
- case "cc":
36
+ case "cc" || "card" | "c":
36
37
  return "Credit Card";
37
38
  case "sb":
38
39
  return "Online Banking";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-payone-provider",
3
- "version": "5.6.10",
3
+ "version": "5.6.12",
4
4
  "description": "Strapi plugin for Payone payment gateway integration",
5
5
  "license": "MIT",
6
6
  "maintainers": [
@@ -42,4 +42,4 @@
42
42
  "kind": "plugin",
43
43
  "displayName": "Strapi Payone Provider"
44
44
  }
45
- }
45
+ }
@@ -22,12 +22,11 @@ module.exports = async ({ strapi }) => {
22
22
  displayName: "",
23
23
  domainName: "",
24
24
  merchantIdentifier: "",
25
- enableCreditCard: true,
26
- enablePayPal: true,
27
- enableGooglePay: true,
28
- enableApplePay: true,
29
- enableSofort: true,
30
- enableSepaDirectDebit: true
25
+ enableCreditCard: false,
26
+ enablePayPal: false,
27
+ enableGooglePay: false,
28
+ enableApplePay: false,
29
+ enableSepaDirectDebit: false
31
30
  }
32
31
  });
33
32
  }
@@ -0,0 +1,5 @@
1
+ const transactionsContentType = require('./transactions/index.js')
2
+
3
+ module.exports = {
4
+ 'transaction': transactionsContentType
5
+ }
@@ -0,0 +1,5 @@
1
+ const schema = require('./schema.json');
2
+
3
+ module.exports = {
4
+ schema
5
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "kind": "collectionType",
3
+ "collectionName": "transactions",
4
+ "info": {
5
+ "singularName": "transaction",
6
+ "pluralName": "transactions",
7
+ "displayName": "Transaction"
8
+ },
9
+ "options": {
10
+ "draftAndPublish": false
11
+ },
12
+ "pluginOptions": {
13
+ "content-manager": {
14
+ "visible": false
15
+ },
16
+ "content-type-builder": {
17
+ "visible": false
18
+ }
19
+ },
20
+ "attributes": {
21
+ "txid": {
22
+ "type": "string",
23
+ "required": false,
24
+ "default": "NO TXID"
25
+ },
26
+ "reference": {
27
+ "type": "string",
28
+ "required": false,
29
+ "default": "NO REFERENCE"
30
+ },
31
+ "invoiceid": {
32
+ "type": "string",
33
+ "required": false,
34
+ "default": "NO INVOICE ID"
35
+ },
36
+ "amount": {
37
+ "type": "string",
38
+ "required": false,
39
+ "default": "0"
40
+ },
41
+ "currency": {
42
+ "type": "string",
43
+ "required": false,
44
+ "default": "EUR"
45
+ },
46
+ "status": {
47
+ "type": "string",
48
+ "required": false,
49
+ "default": "unknown"
50
+ },
51
+ "error_code": {
52
+ "type": "string",
53
+ "required": false,
54
+ "default": "NO ERROR CODE"
55
+ },
56
+ "request_type": {
57
+ "type": "string",
58
+ "required": false,
59
+ "default": "unknown"
60
+ },
61
+ "error_message": {
62
+ "type": "string",
63
+ "required": false,
64
+ "default": "NO ERROR MESSAGE"
65
+ },
66
+ "customer_message": {
67
+ "type": "string",
68
+ "required": false,
69
+ "default": "NO CUSTOMER MESSAGE"
70
+ },
71
+ "body": {
72
+ "type": "json",
73
+ "required": false,
74
+ "default": {}
75
+ },
76
+ "raw_request": {
77
+ "type": "json",
78
+ "required": false,
79
+ "default": {}
80
+ },
81
+ "raw_response": {
82
+ "type": "json",
83
+ "required": false,
84
+ "default": {}
85
+ }
86
+ }
87
+ }
@@ -156,12 +156,22 @@ module.exports = ({ strapi }) => ({
156
156
 
157
157
  async getTransactionHistory(ctx) {
158
158
  try {
159
- const { filters = {}, pagination = {} } = ctx.query || {};
159
+ const { filters: rawFilters = {}, pagination = {} } = ctx.query || {};
160
160
  const page = parseInt(pagination.page || "1", 10);
161
161
  const pageSize = parseInt(pagination.pageSize || "10", 10);
162
162
 
163
+ const filters = {};
164
+ if (rawFilters && typeof rawFilters === "object") {
165
+ for (const [key, value] of Object.entries(rawFilters)) {
166
+ const v = value == null ? "" : String(value).trim();
167
+ if (v !== "" && v.toLowerCase() !== "all") {
168
+ filters[key] = value;
169
+ }
170
+ }
171
+ }
172
+
163
173
  const result = await getPayoneService(strapi).getTransactionHistory({
164
- filters: filters || {},
174
+ filters,
165
175
  pagination: { page, pageSize }
166
176
  });
167
177
 
@@ -299,19 +309,20 @@ module.exports = ({ strapi }) => ({
299
309
 
300
310
  async handleTransactionStatus(ctx) {
301
311
  try {
302
- const notificationData = ctx.request.body || {};
303
- await getPayoneService(strapi).processTransactionStatus(notificationData);
304
-
305
- ctx.status = 200;
306
- ctx.body = "TSOK";
307
- ctx.type = "text/plain";
308
- console.log(`[Payone TransactionStatus] Responded TSOK`);
312
+ if (!ctx.state.payoneAllowed) {
313
+ console.log("[Payone] Notification ignored (policy failed)");
314
+ } else {
315
+ const notificationData = ctx.request.body || {};
316
+ console.log(notificationData);
317
+ await getPayoneService(strapi).processTransactionStatus(notificationData);
318
+ }
309
319
  } catch (error) {
310
- console.log("[Payone TransactionStatus] Error handling notification:", error);
311
- ctx.status = 200;
312
- ctx.body = "TSOK";
313
- ctx.type = "text/plain";
320
+ console.log("[Payone TransactionStatus] Error:", error);
314
321
  }
322
+
323
+ ctx.status = 200;
324
+ ctx.body = "TSOK";
325
+ ctx.type = "text/plain";
315
326
  }
316
327
 
317
328
  });
package/server/index.js CHANGED
@@ -8,6 +8,7 @@ const controllers = require("./controllers");
8
8
  const routes = require("./routes");
9
9
  const services = require("./services");
10
10
  const policies = require("./policies");
11
+ const contentTypes = require("./content-types");
11
12
 
12
13
  module.exports = {
13
14
  register,
@@ -15,6 +16,7 @@ module.exports = {
15
16
  destroy,
16
17
  config,
17
18
  controllers,
19
+ contentTypes,
18
20
  routes,
19
21
  services,
20
22
  policies
@@ -1,30 +1,19 @@
1
- "use strict";
1
+ module.exports = async (ctx) => {
2
+ const { request } = ctx;
2
3
 
3
- module.exports = async (policyContext, config, { strapi }) => {
4
- const { request } = policyContext;
5
- const userAgent = request.header["user-agent"] || request.header["User-Agent"] || "";
6
- const clientIp = request.ip || request.connection?.remoteAddress || "";
4
+ const userAgent = request.headers["user-agent"] || "";
5
+ const clientIp =
6
+ request.headers["x-payone-client-ip"]?.trim() ||
7
+ request.headers["x-forwarded-for"]?.split(",")[0]?.trim() ||
8
+ request.ip ||
9
+ "";
7
10
 
8
- if (userAgent !== "PAYONE FinanceGate") {
9
- console.log(`[Payone TransactionStatus] Invalid User-Agent: ${userAgent}, IP: ${clientIp}`);
10
- return false;
11
- }
12
-
13
-
14
- const isValidIp = (ip) => {
15
- if (ip.startsWith("185.60.20.")) {
16
- return true;
17
- }
11
+ const isValid = userAgent === "PAYONE FinanceGate" && (clientIp.startsWith("185.60.20.") || clientIp === "54.246.203.105");
18
12
 
19
- if (ip === "54.246.203.105") {
20
- return true;
21
- }
22
- return false;
23
- };
13
+ ctx.state.payoneAllowed = isValid;
24
14
 
25
- if (!isValidIp(clientIp)) {
26
- console.log(`[Payone TransactionStatus] Invalid IP address: ${clientIp}, User-Agent: ${userAgent}`);
27
- return false;
15
+ if (!isValid) {
16
+ console.log("[Payone] Policy failed", { userAgent, clientIp });
28
17
  }
29
18
 
30
19
  return true;