strapi-plugin-payone-provider 1.3.0 → 1.4.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.
- package/admin/src/pages/App/components/icons/BankIcon.js +10 -10
- package/admin/src/pages/App/components/icons/ChevronDownIcon.js +9 -9
- package/admin/src/pages/App/components/icons/ChevronUpIcon.js +9 -9
- package/admin/src/pages/App/components/icons/CreditCardIcon.js +9 -9
- package/admin/src/pages/App/components/icons/ErrorIcon.js +10 -10
- package/admin/src/pages/App/components/icons/InfoIcon.js +9 -9
- package/admin/src/pages/App/components/icons/PaymentIcon.js +10 -10
- package/admin/src/pages/App/components/icons/PendingIcon.js +9 -9
- package/admin/src/pages/App/components/icons/PersonIcon.js +9 -9
- package/admin/src/pages/App/components/icons/SuccessIcon.js +9 -9
- package/admin/src/pages/App/components/icons/WalletIcon.js +9 -9
- package/admin/src/pages/App/components/icons/index.js +11 -11
- package/admin/src/pages/hooks/usePaymentActions.js +18 -6
- package/admin/src/pages/utils/formatTransactionData.js +15 -15
- package/package.json +1 -1
- package/server/bootstrap.js +42 -0
- package/server/controllers/payone.js +43 -4
- package/server/routes/index.js +9 -0
- package/server/services/paymentService.js +31 -19
- package/server/services/payone.js +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const BankIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill={color} />
|
|
6
|
-
<path d="M12 6l-1.5 3L7 8.5l2.5 2.5L8 14l4-2.5L16 14l-1.5-3L18 8.5l-3.5.5L12 6z" fill={color} />
|
|
7
|
-
</svg>
|
|
8
|
-
);
|
|
9
|
-
|
|
10
|
-
export default BankIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const BankIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill={color} />
|
|
6
|
+
<path d="M12 6l-1.5 3L7 8.5l2.5 2.5L8 14l4-2.5L16 14l-1.5-3L18 8.5l-3.5.5L12 6z" fill={color} />
|
|
7
|
+
</svg>
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export default BankIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const ChevronDownIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default ChevronDownIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const ChevronDownIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M7.41 8.59L12 13.17l4.59-4.58L18 10l-6 6-6-6 1.41-1.41z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default ChevronDownIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const ChevronUpIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default ChevronUpIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const ChevronUpIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default ChevronUpIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const CreditCardIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default CreditCardIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const CreditCardIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M20 4H4c-1.11 0-1.99.89-1.99 2L2 18c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V6c0-1.11-.89-2-2-2zm0 14H4v-6h16v6zm0-10H4V6h16v2z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default CreditCardIcon;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const ErrorIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill={color} />
|
|
6
|
-
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z" fill={color} />
|
|
7
|
-
</svg>
|
|
8
|
-
);
|
|
9
|
-
|
|
10
|
-
export default ErrorIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const ErrorIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill={color} />
|
|
6
|
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm5 11H7v-2h10v2z" fill={color} />
|
|
7
|
+
</svg>
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export default ErrorIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const InfoIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default InfoIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const InfoIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default InfoIcon;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const PaymentIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M2 8h20v12H2V8zm2 2v8h16V10H4z" fill={color} />
|
|
6
|
-
<path d="M2 4h20v2H2V4z" fill={color} />
|
|
7
|
-
</svg>
|
|
8
|
-
);
|
|
9
|
-
|
|
10
|
-
export default PaymentIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const PaymentIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M2 8h20v12H2V8zm2 2v8h16V10H4z" fill={color} />
|
|
6
|
+
<path d="M2 4h20v2H2V4z" fill={color} />
|
|
7
|
+
</svg>
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
export default PaymentIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const PendingIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M12 20C7.59 20 4 16.41 4 12S7.59 4 12 4 20 7.59 20 12 16.41 20 12 20M12.5 7H11V13L16.25 16.15L17 14.92L12.5 12.25V7Z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default PendingIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const PendingIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M12 20C7.59 20 4 16.41 4 12S7.59 4 12 4 20 7.59 20 12 16.41 20 12 20M12.5 7H11V13L16.25 16.15L17 14.92L12.5 12.25V7Z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default PendingIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const PersonIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default PersonIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const PersonIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default PersonIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const SuccessIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default SuccessIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const SuccessIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default SuccessIcon;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
const WalletIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
-
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
-
<path d="M21 7.28V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-2.28c.59-.35 1-.98 1-1.72V9c0-.74-.41-1.37-1-1.72zM20 9v6h-7V9h7zM5 19V5h14v2h-6c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6v2H5z" fill={color} />
|
|
6
|
-
</svg>
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
export default WalletIcon;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
const WalletIcon = ({ size = 16, color = 'currentColor' }) => (
|
|
4
|
+
<svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
5
|
+
<path d="M21 7.28V5c0-1.1-.9-2-2-2H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-2.28c.59-.35 1-.98 1-1.72V9c0-.74-.41-1.37-1-1.72zM20 9v6h-7V9h7zM5 19V5h14v2h-6c-1.1 0-2 .9-2 2v6c0 1.1.9 2 2 2h6v2H5z" fill={color} />
|
|
6
|
+
</svg>
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
export default WalletIcon;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { default as PaymentIcon } from './PaymentIcon';
|
|
2
|
-
export { default as PersonIcon } from './PersonIcon';
|
|
3
|
-
export { default as CreditCardIcon } from './CreditCardIcon';
|
|
4
|
-
export { default as BankIcon } from './BankIcon';
|
|
5
|
-
export { default as WalletIcon } from './WalletIcon';
|
|
6
|
-
export { default as ErrorIcon } from './ErrorIcon';
|
|
7
|
-
export { default as SuccessIcon } from './SuccessIcon';
|
|
8
|
-
export { default as PendingIcon } from './PendingIcon';
|
|
9
|
-
export { default as InfoIcon } from './InfoIcon';
|
|
10
|
-
export { default as ChevronDownIcon } from './ChevronDownIcon';
|
|
11
|
-
export { default as ChevronUpIcon } from './ChevronUpIcon';
|
|
1
|
+
export { default as PaymentIcon } from './PaymentIcon';
|
|
2
|
+
export { default as PersonIcon } from './PersonIcon';
|
|
3
|
+
export { default as CreditCardIcon } from './CreditCardIcon';
|
|
4
|
+
export { default as BankIcon } from './BankIcon';
|
|
5
|
+
export { default as WalletIcon } from './WalletIcon';
|
|
6
|
+
export { default as ErrorIcon } from './ErrorIcon';
|
|
7
|
+
export { default as SuccessIcon } from './SuccessIcon';
|
|
8
|
+
export { default as PendingIcon } from './PendingIcon';
|
|
9
|
+
export { default as InfoIcon } from './InfoIcon';
|
|
10
|
+
export { default as ChevronDownIcon } from './ChevronDownIcon';
|
|
11
|
+
export { default as ChevronUpIcon } from './ChevronUpIcon';
|
|
@@ -116,9 +116,15 @@ const usePaymentActions = () => {
|
|
|
116
116
|
|
|
117
117
|
if (needsRedirectUrls) {
|
|
118
118
|
const baseUrl = window.location.origin;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
// Detect current context (admin or content-ui) from pathname
|
|
120
|
+
const currentPath = window.location.pathname;
|
|
121
|
+
const isContentUI = currentPath.includes('/content-ui') || currentPath.includes('/content-manager');
|
|
122
|
+
const basePath = isContentUI ? '/content-ui' : '/admin';
|
|
123
|
+
const pluginPath = '/plugins/strapi-plugin-payone-provider/payment';
|
|
124
|
+
|
|
125
|
+
baseParams.successurl = `${baseUrl}${basePath}${pluginPath}/success`;
|
|
126
|
+
baseParams.errorurl = `${baseUrl}${basePath}${pluginPath}/error`;
|
|
127
|
+
baseParams.backurl = `${baseUrl}${basePath}${pluginPath}/back`;
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
const tokenToUse = tokenParam || googlePayToken;
|
|
@@ -252,9 +258,15 @@ const usePaymentActions = () => {
|
|
|
252
258
|
|
|
253
259
|
if (needsRedirectUrls) {
|
|
254
260
|
const baseUrl = window.location.origin;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
261
|
+
// Detect current context (admin or content-ui) from pathname
|
|
262
|
+
const currentPath = window.location.pathname;
|
|
263
|
+
const isContentUI = currentPath.includes('/content-ui') || currentPath.includes('/content-manager');
|
|
264
|
+
const basePath = isContentUI ? '/content-ui' : '/admin';
|
|
265
|
+
const pluginPath = '/plugins/strapi-plugin-payone-provider/payment';
|
|
266
|
+
|
|
267
|
+
baseParams.successurl = `${baseUrl}${basePath}${pluginPath}/success`;
|
|
268
|
+
baseParams.errorurl = `${baseUrl}${basePath}${pluginPath}/error`;
|
|
269
|
+
baseParams.backurl = `${baseUrl}${basePath}${pluginPath}/back`;
|
|
258
270
|
}
|
|
259
271
|
|
|
260
272
|
const tokenToUse = tokenParam || googlePayToken;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
export const formatTransactionData = (data) => {
|
|
2
|
-
const formattedData = [];
|
|
3
|
-
if (!data || typeof data !== "object") return formattedData;
|
|
4
|
-
|
|
5
|
-
for (const [key, value] of Object.entries(data)) {
|
|
6
|
-
if (value !== null && value !== undefined) {
|
|
7
|
-
formattedData.push({
|
|
8
|
-
key:
|
|
9
|
-
key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, " $1"),
|
|
10
|
-
value: typeof value === "object" ? JSON.stringify(value) : String(value)
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return formattedData;
|
|
1
|
+
export const formatTransactionData = (data) => {
|
|
2
|
+
const formattedData = [];
|
|
3
|
+
if (!data || typeof data !== "object") return formattedData;
|
|
4
|
+
|
|
5
|
+
for (const [key, value] of Object.entries(data)) {
|
|
6
|
+
if (value !== null && value !== undefined) {
|
|
7
|
+
formattedData.push({
|
|
8
|
+
key:
|
|
9
|
+
key.charAt(0).toUpperCase() + key.slice(1).replace(/([A-Z])/g, " $1"),
|
|
10
|
+
value: typeof value === "object" ? JSON.stringify(value) : String(value)
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return formattedData;
|
|
16
16
|
};
|
package/package.json
CHANGED
package/server/bootstrap.js
CHANGED
|
@@ -23,4 +23,46 @@ module.exports = async ({ strapi }) => {
|
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
// Register custom routes for 3DS redirects at root level
|
|
28
|
+
// These routes handle redirects from Payone after 3DS authentication
|
|
29
|
+
// They work with both /admin/ and /content-ui/ paths
|
|
30
|
+
const pluginName = "strapi-plugin-payone-provider";
|
|
31
|
+
|
|
32
|
+
// Get the controller
|
|
33
|
+
const getController = () => {
|
|
34
|
+
return strapi.plugin(pluginName).controller("payone");
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// All routes use the same handler - it detects success/error/back from URL path
|
|
38
|
+
// Routes match the plugin's internal payment callback URLs
|
|
39
|
+
const routes = [
|
|
40
|
+
"/admin/plugins/strapi-plugin-payone-provider/payment/success",
|
|
41
|
+
"/admin/plugins/strapi-plugin-payone-provider/payment/error",
|
|
42
|
+
"/admin/plugins/strapi-plugin-payone-provider/payment/back",
|
|
43
|
+
"/content-ui/plugins/strapi-plugin-payone-provider/payment/success",
|
|
44
|
+
"/content-ui/plugins/strapi-plugin-payone-provider/payment/error",
|
|
45
|
+
"/content-ui/plugins/strapi-plugin-payone-provider/payment/back"
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
// Register routes using Koa router
|
|
49
|
+
try {
|
|
50
|
+
const Router = require('@koa/router');
|
|
51
|
+
const router = new Router();
|
|
52
|
+
|
|
53
|
+
routes.forEach(route => {
|
|
54
|
+
router.get(route, async (ctx) => {
|
|
55
|
+
const controller = getController();
|
|
56
|
+
return await controller.handle3DSCallback(ctx);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Add router to the server app
|
|
61
|
+
if (strapi.server.app && typeof strapi.server.app.use === 'function') {
|
|
62
|
+
strapi.server.app.use(router.routes());
|
|
63
|
+
strapi.server.app.use(router.allowedMethods());
|
|
64
|
+
}
|
|
65
|
+
} catch (error) {
|
|
66
|
+
strapi.log.warn('Could not register 3DS callback routes:', error.message);
|
|
67
|
+
}
|
|
26
68
|
};
|
|
@@ -43,12 +43,25 @@ module.exports = ({ strapi }) => ({
|
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
|
|
46
|
+
async getPublicSettings(ctx) {
|
|
47
|
+
try {
|
|
48
|
+
const settings = await getPayoneService(strapi).getSettings();
|
|
49
|
+
ctx.body = {
|
|
50
|
+
data: {
|
|
51
|
+
mid: settings?.mid || null,
|
|
52
|
+
mode: settings?.mode || null
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
} catch (error) {
|
|
56
|
+
handleError(ctx, error);
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
|
|
46
60
|
async updateSettings(ctx) {
|
|
47
61
|
try {
|
|
48
62
|
const { body } = ctx.request;
|
|
49
63
|
const currentSettings = await getPayoneService(strapi).getSettings();
|
|
50
64
|
|
|
51
|
-
// Preserve existing key if hidden or not provided
|
|
52
65
|
if (body.key === "***HIDDEN***" || !body.key) {
|
|
53
66
|
body.key = currentSettings?.key;
|
|
54
67
|
}
|
|
@@ -124,13 +137,39 @@ module.exports = ({ strapi }) => ({
|
|
|
124
137
|
/**
|
|
125
138
|
* Handle 3D Secure callback from Payone
|
|
126
139
|
* This endpoint receives the callback after customer completes 3DS authentication
|
|
140
|
+
* Works with both /admin/ and /content-ui/ paths
|
|
127
141
|
*/
|
|
128
142
|
async handle3DSCallback(ctx) {
|
|
129
143
|
try {
|
|
130
|
-
|
|
144
|
+
const isGetRequest = ctx.request.method === "GET";
|
|
145
|
+
const currentPath = ctx.request.url;
|
|
146
|
+
|
|
147
|
+
let resultType = "callback";
|
|
148
|
+
if (currentPath.includes("/success")) {
|
|
149
|
+
resultType = "success";
|
|
150
|
+
} else if (currentPath.includes("/error")) {
|
|
151
|
+
resultType = "error";
|
|
152
|
+
} else if (currentPath.includes("/back")) {
|
|
153
|
+
resultType = "cancelled";
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const callbackData = isGetRequest ? ctx.query : ctx.request.body;
|
|
157
|
+
strapi.log.info(`3DS ${resultType} received (${ctx.request.method}):`, callbackData);
|
|
158
|
+
const result = await getPayoneService(strapi).handle3DSCallback(callbackData, resultType);
|
|
131
159
|
|
|
132
|
-
|
|
133
|
-
|
|
160
|
+
if (isGetRequest) {
|
|
161
|
+
const isContentUI = currentPath.includes('/content-ui');
|
|
162
|
+
const basePath = isContentUI ? '/content-ui' : '/admin';
|
|
163
|
+
const pluginPath = '/plugins/strapi-plugin-payone-provider';
|
|
164
|
+
|
|
165
|
+
const queryParams = new URLSearchParams();
|
|
166
|
+
queryParams.set('3ds', resultType);
|
|
167
|
+
if (result.txid) queryParams.set('txid', result.txid);
|
|
168
|
+
if (result.status) queryParams.set('status', result.status);
|
|
169
|
+
|
|
170
|
+
const redirectUrl = `${basePath}${pluginPath}?${queryParams.toString()}`;
|
|
171
|
+
return ctx.redirect(redirectUrl);
|
|
172
|
+
}
|
|
134
173
|
|
|
135
174
|
ctx.body = { data: result };
|
|
136
175
|
} catch (error) {
|
package/server/routes/index.js
CHANGED
|
@@ -82,6 +82,15 @@ module.exports = {
|
|
|
82
82
|
"content-api": {
|
|
83
83
|
type: "content-api",
|
|
84
84
|
routes: [
|
|
85
|
+
{
|
|
86
|
+
method: "GET",
|
|
87
|
+
path: "/settings",
|
|
88
|
+
handler: "payone.getPublicSettings",
|
|
89
|
+
config: {
|
|
90
|
+
policies: ["plugin::strapi-plugin-payone-provider.is-auth"],
|
|
91
|
+
auth: false
|
|
92
|
+
}
|
|
93
|
+
},
|
|
85
94
|
{
|
|
86
95
|
method: "POST",
|
|
87
96
|
path: "/preauthorization",
|
|
@@ -219,36 +219,48 @@ const refund = async (strapi, params) => {
|
|
|
219
219
|
/**
|
|
220
220
|
* Handle 3D Secure callback from Payone
|
|
221
221
|
* This processes the callback after customer completes 3DS authentication
|
|
222
|
+
* Note: Payone's redirect callback typically doesn't include transaction details -
|
|
223
|
+
* the URL path (success/error/back) indicates the result.
|
|
222
224
|
* @param {Object} strapi - Strapi instance
|
|
223
|
-
* @param {Object} callbackData - Callback data from Payone
|
|
225
|
+
* @param {Object} callbackData - Callback data from Payone (may be empty or minimal)
|
|
226
|
+
* @param {string} resultType - Result type from URL path: 'success', 'error', 'cancelled', or 'callback'
|
|
224
227
|
* @returns {Promise<Object>} Processed callback result
|
|
225
228
|
*/
|
|
226
|
-
const handle3DSCallback = async (strapi, callbackData) => {
|
|
229
|
+
const handle3DSCallback = async (strapi, callbackData, resultType = 'callback') => {
|
|
227
230
|
try {
|
|
228
|
-
|
|
231
|
+
// Parse any data that Payone might have sent
|
|
232
|
+
const parsedData = callbackData && Object.keys(callbackData).length > 0
|
|
233
|
+
? parseResponse(callbackData, strapi.log)
|
|
234
|
+
: {};
|
|
229
235
|
|
|
230
|
-
// Extract transaction information
|
|
236
|
+
// Extract transaction information if available
|
|
231
237
|
const txid = extractTxId(parsedData);
|
|
232
|
-
const status = parsedData.status || parsedData.Status || "unknown";
|
|
233
238
|
const reference = parsedData.reference || parsedData.Reference || null;
|
|
234
239
|
|
|
235
|
-
//
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
240
|
+
// Determine status from resultType (URL path) since Payone callback may not include status
|
|
241
|
+
let status;
|
|
242
|
+
if (resultType === 'success') {
|
|
243
|
+
status = 'APPROVED';
|
|
244
|
+
} else if (resultType === 'error') {
|
|
245
|
+
status = 'ERROR';
|
|
246
|
+
} else if (resultType === 'cancelled') {
|
|
247
|
+
status = 'CANCELLED';
|
|
248
|
+
} else {
|
|
249
|
+
// Fallback to parsed data if available
|
|
250
|
+
status = parsedData.status || parsedData.Status || 'PENDING';
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Log for debugging purposes only (not saved to transaction history)
|
|
254
|
+
strapi.log.info("3DS callback processed:", {
|
|
255
|
+
resultType,
|
|
256
|
+
status,
|
|
257
|
+
txid,
|
|
258
|
+
reference,
|
|
259
|
+
callbackData
|
|
248
260
|
});
|
|
249
261
|
|
|
250
262
|
return {
|
|
251
|
-
success:
|
|
263
|
+
success: resultType === 'success',
|
|
252
264
|
status: status,
|
|
253
265
|
txid: txid,
|
|
254
266
|
reference: reference,
|
|
@@ -50,7 +50,7 @@ module.exports = ({ strapi }) => ({
|
|
|
50
50
|
},
|
|
51
51
|
|
|
52
52
|
// 3D Secure callback handler
|
|
53
|
-
async handle3DSCallback(callbackData) {
|
|
54
|
-
return await paymentService.handle3DSCallback(strapi, callbackData);
|
|
53
|
+
async handle3DSCallback(callbackData, resultType) {
|
|
54
|
+
return await paymentService.handle3DSCallback(strapi, callbackData, resultType);
|
|
55
55
|
}
|
|
56
56
|
});
|