strapi-plugin-payone-provider 5.6.11 → 5.6.13
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/README.md +102 -545
- package/admin/src/components/PluginIcon/index.jsx +14 -3
- package/admin/src/pages/App/components/AppHeader.jsx +1 -1
- package/admin/src/pages/App/components/AppTabs.jsx +69 -16
- package/admin/src/pages/App/components/RenderInput.jsx +9 -25
- package/admin/src/pages/App/components/StatusBadge.jsx +69 -17
- package/admin/src/pages/App/components/configuration/ConfigurationPanel.jsx +2 -2
- package/admin/src/pages/App/components/icons/index.jsx +1 -0
- package/admin/src/pages/App/components/transaction-history/FiltersPanel.jsx +4 -3
- package/admin/src/pages/App/components/transaction-history/TransactionTable.jsx +6 -5
- package/admin/src/pages/App/components/transaction-history/details/TransactionDetails.jsx +10 -10
- package/admin/src/pages/App/index.jsx +3 -3
- package/admin/src/pages/App/styles.css +28 -23
- package/admin/src/pages/utils/api.js +3 -2
- package/admin/src/pages/utils/getInputComponent.jsx +20 -45
- package/admin/src/pages/utils/transactionTableUtils.js +2 -1
- package/package.json +1 -1
- package/server/content-types/index.js +5 -0
- package/server/content-types/transactions/index.js +5 -0
- package/server/content-types/transactions/schema.json +87 -0
- package/server/controllers/payone.js +24 -13
- package/server/index.js +2 -0
- package/server/policies/is-payone-notification.js +12 -23
- package/server/services/transactionService.js +137 -104
- package/server/services/transactionStatusService.js +55 -61
- package/server/utils/sanitize.js +42 -0
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
import * as React from '@strapi/strapi/admin';
|
|
2
|
-
import { PuzzlePiece } from "@strapi/icons";
|
|
3
1
|
|
|
4
|
-
const PluginIcon = () =>
|
|
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;
|
|
@@ -1,20 +1,65 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { Tabs } from "@strapi/design-system";
|
|
2
|
+
import { Box, Typography, Tabs } from "@strapi/design-system";
|
|
3
3
|
import ConfigurationPanel from "./configuration/ConfigurationPanel";
|
|
4
4
|
import HistoryPanel from "./transaction-history/HistoryPanel";
|
|
5
5
|
import PaymentActionsPanel from "./payment-actions/PaymentActionsPanel";
|
|
6
6
|
import DocsPanel from "./DocsPanel";
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Error boundary to prevent a single tab's error from crashing the entire plugin.
|
|
10
|
+
* Automatically resets when the user switches tabs.
|
|
11
|
+
*/
|
|
12
|
+
class TabErrorBoundary extends React.Component {
|
|
13
|
+
constructor(props) {
|
|
14
|
+
super(props);
|
|
15
|
+
this.state = { hasError: false, error: null };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static getDerivedStateFromError(error) {
|
|
19
|
+
return { hasError: true, error };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
componentDidCatch(error, errorInfo) {
|
|
23
|
+
console.error("Payone Tab Error:", error, errorInfo);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
componentDidUpdate(prevProps) {
|
|
27
|
+
// Auto-reset when the user switches to a different tab
|
|
28
|
+
if (prevProps.activeTab !== this.props.activeTab && this.state.hasError) {
|
|
29
|
+
this.setState({ hasError: false, error: null });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
render() {
|
|
34
|
+
if (this.state.hasError) {
|
|
35
|
+
return (
|
|
36
|
+
<Box padding={6} style={{ textAlign: "center" }}>
|
|
37
|
+
<Typography variant="beta" textColor="danger600">
|
|
38
|
+
Something went wrong loading this tab.
|
|
39
|
+
</Typography>
|
|
40
|
+
<Typography
|
|
41
|
+
variant="pi"
|
|
42
|
+
textColor="neutral600"
|
|
43
|
+
style={{ marginTop: "8px", display: "block" }}
|
|
44
|
+
>
|
|
45
|
+
Try switching to another tab or reload the page.
|
|
46
|
+
</Typography>
|
|
47
|
+
</Box>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
return this.props.children;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
8
54
|
const AppTabs = ({
|
|
9
55
|
activeTab,
|
|
10
56
|
setActiveTab,
|
|
11
57
|
onNavigateToConfig,
|
|
12
58
|
settings,
|
|
13
|
-
paymentActions
|
|
59
|
+
paymentActions
|
|
14
60
|
}) => {
|
|
15
61
|
return (
|
|
16
62
|
<Tabs.Root
|
|
17
|
-
defaultValue={`tab-${activeTab}`}
|
|
18
63
|
value={`tab-${activeTab}`}
|
|
19
64
|
variant="regular"
|
|
20
65
|
onValueChange={(value) =>
|
|
@@ -22,29 +67,37 @@ const AppTabs = ({
|
|
|
22
67
|
}
|
|
23
68
|
>
|
|
24
69
|
<Tabs.List style={{ width: "100%" }}>
|
|
25
|
-
<Tabs.Trigger value="tab-1">
|
|
26
|
-
<Tabs.Trigger value="tab-2">
|
|
70
|
+
<Tabs.Trigger value="tab-1">Transaction History</Tabs.Trigger>
|
|
71
|
+
<Tabs.Trigger value="tab-2">Configuration</Tabs.Trigger>
|
|
27
72
|
<Tabs.Trigger value="tab-3">Payment Actions</Tabs.Trigger>
|
|
28
73
|
<Tabs.Trigger value="tab-4">Documentation</Tabs.Trigger>
|
|
29
74
|
</Tabs.List>
|
|
30
75
|
<Tabs.Content value="tab-1">
|
|
31
|
-
<
|
|
76
|
+
<TabErrorBoundary activeTab={activeTab}>
|
|
77
|
+
<HistoryPanel />
|
|
78
|
+
</TabErrorBoundary>
|
|
32
79
|
</Tabs.Content>
|
|
33
|
-
|
|
34
80
|
<Tabs.Content value="tab-2">
|
|
35
|
-
<
|
|
81
|
+
<TabErrorBoundary activeTab={activeTab}>
|
|
82
|
+
<ConfigurationPanel
|
|
83
|
+
settings={settings}
|
|
84
|
+
onNavigateToConfig={onNavigateToConfig}
|
|
85
|
+
/>
|
|
86
|
+
</TabErrorBoundary>
|
|
36
87
|
</Tabs.Content>
|
|
37
|
-
|
|
38
88
|
<Tabs.Content value="tab-3">
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
89
|
+
<TabErrorBoundary activeTab={activeTab}>
|
|
90
|
+
<PaymentActionsPanel
|
|
91
|
+
onNavigateToConfig={onNavigateToConfig}
|
|
92
|
+
settings={settings}
|
|
93
|
+
paymentActions={paymentActions}
|
|
94
|
+
/>
|
|
95
|
+
</TabErrorBoundary>
|
|
44
96
|
</Tabs.Content>
|
|
45
|
-
|
|
46
97
|
<Tabs.Content value="tab-4">
|
|
47
|
-
<
|
|
98
|
+
<TabErrorBoundary activeTab={activeTab}>
|
|
99
|
+
<DocsPanel settings={settings} paymentActions={paymentActions} />
|
|
100
|
+
</TabErrorBoundary>
|
|
48
101
|
</Tabs.Content>
|
|
49
102
|
</Tabs.Root>
|
|
50
103
|
);
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Field,
|
|
3
|
-
Flex,
|
|
4
|
-
DesignSystemProvider,
|
|
5
|
-
Tooltip,
|
|
6
|
-
Typography,
|
|
7
|
-
darkTheme,
|
|
8
|
-
lightTheme,
|
|
9
|
-
} from "@strapi/design-system";
|
|
1
|
+
import { Field, Flex, Tooltip, Typography } from "@strapi/design-system";
|
|
10
2
|
import { Information } from "@strapi/icons";
|
|
11
3
|
import { InputComponent } from "../../utils/getInputComponent";
|
|
12
4
|
import { shouldShowTooltip } from "../../utils/tooltipHelpers";
|
|
13
|
-
import { useSystemTheme } from "../../hooks/use-system-theme";
|
|
14
5
|
|
|
15
6
|
const RenderInput = ({
|
|
16
7
|
hint,
|
|
@@ -32,14 +23,12 @@ const RenderInput = ({
|
|
|
32
23
|
labelDirection = "column",
|
|
33
24
|
...props
|
|
34
25
|
}) => {
|
|
35
|
-
const systemTheme = useSystemTheme();
|
|
36
|
-
const theme = systemTheme === "dark" ? darkTheme : lightTheme;
|
|
37
26
|
const getLabelStyle = () => {
|
|
38
27
|
if (labelDirection === "row") {
|
|
39
28
|
return {
|
|
40
29
|
display: "flex",
|
|
41
30
|
flexDirection: "row",
|
|
42
|
-
justifyContent: "space-between"
|
|
31
|
+
justifyContent: "space-between"
|
|
43
32
|
};
|
|
44
33
|
}
|
|
45
34
|
return { display: "flex", flexDirection: "column" };
|
|
@@ -51,16 +40,13 @@ const RenderInput = ({
|
|
|
51
40
|
<Flex alignItems="center" gap={1} style={{ marginBottom: "5px" }}>
|
|
52
41
|
<Field.Label style={labelStyle}>{label}</Field.Label>
|
|
53
42
|
{shouldShowTooltip(inputType, tooltipContent) && (
|
|
54
|
-
<
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
/>
|
|
62
|
-
</Tooltip>
|
|
63
|
-
</DesignSystemProvider>
|
|
43
|
+
<Tooltip label={tooltipContent}>
|
|
44
|
+
<Information
|
|
45
|
+
style={{
|
|
46
|
+
cursor: "pointer"
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
</Tooltip>
|
|
64
50
|
)}
|
|
65
51
|
</Flex>
|
|
66
52
|
<InputComponent
|
|
@@ -75,8 +61,6 @@ const RenderInput = ({
|
|
|
75
61
|
placeholder={placeholder}
|
|
76
62
|
onLabel={onLabel}
|
|
77
63
|
offLabel={offLabel}
|
|
78
|
-
systemTheme={systemTheme}
|
|
79
|
-
theme={theme}
|
|
80
64
|
type={type}
|
|
81
65
|
{...props}
|
|
82
66
|
/>
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import * as React from "
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
import {
|
|
3
3
|
Badge,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
Box,
|
|
5
|
+
Flex,
|
|
6
|
+
Typography,
|
|
7
7
|
} from "@strapi/design-system";
|
|
8
|
-
import {
|
|
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
|
-
|
|
20
|
-
const
|
|
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
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
|
|
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={
|
|
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
|
|
100
|
+
const raw =
|
|
101
101
|
filter.inputType === "textInput"
|
|
102
102
|
? e.target.value
|
|
103
|
-
: e.target?.value
|
|
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}
|
|
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>
|
|
@@ -24,7 +24,7 @@ const App = () => {
|
|
|
24
24
|
|
|
25
25
|
if (isApplePayConfigPage) {
|
|
26
26
|
return (
|
|
27
|
-
<Layouts.Root>
|
|
27
|
+
<Layouts.Root className="payone-provider-root">
|
|
28
28
|
<AppHeader
|
|
29
29
|
title="Apple Pay Configuration"
|
|
30
30
|
activeTab={null}
|
|
@@ -48,7 +48,7 @@ const App = () => {
|
|
|
48
48
|
|
|
49
49
|
if (isGooglePayConfigPage) {
|
|
50
50
|
return (
|
|
51
|
-
<Layouts.Root>
|
|
51
|
+
<Layouts.Root className="payone-provider-root">
|
|
52
52
|
<AppHeader
|
|
53
53
|
title="Google Pay Configuration"
|
|
54
54
|
activeTab={null}
|
|
@@ -72,7 +72,7 @@ const App = () => {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
return (
|
|
75
|
-
<Layouts.Root>
|
|
75
|
+
<Layouts.Root className="payone-provider-root">
|
|
76
76
|
<AppHeader
|
|
77
77
|
activeTab={activeTab}
|
|
78
78
|
isSaving={settings.isSaving}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
[data-state="inactive"],
|
|
2
|
-
[data-state="active"] {
|
|
1
|
+
.payone-provider-root [data-state="inactive"],
|
|
2
|
+
.payone-provider-root [data-state="active"] {
|
|
3
3
|
background: transparent !important;
|
|
4
4
|
}
|
|
5
5
|
|
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
@keyframes pulse {
|
|
32
|
-
|
|
33
32
|
0%,
|
|
34
33
|
100% {
|
|
35
34
|
opacity: 1;
|
|
@@ -50,9 +49,8 @@
|
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
|
|
54
52
|
/* Tab Button Base Styles */
|
|
55
|
-
button[role="tab"] {
|
|
53
|
+
.payone-provider-root button[role="tab"] {
|
|
56
54
|
box-shadow: none !important;
|
|
57
55
|
border: none !important;
|
|
58
56
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1) !important;
|
|
@@ -60,44 +58,49 @@ button[role="tab"] {
|
|
|
60
58
|
background: transparent !important;
|
|
61
59
|
outline: none !important;
|
|
62
60
|
transform: scale(1) !important;
|
|
63
|
-
|
|
64
61
|
}
|
|
65
62
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
button[role="tab"]:active {
|
|
63
|
+
.payone-provider-root button[role="tab"]:active {
|
|
69
64
|
transform: scale(1) !important;
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
/* Remove shake animation */
|
|
73
|
-
button[role="tab"]:focus,
|
|
74
|
-
button[role="tab"]:focus-visible {
|
|
68
|
+
.payone-provider-root button[role="tab"]:focus,
|
|
69
|
+
.payone-provider-root button[role="tab"]:focus-visible {
|
|
75
70
|
outline: none !important;
|
|
76
71
|
box-shadow: none !important;
|
|
77
72
|
transform: none !important;
|
|
78
73
|
}
|
|
79
74
|
|
|
80
|
-
button[role="tab"][data-state="active"] {
|
|
81
|
-
background: linear-gradient(
|
|
75
|
+
.payone-provider-root button[role="tab"][data-state="active"] {
|
|
76
|
+
background: linear-gradient(
|
|
77
|
+
180deg,
|
|
78
|
+
rgba(73, 69, 255, 0.05) 0%,
|
|
79
|
+
transparent 100%
|
|
80
|
+
) !important;
|
|
82
81
|
color: #4945ff !important;
|
|
83
82
|
font-weight: 600 !important;
|
|
84
83
|
box-shadow: none !important;
|
|
85
84
|
border: none !important;
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
button[role="tab"][data-state="inactive"] {
|
|
87
|
+
.payone-provider-root button[role="tab"][data-state="inactive"] {
|
|
89
88
|
background: transparent !important;
|
|
90
89
|
color: #6b7280 !important;
|
|
91
90
|
box-shadow: none !important;
|
|
92
91
|
border: none !important;
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
button[role="tab"][data-state="inactive"]::after {
|
|
94
|
+
.payone-provider-root button[role="tab"][data-state="inactive"]::after {
|
|
96
95
|
background: transparent;
|
|
97
96
|
}
|
|
98
97
|
|
|
99
|
-
button[role="tab"][data-state="inactive"]:hover {
|
|
100
|
-
background: linear-gradient(
|
|
98
|
+
.payone-provider-root button[role="tab"][data-state="inactive"]:hover {
|
|
99
|
+
background: linear-gradient(
|
|
100
|
+
180deg,
|
|
101
|
+
rgba(73, 69, 255, 0.02) 0%,
|
|
102
|
+
transparent 100%
|
|
103
|
+
) !important;
|
|
101
104
|
box-shadow: none !important;
|
|
102
105
|
}
|
|
103
106
|
|
|
@@ -144,15 +147,17 @@ button[role="tab"][data-state="inactive"]:hover {
|
|
|
144
147
|
.payment-divider {
|
|
145
148
|
border: none;
|
|
146
149
|
height: 1px;
|
|
147
|
-
background: linear-gradient(
|
|
150
|
+
background: linear-gradient(
|
|
151
|
+
90deg,
|
|
152
|
+
transparent 0%,
|
|
153
|
+
#e8e8ea 20%,
|
|
154
|
+
#e8e8ea 80%,
|
|
155
|
+
transparent 100%
|
|
156
|
+
);
|
|
148
157
|
margin: 32px 0;
|
|
149
158
|
animation: fadeIn 0.4s ease-out;
|
|
150
159
|
}
|
|
151
160
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
161
|
/* ===== Responsive ===== */
|
|
157
162
|
@media (max-width: 768px) {
|
|
158
163
|
.payment-container {
|
|
@@ -168,4 +173,4 @@ button[role="tab"][data-state="inactive"]:hover {
|
|
|
168
173
|
.payment-grid-3 {
|
|
169
174
|
grid-template-columns: 1fr;
|
|
170
175
|
}
|
|
171
|
-
}
|
|
176
|
+
}
|
|
@@ -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
|
-
|
|
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
|
});
|