strapi-plugin-payone-provider 1.6.7 → 5.6.9
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 +24 -11
- package/admin/src/components/Initializer/index.jsx +3 -3
- package/admin/src/components/PluginIcon/index.jsx +3 -3
- package/admin/src/index.js +33 -11
- package/admin/src/pages/App/components/AppHeader.jsx +17 -32
- package/admin/src/pages/App/components/AppTabs.jsx +36 -156
- package/admin/src/pages/App/components/ApplePayBtn.jsx +9 -11
- package/admin/src/pages/App/components/ApplePayConfig.jsx +221 -161
- package/admin/src/pages/App/components/ApplePayConfigPanel.jsx +33 -45
- package/admin/src/pages/App/components/DocsPanel.jsx +66 -1726
- package/admin/src/pages/App/components/GooglePayConfig.jsx +136 -169
- package/admin/src/pages/App/components/GooglePayConfigPanel.jsx +37 -55
- package/admin/src/pages/App/components/GooglePaybutton.jsx +101 -43
- package/admin/src/pages/App/components/RenderInput.jsx +94 -0
- package/admin/src/pages/App/components/StatusBadge.jsx +27 -16
- package/admin/src/pages/App/components/configuration/ConfigurationFields.jsx +255 -0
- package/admin/src/pages/App/components/configuration/ConfigurationPanel.jsx +54 -0
- package/admin/src/pages/App/components/configuration/TestConnection.jsx +130 -0
- package/admin/src/pages/App/components/docs/ApplePaySection.jsx +260 -0
- package/admin/src/pages/App/components/docs/BaseUrlSection.jsx +53 -0
- package/admin/src/pages/App/components/docs/CaptureRefundSection.jsx +113 -0
- package/admin/src/pages/App/components/docs/CodeBlock.jsx +59 -0
- package/admin/src/pages/App/components/docs/CreditCardSection.jsx +93 -0
- package/admin/src/pages/App/components/docs/GooglePaySection.jsx +248 -0
- package/admin/src/pages/App/components/docs/PayPalSection.jsx +116 -0
- package/admin/src/pages/App/components/docs/PaymentMethodsSection.jsx +55 -0
- package/admin/src/pages/App/components/docs/TableOfContents.jsx +47 -0
- package/admin/src/pages/App/components/docs/TestCredentialsSection.jsx +304 -0
- package/admin/src/pages/App/components/docs/ThreeDSecureSection.jsx +188 -0
- package/admin/src/pages/App/components/icons/BankIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/ChevronDownIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/ChevronUpIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/CreditCardIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/ErrorIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/InfoIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/MarkCircle.jsx +19 -0
- package/admin/src/pages/App/components/icons/PaymentIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/PendingIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/PersonIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/SuccessIcon.jsx +1 -1
- package/admin/src/pages/App/components/icons/WalletIcon.jsx +1 -1
- package/admin/src/pages/App/components/payment-actions/ApplePayPanel.jsx +51 -0
- package/admin/src/pages/App/components/payment-actions/AuthorizationForm.jsx +341 -0
- package/admin/src/pages/App/components/payment-actions/CaptureForm.jsx +128 -0
- package/admin/src/pages/App/components/{paymentActions → payment-actions}/CardDetailsInput.jsx +77 -72
- package/admin/src/pages/App/components/payment-actions/PaymentActionsPanel.jsx +194 -0
- package/admin/src/pages/App/components/payment-actions/PaymentMethodSelector.jsx +313 -0
- package/admin/src/pages/App/components/payment-actions/PaymentResult.jsx +133 -0
- package/admin/src/pages/App/components/payment-actions/PreauthorizationForm.jsx +280 -0
- package/admin/src/pages/App/components/payment-actions/RefundForm.jsx +121 -0
- package/admin/src/pages/App/components/transaction-history/FiltersPanel.jsx +145 -0
- package/admin/src/pages/App/components/transaction-history/HistoryPanel.jsx +50 -0
- package/admin/src/pages/App/components/transaction-history/TransactionTable.jsx +163 -0
- package/admin/src/pages/App/components/transaction-history/details/TransactionDetails.jsx +156 -0
- package/admin/src/pages/App/components/{TransactionHistoryItem.jsx → transaction-history/details/TransactionHistoryItem.jsx} +16 -28
- package/admin/src/pages/App/index.jsx +27 -67
- package/admin/src/pages/App/styles.css +46 -169
- package/admin/src/pages/constants/paymentConstants.js +52 -16
- package/admin/src/pages/hooks/use-system-theme.js +27 -0
- package/admin/src/pages/hooks/usePaymentActions.js +273 -210
- package/admin/src/pages/hooks/useSettings.js +87 -48
- package/admin/src/pages/hooks/useTransactionHistory.js +109 -47
- package/admin/src/pages/utils/api.js +57 -72
- package/admin/src/pages/utils/applePayConstants.js +2 -28
- package/admin/src/pages/utils/countryLanguageUtils.js +280 -0
- package/admin/src/pages/utils/getInputComponent.jsx +225 -0
- package/admin/src/pages/utils/googlePayConstants.js +2 -9
- package/admin/src/pages/utils/paymentUtils.js +13 -25
- package/admin/src/pages/utils/tooltipHelpers.js +18 -0
- package/admin/src/pages/utils/transactionTableUtils.js +60 -0
- package/package.json +7 -12
- package/server/config/index.js +18 -2
- package/server/controllers/payone.js +80 -31
- package/server/policies/is-auth.js +9 -3
- package/server/policies/isSuperAdmin.js +7 -5
- package/server/services/paymentService.js +6 -22
- package/server/services/payone.js +3 -3
- package/server/services/settingsService.js +13 -3
- package/server/services/testConnectionService.js +11 -73
- package/server/services/transactionService.js +61 -32
- package/server/utils/normalize.js +0 -12
- package/server/utils/paymentMethodParams.js +0 -1
- package/server/utils/responseParser.js +9 -14
- package/strapi-admin.js +3 -1
- package/admin/src/pages/App/components/ConfigurationPanel.jsx +0 -517
- package/admin/src/pages/App/components/HistoryPanel.jsx +0 -312
- package/admin/src/pages/App/components/PaymentActionsPanel.jsx +0 -280
- package/admin/src/pages/App/components/paymentActions/ApplePayPanel.jsx +0 -95
- package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +0 -197
- package/admin/src/pages/App/components/paymentActions/CaptureForm.jsx +0 -65
- package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.jsx +0 -306
- package/admin/src/pages/App/components/paymentActions/PaymentResult.jsx +0 -192
- package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +0 -142
- package/admin/src/pages/App/components/paymentActions/RefundForm.jsx +0 -90
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
export const getStatusColor = (status) => {
|
|
3
|
+
switch (status) {
|
|
4
|
+
case "APPROVED":
|
|
5
|
+
return "success200";
|
|
6
|
+
case "ERROR":
|
|
7
|
+
return "danger200";
|
|
8
|
+
case "PENDING":
|
|
9
|
+
return "warning200";
|
|
10
|
+
case "REDIRECT":
|
|
11
|
+
return "success100";
|
|
12
|
+
default:
|
|
13
|
+
return "success100";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const formatAmount = (amount, currency) => {
|
|
18
|
+
if (!amount) return "N/A";
|
|
19
|
+
return `${(amount / 100).toFixed(2)} ${currency || "EUR"}`;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const formatDate = (dateString) => {
|
|
23
|
+
if (!dateString) return "N/A";
|
|
24
|
+
return new Date(dateString).toLocaleString("en-US", {
|
|
25
|
+
year: "numeric",
|
|
26
|
+
month: "2-digit",
|
|
27
|
+
day: "2-digit",
|
|
28
|
+
hour: "2-digit",
|
|
29
|
+
minute: "2-digit",
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const getPaymentMethodName = (clearingtype, wallettype) => {
|
|
34
|
+
switch (clearingtype) {
|
|
35
|
+
case "cc":
|
|
36
|
+
return "Credit Card";
|
|
37
|
+
case "sb":
|
|
38
|
+
return "Online Banking";
|
|
39
|
+
case "wlt":
|
|
40
|
+
return wallettype === "PPE" ? "PayPal" : "Wallet";
|
|
41
|
+
case "elv":
|
|
42
|
+
return "Direct Debit (SEPA)";
|
|
43
|
+
default:
|
|
44
|
+
return clearingtype || "Unknown";
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const getCardTypeName = (cardtype) => {
|
|
49
|
+
switch (cardtype) {
|
|
50
|
+
case "V":
|
|
51
|
+
return "Visa";
|
|
52
|
+
case "M":
|
|
53
|
+
return "Mastercard";
|
|
54
|
+
case "A":
|
|
55
|
+
return "American Express";
|
|
56
|
+
default:
|
|
57
|
+
return cardtype || "Unknown";
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strapi-plugin-payone-provider",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.6.9",
|
|
4
4
|
"description": "Strapi plugin for Payone payment gateway integration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"maintainers": [
|
|
@@ -10,22 +10,17 @@
|
|
|
10
10
|
}
|
|
11
11
|
],
|
|
12
12
|
"dependencies": {
|
|
13
|
+
"@uiw/react-json-view": "^2.0.0-alpha.40",
|
|
13
14
|
"apple-pay-button": "^1.2.1",
|
|
14
15
|
"axios": "^1.6.3",
|
|
15
16
|
"prop-types": "^15.7.2"
|
|
16
17
|
},
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"react": "^18.2.0",
|
|
19
|
-
"react-dom": "^18.2.0",
|
|
20
|
-
"react-router-dom": "^5.3.4",
|
|
21
|
-
"styled-components": "^5.3.6"
|
|
22
|
-
},
|
|
23
18
|
"peerDependencies": {
|
|
24
|
-
"@strapi/strapi": "^
|
|
25
|
-
"react": "^
|
|
26
|
-
"react-dom": "^
|
|
27
|
-
"react-router-dom": "^
|
|
28
|
-
"styled-components": "^
|
|
19
|
+
"@strapi/strapi": "^5.0.0",
|
|
20
|
+
"react": "^18.0.0",
|
|
21
|
+
"react-dom": "^18.0.0",
|
|
22
|
+
"react-router-dom": "^6.0.0",
|
|
23
|
+
"styled-components": "^6.0.0"
|
|
29
24
|
},
|
|
30
25
|
"engines": {
|
|
31
26
|
"node": ">=18.0.0",
|
package/server/config/index.js
CHANGED
|
@@ -14,7 +14,13 @@ module.exports = {
|
|
|
14
14
|
merchantName: "",
|
|
15
15
|
displayName: "",
|
|
16
16
|
domainName: "",
|
|
17
|
-
merchantIdentifier: ""
|
|
17
|
+
merchantIdentifier: "",
|
|
18
|
+
enableCreditCard: false,
|
|
19
|
+
enablePayPal: false,
|
|
20
|
+
enableGooglePay: false,
|
|
21
|
+
enableApplePay: false,
|
|
22
|
+
enableSofort: false,
|
|
23
|
+
enableSepaDirectDebit: false
|
|
18
24
|
}
|
|
19
25
|
},
|
|
20
26
|
validator(config) {
|
|
@@ -33,7 +39,17 @@ module.exports = {
|
|
|
33
39
|
api_version: yup
|
|
34
40
|
.string()
|
|
35
41
|
.matches(/^\d+\.\d+$/)
|
|
36
|
-
.defined()
|
|
42
|
+
.defined(),
|
|
43
|
+
merchantName: yup.string().optional(),
|
|
44
|
+
displayName: yup.string().optional(),
|
|
45
|
+
domainName: yup.string().optional(),
|
|
46
|
+
merchantIdentifier: yup.string().optional(),
|
|
47
|
+
enableCreditCard: yup.boolean().optional(),
|
|
48
|
+
enablePayPal: yup.boolean().optional(),
|
|
49
|
+
enableGooglePay: yup.boolean().optional(),
|
|
50
|
+
enableApplePay: yup.boolean().optional(),
|
|
51
|
+
enableSofort: yup.boolean().optional(),
|
|
52
|
+
enableSepaDirectDebit: yup.boolean().optional()
|
|
37
53
|
})
|
|
38
54
|
.defined()
|
|
39
55
|
});
|
|
@@ -7,13 +7,25 @@ const getPayoneService = (strapi) => {
|
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
const handleError = (ctx, error) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const status = error.status || error.response?.status || 500;
|
|
11
|
+
const message = error.message || "Internal server error";
|
|
12
|
+
|
|
13
|
+
if (status >= 400) {
|
|
14
|
+
console.log("[Payone] Controller error:", {
|
|
15
|
+
status,
|
|
16
|
+
message,
|
|
17
|
+
error: error.stack || error
|
|
14
18
|
});
|
|
15
19
|
}
|
|
16
|
-
|
|
20
|
+
|
|
21
|
+
ctx.status = status;
|
|
22
|
+
ctx.body = {
|
|
23
|
+
error: {
|
|
24
|
+
status,
|
|
25
|
+
message,
|
|
26
|
+
name: error.name || "Error"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
17
29
|
};
|
|
18
30
|
|
|
19
31
|
const hideKey = (settings) => {
|
|
@@ -27,7 +39,9 @@ module.exports = ({ strapi }) => ({
|
|
|
27
39
|
async getSettings(ctx) {
|
|
28
40
|
try {
|
|
29
41
|
const settings = await getPayoneService(strapi).getSettings();
|
|
30
|
-
ctx.body = {
|
|
42
|
+
ctx.body = {
|
|
43
|
+
...hideKey(settings || {})
|
|
44
|
+
};
|
|
31
45
|
} catch (error) {
|
|
32
46
|
handleError(ctx, error);
|
|
33
47
|
}
|
|
@@ -62,15 +76,20 @@ module.exports = ({ strapi }) => ({
|
|
|
62
76
|
|
|
63
77
|
async updateSettings(ctx) {
|
|
64
78
|
try {
|
|
65
|
-
const
|
|
79
|
+
const bodyData = ctx.request.body?.data || ctx.request.body;
|
|
80
|
+
|
|
81
|
+
if (!bodyData || typeof bodyData !== 'object') {
|
|
82
|
+
ctx.throw(400, "Invalid request body");
|
|
83
|
+
}
|
|
84
|
+
|
|
66
85
|
const currentSettings = await getPayoneService(strapi).getSettings();
|
|
67
86
|
|
|
68
|
-
if (
|
|
69
|
-
|
|
87
|
+
if (bodyData.key === "***HIDDEN***" || !bodyData.key) {
|
|
88
|
+
bodyData.key = currentSettings?.key;
|
|
70
89
|
}
|
|
71
90
|
|
|
72
|
-
const settings = await getPayoneService(strapi).updateSettings(
|
|
73
|
-
ctx.body = {
|
|
91
|
+
const settings = await getPayoneService(strapi).updateSettings(bodyData);
|
|
92
|
+
ctx.body = { ...hideKey(settings) };
|
|
74
93
|
} catch (error) {
|
|
75
94
|
handleError(ctx, error);
|
|
76
95
|
}
|
|
@@ -78,9 +97,13 @@ module.exports = ({ strapi }) => ({
|
|
|
78
97
|
|
|
79
98
|
async preauthorization(ctx) {
|
|
80
99
|
try {
|
|
81
|
-
const params = ctx.request.body;
|
|
100
|
+
const params = ctx.request.body?.data || ctx.request.body;
|
|
101
|
+
if (!params || typeof params !== 'object') {
|
|
102
|
+
ctx.throw(400, "Invalid request body");
|
|
103
|
+
}
|
|
104
|
+
|
|
82
105
|
const result = await getPayoneService(strapi).preauthorization(params);
|
|
83
|
-
ctx.body =
|
|
106
|
+
ctx.body = result;
|
|
84
107
|
} catch (error) {
|
|
85
108
|
handleError(ctx, error);
|
|
86
109
|
}
|
|
@@ -88,9 +111,14 @@ module.exports = ({ strapi }) => ({
|
|
|
88
111
|
|
|
89
112
|
async authorization(ctx) {
|
|
90
113
|
try {
|
|
91
|
-
const params = ctx.request.body;
|
|
114
|
+
const params = ctx.request.body?.data || ctx.request.body;
|
|
115
|
+
|
|
116
|
+
if (!params || typeof params !== 'object') {
|
|
117
|
+
ctx.throw(400, "Invalid request body");
|
|
118
|
+
}
|
|
119
|
+
|
|
92
120
|
const result = await getPayoneService(strapi).authorization(params);
|
|
93
|
-
ctx.body =
|
|
121
|
+
ctx.body = result;
|
|
94
122
|
} catch (error) {
|
|
95
123
|
handleError(ctx, error);
|
|
96
124
|
}
|
|
@@ -98,9 +126,14 @@ module.exports = ({ strapi }) => ({
|
|
|
98
126
|
|
|
99
127
|
async capture(ctx) {
|
|
100
128
|
try {
|
|
101
|
-
const params = ctx.request.body;
|
|
129
|
+
const params = ctx.request.body?.data || ctx.request.body;
|
|
130
|
+
|
|
131
|
+
if (!params || typeof params !== 'object') {
|
|
132
|
+
ctx.throw(400, "Invalid request body");
|
|
133
|
+
}
|
|
134
|
+
|
|
102
135
|
const result = await getPayoneService(strapi).capture(params);
|
|
103
|
-
ctx.body =
|
|
136
|
+
ctx.body = result;
|
|
104
137
|
} catch (error) {
|
|
105
138
|
handleError(ctx, error);
|
|
106
139
|
}
|
|
@@ -108,9 +141,14 @@ module.exports = ({ strapi }) => ({
|
|
|
108
141
|
|
|
109
142
|
async refund(ctx) {
|
|
110
143
|
try {
|
|
111
|
-
const params = ctx.request.body;
|
|
144
|
+
const params = ctx.request.body?.data || ctx.request.body;
|
|
145
|
+
|
|
146
|
+
if (!params || typeof params !== 'object') {
|
|
147
|
+
ctx.throw(400, "Invalid request body");
|
|
148
|
+
}
|
|
149
|
+
|
|
112
150
|
const result = await getPayoneService(strapi).refund(params);
|
|
113
|
-
ctx.body =
|
|
151
|
+
ctx.body = result;
|
|
114
152
|
} catch (error) {
|
|
115
153
|
handleError(ctx, error);
|
|
116
154
|
}
|
|
@@ -118,9 +156,21 @@ module.exports = ({ strapi }) => ({
|
|
|
118
156
|
|
|
119
157
|
async getTransactionHistory(ctx) {
|
|
120
158
|
try {
|
|
121
|
-
const filters = ctx.query || {};
|
|
122
|
-
const
|
|
123
|
-
|
|
159
|
+
const { filters = {}, pagination = {} } = ctx.query || {};
|
|
160
|
+
const page = parseInt(pagination.page || "1", 10);
|
|
161
|
+
const pageSize = parseInt(pagination.pageSize || "10", 10);
|
|
162
|
+
|
|
163
|
+
const result = await getPayoneService(strapi).getTransactionHistory({
|
|
164
|
+
filters: filters || {},
|
|
165
|
+
pagination: { page, pageSize }
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
ctx.body = {
|
|
169
|
+
data: result.data || [],
|
|
170
|
+
meta: {
|
|
171
|
+
pagination: result.pagination
|
|
172
|
+
},
|
|
173
|
+
};
|
|
124
174
|
} catch (error) {
|
|
125
175
|
handleError(ctx, error);
|
|
126
176
|
}
|
|
@@ -129,7 +179,7 @@ module.exports = ({ strapi }) => ({
|
|
|
129
179
|
async testConnection(ctx) {
|
|
130
180
|
try {
|
|
131
181
|
const result = await getPayoneService(strapi).testConnection();
|
|
132
|
-
ctx.body =
|
|
182
|
+
ctx.body = result || {};
|
|
133
183
|
} catch (error) {
|
|
134
184
|
handleError(ctx, error);
|
|
135
185
|
}
|
|
@@ -149,7 +199,10 @@ module.exports = ({ strapi }) => ({
|
|
|
149
199
|
resultType = "cancelled";
|
|
150
200
|
}
|
|
151
201
|
|
|
152
|
-
const callbackData = isGetRequest
|
|
202
|
+
const callbackData = isGetRequest
|
|
203
|
+
? ctx.query
|
|
204
|
+
: (ctx.request.body || ctx.request.body?.data || ctx.request?.data);
|
|
205
|
+
|
|
153
206
|
const result = await getPayoneService(strapi).handle3DSCallback(callbackData, resultType);
|
|
154
207
|
|
|
155
208
|
if (isGetRequest) {
|
|
@@ -166,7 +219,7 @@ module.exports = ({ strapi }) => ({
|
|
|
166
219
|
return ctx.redirect(redirectUrl);
|
|
167
220
|
}
|
|
168
221
|
|
|
169
|
-
ctx.body =
|
|
222
|
+
ctx.body = result;
|
|
170
223
|
} catch (error) {
|
|
171
224
|
handleError(ctx, error);
|
|
172
225
|
}
|
|
@@ -177,13 +230,12 @@ module.exports = ({ strapi }) => ({
|
|
|
177
230
|
const settings = await getPayoneService(strapi).getSettings();
|
|
178
231
|
const applePayConfig = settings?.applePayConfig || {};
|
|
179
232
|
|
|
180
|
-
const params = ctx.request.body;
|
|
233
|
+
const params = ctx.request.body || ctx.request.body?.data || ctx.request?.data;
|
|
181
234
|
|
|
182
235
|
if (!params) {
|
|
183
236
|
throw new Error("Request body is missing");
|
|
184
237
|
}
|
|
185
238
|
|
|
186
|
-
// Ensure domain is set
|
|
187
239
|
if (!params.domain && !params.domainName) {
|
|
188
240
|
params.domain = ctx.request.hostname || ctx.request.host || 'localhost';
|
|
189
241
|
params.domainName = params.domain;
|
|
@@ -210,11 +262,10 @@ module.exports = ({ strapi }) => ({
|
|
|
210
262
|
throw new Error("Merchant validation returned null. Please check your Payone Apple Pay configuration.");
|
|
211
263
|
}
|
|
212
264
|
|
|
213
|
-
ctx.body =
|
|
265
|
+
ctx.body = result;
|
|
214
266
|
} catch (error) {
|
|
215
267
|
const errorStatus = error.status || (error.message?.includes('403') ? 403 : 500);
|
|
216
268
|
|
|
217
|
-
// Only log if it's a response error
|
|
218
269
|
if (error.response || errorStatus === 403 || errorStatus === 401 || errorStatus >= 500) {
|
|
219
270
|
strapi.log.error("[Apple Pay] Controller error:", {
|
|
220
271
|
status: errorStatus,
|
|
@@ -222,11 +273,9 @@ module.exports = ({ strapi }) => ({
|
|
|
222
273
|
});
|
|
223
274
|
}
|
|
224
275
|
|
|
225
|
-
// Extract detailed error message if available
|
|
226
276
|
let errorMessage = error.message || "Apple Pay merchant validation failed";
|
|
227
277
|
let errorDetails = "Please check your Payone Apple Pay configuration in PMI (CONFIGURATION → PAYMENT PORTALS → [Your Portal] → Apple Pay). Ensure that Merchant ID (mid) is correctly configured and Apple Pay is enabled for your portal.";
|
|
228
278
|
|
|
229
|
-
// If it's a 403 error, provide more specific guidance
|
|
230
279
|
if (errorStatus === 403 || error.message?.includes('403')) {
|
|
231
280
|
errorDetails = "403 Forbidden: Authentication failed with Payone. " +
|
|
232
281
|
"Please check: 1) Your Payone credentials (aid, portalid, mid, key) in plugin settings, " +
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
module.exports = async (
|
|
4
|
-
const { authorization } =
|
|
3
|
+
module.exports = async (policyContext, config, { strapi }) => {
|
|
4
|
+
const { authorization } = policyContext.request.header || {};
|
|
5
5
|
|
|
6
6
|
if (authorization && authorization.startsWith("Bearer ")) {
|
|
7
7
|
const token = authorization.split(" ")[1];
|
|
8
8
|
|
|
9
9
|
try {
|
|
10
|
-
const apiTokenService = strapi.
|
|
10
|
+
const apiTokenService = strapi.service("admin::api-token");
|
|
11
|
+
|
|
12
|
+
if (!apiTokenService) {
|
|
13
|
+
strapi.log.warn("strapi-plugin-payone-provider: api-token service not found");
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
const accessKey = await apiTokenService.hash(token);
|
|
12
18
|
const storedToken = await apiTokenService.getBy({ accessKey });
|
|
13
19
|
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
module.exports = async (
|
|
4
|
-
const adminUser =
|
|
3
|
+
module.exports = async (policyContext, config, { strapi }) => {
|
|
4
|
+
const adminUser = policyContext.state && policyContext.state.user;
|
|
5
5
|
|
|
6
6
|
if (!adminUser) {
|
|
7
|
-
|
|
7
|
+
policyContext.unauthorized("Admin authentication required");
|
|
8
|
+
return false;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
const roles = Array.isArray(adminUser.roles) ? adminUser.roles : [];
|
|
11
12
|
const isSuperAdmin = roles.some((role) => role.code === "strapi-super-admin");
|
|
12
13
|
|
|
13
14
|
if (!isSuperAdmin) {
|
|
14
|
-
|
|
15
|
+
policyContext.forbidden("Only super admins can access this resource");
|
|
16
|
+
return false;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
return
|
|
19
|
+
return true;
|
|
18
20
|
};
|
|
@@ -51,13 +51,7 @@ const sendRequest = async (strapi, params) => {
|
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
const responseData = parseResponse(response.data, strapi.log);
|
|
54
|
-
const errorCode =
|
|
55
|
-
responseData.errorcode ||
|
|
56
|
-
responseData.ErrorCode ||
|
|
57
|
-
responseData.Error?.ErrorCode ||
|
|
58
|
-
responseData.error_code ||
|
|
59
|
-
null;
|
|
60
|
-
|
|
54
|
+
const errorCode = responseData?.Error?.ErrorCode;
|
|
61
55
|
const requires3DSErrorCodes = ["4219", 4219];
|
|
62
56
|
const is3DSRequiredError = requires3DSErrorCodes.includes(errorCode);
|
|
63
57
|
|
|
@@ -69,21 +63,11 @@ const sendRequest = async (strapi, params) => {
|
|
|
69
63
|
|
|
70
64
|
}
|
|
71
65
|
|
|
72
|
-
const errorMessage =
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
null;
|
|
78
|
-
|
|
79
|
-
const customerMessage =
|
|
80
|
-
responseData.customermessage ||
|
|
81
|
-
responseData.CustomerMessage ||
|
|
82
|
-
responseData.Error?.CustomerMessage ||
|
|
83
|
-
responseData.customer_message ||
|
|
84
|
-
null;
|
|
85
|
-
|
|
86
|
-
const status = (responseData.status || responseData.Status || "unknown").toUpperCase();
|
|
66
|
+
const errorMessage = responseData?.Error?.ErrorMessage || null;
|
|
67
|
+
|
|
68
|
+
const customerMessage = responseData?.Error?.CustomerMessage || null;
|
|
69
|
+
|
|
70
|
+
const status = (responseData?.status || responseData?.Status || "unknown").toUpperCase() || null;
|
|
87
71
|
|
|
88
72
|
await logTransaction(strapi, {
|
|
89
73
|
txid: extractTxId(responseData) || params.txid || null,
|
|
@@ -16,7 +16,6 @@ module.exports = ({ strapi }) => ({
|
|
|
16
16
|
return await settingsService.updateSettings(strapi, settings);
|
|
17
17
|
},
|
|
18
18
|
|
|
19
|
-
// Payment operations
|
|
20
19
|
async preauthorization(params) {
|
|
21
20
|
return await paymentService.preauthorization(strapi, params);
|
|
22
21
|
},
|
|
@@ -38,8 +37,9 @@ module.exports = ({ strapi }) => ({
|
|
|
38
37
|
return await transactionService.logTransaction(strapi, transactionData);
|
|
39
38
|
},
|
|
40
39
|
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
|
|
41
|
+
async getTransactionHistory({ filters = {}, pagination = {} }) {
|
|
42
|
+
return await transactionService.getTransactionHistory(strapi, { filters, pagination });
|
|
43
43
|
},
|
|
44
44
|
|
|
45
45
|
// Test connection
|
|
@@ -12,16 +12,26 @@ const getPluginStore = (strapi) => {
|
|
|
12
12
|
|
|
13
13
|
const getSettings = async (strapi) => {
|
|
14
14
|
const pluginStore = getPluginStore(strapi);
|
|
15
|
-
|
|
15
|
+
const settings = await pluginStore.get({ key: "settings" }) || {};
|
|
16
|
+
|
|
17
|
+
return settings;
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
const updateSettings = async (strapi, settings) => {
|
|
19
21
|
const pluginStore = getPluginStore(strapi);
|
|
22
|
+
const currentSettings = await getSettings(strapi) || {};
|
|
23
|
+
const mergedSettings = {
|
|
24
|
+
...currentSettings,
|
|
25
|
+
...settings
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
20
29
|
await pluginStore.set({
|
|
21
30
|
key: "settings",
|
|
22
|
-
value:
|
|
31
|
+
value: mergedSettings
|
|
23
32
|
});
|
|
24
|
-
|
|
33
|
+
|
|
34
|
+
return mergedSettings;
|
|
25
35
|
};
|
|
26
36
|
|
|
27
37
|
const validateSettings = (settings) => {
|
|
@@ -54,82 +54,19 @@ const testConnection = async (strapi) => {
|
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
const result = parseResponse(response.data, strapi.log);
|
|
57
|
-
const status = result
|
|
58
|
-
const errorMessage =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
result.ERRORMESSAGE ||
|
|
62
|
-
result.error ||
|
|
63
|
-
result.Error?.ErrorMessage ||
|
|
64
|
-
"";
|
|
65
|
-
const errorCode =
|
|
66
|
-
result.errorcode ||
|
|
67
|
-
result.Errorcode ||
|
|
68
|
-
result.ERRORCODE ||
|
|
69
|
-
result.Error?.ErrorCode ||
|
|
70
|
-
"";
|
|
71
|
-
const customErrorMessage =
|
|
72
|
-
result.customerrormessage ||
|
|
73
|
-
result.Customerrormessage ||
|
|
74
|
-
result.CUSTOMERRORMESSAGE ||
|
|
75
|
-
result.Error?.CustomerMessage ||
|
|
76
|
-
"";
|
|
57
|
+
const status = result?.status || result?.Status || result?.STATUS;
|
|
58
|
+
const errorMessage = result?.Error?.ErrorMessage;
|
|
59
|
+
const errorCode = result?.Error?.ErrorCode;
|
|
60
|
+
const customErrorMessage = result?.Error?.CustomerMessage;
|
|
77
61
|
|
|
78
62
|
if (status === "ERROR" || status === "error") {
|
|
79
|
-
if (["2006", "920", "921", "922", "401", "403"].includes(errorCode)) {
|
|
80
|
-
return {
|
|
81
|
-
success: false,
|
|
82
|
-
message: `Authentication failed: ${customErrorMessage || errorMessage || "Invalid credentials"}`,
|
|
83
|
-
errorcode: errorCode
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const errorMessageStr = typeof errorMessage === "string" ? errorMessage : JSON.stringify(errorMessage);
|
|
88
|
-
const errorMessageLower = (errorMessageStr || "").toLowerCase();
|
|
89
|
-
const authErrorKeywords = [
|
|
90
|
-
"key incorrect",
|
|
91
|
-
"invalid key",
|
|
92
|
-
"portal key",
|
|
93
|
-
"unauthorized",
|
|
94
|
-
"not authorized",
|
|
95
|
-
"unknown aid",
|
|
96
|
-
"unknown account",
|
|
97
|
-
"unknown portal",
|
|
98
|
-
"unknown merchant",
|
|
99
|
-
"invalid aid",
|
|
100
|
-
"invalid mid",
|
|
101
|
-
"invalid portalid"
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
if (authErrorKeywords.some((keyword) => errorMessageLower.includes(keyword))) {
|
|
105
|
-
return {
|
|
106
|
-
success: false,
|
|
107
|
-
message: `Authentication failed: ${errorMessageStr}`,
|
|
108
|
-
errorcode: errorCode || "AUTH"
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (errorCode === "911") {
|
|
113
|
-
return {
|
|
114
|
-
success: true,
|
|
115
|
-
message: "Connection successful! Your Payone credentials are valid.",
|
|
116
|
-
details: {
|
|
117
|
-
mode: settings.mode,
|
|
118
|
-
aid: settings.aid,
|
|
119
|
-
portalid: settings.portalid,
|
|
120
|
-
mid: settings.mid
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
63
|
return {
|
|
126
64
|
success: false,
|
|
127
|
-
message: `
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
rawResponse: JSON.stringify(result).substring(0, 200)
|
|
65
|
+
message: `Test connection failed: ${errorCode}`,
|
|
66
|
+
error: {
|
|
67
|
+
ErrorCode: errorCode,
|
|
68
|
+
ErrorMessage: errorMessage,
|
|
69
|
+
CustomerMessage: customErrorMessage
|
|
133
70
|
}
|
|
134
71
|
};
|
|
135
72
|
}
|
|
@@ -157,11 +94,12 @@ const testConnection = async (strapi) => {
|
|
|
157
94
|
rawResponse: JSON.stringify(result).substring(0, 200)
|
|
158
95
|
}
|
|
159
96
|
};
|
|
97
|
+
|
|
160
98
|
} catch (error) {
|
|
161
99
|
strapi.log.error("Payone test connection error:", error);
|
|
162
100
|
return {
|
|
163
101
|
success: false,
|
|
164
|
-
message: `
|
|
102
|
+
message: `Test connection error: ${error.message || "Unknown error"}`,
|
|
165
103
|
error: error.toString(),
|
|
166
104
|
details: {
|
|
167
105
|
errorType: error.constructor.name,
|