strapi-plugin-payone-provider 4.6.9 → 5.6.10
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 +156 -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 -162
- 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 +24 -71
- 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 -70
- 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 +105 -108
- 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 -26
- package/admin/src/pages/utils/tooltipHelpers.js +18 -0
- package/admin/src/pages/utils/transactionTableUtils.js +60 -0
- package/package.json +8 -14
- package/server/config/index.js +18 -2
- package/server/controllers/payone.js +98 -31
- package/server/policies/index.js +2 -1
- package/server/policies/is-auth.js +9 -3
- package/server/policies/is-payone-notification.js +31 -0
- package/server/policies/isSuperAdmin.js +7 -5
- package/server/routes/index.js +11 -0
- package/server/services/paymentService.js +6 -22
- package/server/services/payone.js +10 -3
- package/server/services/settingsService.js +13 -3
- package/server/services/testConnectionService.js +11 -73
- package/server/services/transactionService.js +62 -99
- package/server/services/transactionStatusService.js +87 -0
- package/server/utils/normalize.js +0 -12
- package/server/utils/paymentMethodParams.js +0 -1
- package/server/utils/requestBuilder.js +34 -5
- 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/CustomerInfoPopover.jsx +0 -147
- package/admin/src/pages/App/components/HistoryPanel.jsx +0 -94
- package/admin/src/pages/App/components/PaymentActionsPanel.jsx +0 -280
- package/admin/src/pages/App/components/RawDataPopover.jsx +0 -113
- package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTableFilters.jsx +0 -113
- package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTablePagination.jsx +0 -180
- package/admin/src/pages/App/components/TransactionHistoryTable/index.jsx +0 -225
- 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
|
@@ -9,18 +9,15 @@ export function getValidCardExpiryDate(cardexpiredate) {
|
|
|
9
9
|
return `${nextYear}${monthStr}`;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
// Validate format (must be 4 digits)
|
|
13
12
|
if (!/^\d{4}$/.test(cardexpiredate)) {
|
|
14
13
|
const nextYear = currentYear + 1;
|
|
15
14
|
const monthStr = String(currentMonth).padStart(2, '0');
|
|
16
15
|
return `${nextYear}${monthStr}`;
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
// Parse YYMM format
|
|
20
18
|
const year = parseInt(cardexpiredate.substring(0, 2), 10);
|
|
21
19
|
const month = parseInt(cardexpiredate.substring(2, 4), 10);
|
|
22
20
|
|
|
23
|
-
// Validate month (1-12)
|
|
24
21
|
if (month < 1 || month > 12) {
|
|
25
22
|
const nextYear = currentYear + 1;
|
|
26
23
|
const monthStr = String(currentMonth).padStart(2, '0');
|
|
@@ -92,7 +89,6 @@ export const getBaseParams = (options = {}) => {
|
|
|
92
89
|
currency: currency.toUpperCase(),
|
|
93
90
|
reference: reference || `REF-${Date.now()}`,
|
|
94
91
|
customerid: finalCustomerId,
|
|
95
|
-
|
|
96
92
|
firstname,
|
|
97
93
|
lastname,
|
|
98
94
|
street,
|
|
@@ -100,16 +96,12 @@ export const getBaseParams = (options = {}) => {
|
|
|
100
96
|
city,
|
|
101
97
|
country: country.toUpperCase(),
|
|
102
98
|
email,
|
|
103
|
-
|
|
104
|
-
// Additional customer details
|
|
105
99
|
salutation,
|
|
106
100
|
gender,
|
|
107
101
|
telephonenumber,
|
|
108
102
|
ip,
|
|
109
103
|
customer_is_present,
|
|
110
104
|
language,
|
|
111
|
-
|
|
112
|
-
// URL parameters (required for redirect-based payments)
|
|
113
105
|
successurl,
|
|
114
106
|
errorurl,
|
|
115
107
|
backurl
|
|
@@ -128,14 +120,12 @@ export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
|
128
120
|
iban,
|
|
129
121
|
bic,
|
|
130
122
|
bankaccountholder,
|
|
131
|
-
// Shipping address for wallet payments (Google Pay, Apple Pay, PayPal)
|
|
132
123
|
shipping_firstname,
|
|
133
124
|
shipping_lastname,
|
|
134
125
|
shipping_street,
|
|
135
126
|
shipping_zip,
|
|
136
127
|
shipping_city,
|
|
137
128
|
shipping_country,
|
|
138
|
-
// Billing address (used as fallback for shipping)
|
|
139
129
|
firstname,
|
|
140
130
|
lastname,
|
|
141
131
|
street,
|
|
@@ -144,10 +134,8 @@ export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
|
144
134
|
country
|
|
145
135
|
} = options;
|
|
146
136
|
|
|
147
|
-
// Use cardtype if provided, otherwise fall back to cardType, otherwise default to "V"
|
|
148
137
|
const finalCardType = cardtype || cardType || "V";
|
|
149
138
|
|
|
150
|
-
// Helper to get shipping params for wallet payments
|
|
151
139
|
const getShippingParams = () => ({
|
|
152
140
|
shipping_firstname: shipping_firstname || firstname || "John",
|
|
153
141
|
shipping_lastname: shipping_lastname || lastname || "Doe",
|
|
@@ -158,19 +146,19 @@ export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
|
158
146
|
});
|
|
159
147
|
|
|
160
148
|
switch (paymentMethod) {
|
|
161
|
-
case "cc":
|
|
149
|
+
case "cc":
|
|
162
150
|
return {
|
|
163
151
|
clearingtype: "cc",
|
|
164
|
-
cardtype: finalCardType,
|
|
165
|
-
cardpan: cardpan || "4111111111111111",
|
|
152
|
+
cardtype: finalCardType,
|
|
153
|
+
cardpan: cardpan || "4111111111111111",
|
|
166
154
|
cardexpiredate: getValidCardExpiryDate(cardexpiredate),
|
|
167
|
-
cardcvc2: cardcvc2 || "123"
|
|
155
|
+
cardcvc2: cardcvc2 || "123"
|
|
168
156
|
};
|
|
169
157
|
|
|
170
|
-
case "wlt":
|
|
158
|
+
case "wlt":
|
|
171
159
|
return {
|
|
172
160
|
clearingtype: "wlt",
|
|
173
|
-
wallettype: "PPE",
|
|
161
|
+
wallettype: "PPE",
|
|
174
162
|
...getShippingParams()
|
|
175
163
|
};
|
|
176
164
|
|
|
@@ -194,10 +182,10 @@ export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
|
194
182
|
|
|
195
183
|
return googlePayParams;
|
|
196
184
|
|
|
197
|
-
case "apl":
|
|
185
|
+
case "apl":
|
|
198
186
|
const applePayParams = {
|
|
199
187
|
clearingtype: "wlt",
|
|
200
|
-
wallettype: "APL",
|
|
188
|
+
wallettype: "APL",
|
|
201
189
|
...getShippingParams()
|
|
202
190
|
};
|
|
203
191
|
|
|
@@ -214,24 +202,23 @@ export const getPaymentMethodParams = (paymentMethod, options = {}) => {
|
|
|
214
202
|
|
|
215
203
|
return applePayParams;
|
|
216
204
|
|
|
217
|
-
case "sb":
|
|
205
|
+
case "sb":
|
|
218
206
|
return {
|
|
219
207
|
clearingtype: "sb",
|
|
220
208
|
bankcountry: "DE",
|
|
221
|
-
onlinebanktransfertype: "PNT"
|
|
209
|
+
onlinebanktransfertype: "PNT"
|
|
222
210
|
};
|
|
223
211
|
|
|
224
|
-
case "elv":
|
|
212
|
+
case "elv":
|
|
225
213
|
return {
|
|
226
214
|
clearingtype: "elv",
|
|
227
215
|
bankcountry: "DE",
|
|
228
|
-
iban: iban || "DE89370400440532013000",
|
|
229
|
-
bic: bic || "COBADEFFXXX",
|
|
216
|
+
iban: iban || "DE89370400440532013000",
|
|
217
|
+
bic: bic || "COBADEFFXXX",
|
|
230
218
|
bankaccountholder: bankaccountholder || "John Doe"
|
|
231
219
|
};
|
|
232
220
|
|
|
233
221
|
default:
|
|
234
|
-
// Default to credit card for unknown payment methods
|
|
235
222
|
return {
|
|
236
223
|
clearingtype: "cc",
|
|
237
224
|
cardtype: "V",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
export const shouldShowTooltip = (inputType, tooltipContent) => {
|
|
3
|
+
if (!tooltipContent) {
|
|
4
|
+
return false;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const inputTypesWithTooltip = ["switch", "toggle", "checkbox", "textarea"];
|
|
8
|
+
|
|
9
|
+
return inputTypesWithTooltip.includes(inputType);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const getTooltipProps = (tooltipContent) => {
|
|
14
|
+
return {
|
|
15
|
+
label: tooltipContent,
|
|
16
|
+
position: "top",
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -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.10",
|
|
4
4
|
"description": "Strapi plugin for Payone payment gateway integration",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"maintainers": [
|
|
@@ -10,23 +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
|
-
"prop-types": "^15.7.2"
|
|
16
|
-
"@uiw/react-json-view": "^2.0.0-alpha.40"
|
|
17
|
-
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"react": "^18.2.0",
|
|
20
|
-
"react-dom": "^18.2.0",
|
|
21
|
-
"react-router-dom": "^5.3.4",
|
|
22
|
-
"styled-components": "^5.3.6"
|
|
16
|
+
"prop-types": "^15.7.2"
|
|
23
17
|
},
|
|
24
18
|
"peerDependencies": {
|
|
25
|
-
"@strapi/strapi": "^
|
|
26
|
-
"react": "^
|
|
27
|
-
"react-dom": "^
|
|
28
|
-
"react-router-dom": "^
|
|
29
|
-
"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"
|
|
30
24
|
},
|
|
31
25
|
"engines": {
|
|
32
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, " +
|
|
@@ -246,5 +295,23 @@ module.exports = ({ strapi }) => ({
|
|
|
246
295
|
}
|
|
247
296
|
};
|
|
248
297
|
}
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
async handleTransactionStatus(ctx) {
|
|
301
|
+
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`);
|
|
309
|
+
} catch (error) {
|
|
310
|
+
console.log("[Payone TransactionStatus] Error handling notification:", error);
|
|
311
|
+
ctx.status = 200;
|
|
312
|
+
ctx.body = "TSOK";
|
|
313
|
+
ctx.type = "text/plain";
|
|
314
|
+
}
|
|
249
315
|
}
|
|
316
|
+
|
|
250
317
|
});
|
package/server/policies/index.js
CHANGED
|
@@ -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
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
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 || "";
|
|
7
|
+
|
|
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
|
+
}
|
|
18
|
+
|
|
19
|
+
if (ip === "54.246.203.105") {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
if (!isValidIp(clientIp)) {
|
|
26
|
+
console.log(`[Payone TransactionStatus] Invalid IP address: ${clientIp}, User-Agent: ${userAgent}`);
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
};
|
|
@@ -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
|
};
|
package/server/routes/index.js
CHANGED
|
@@ -162,6 +162,17 @@ module.exports = {
|
|
|
162
162
|
auth: false
|
|
163
163
|
}
|
|
164
164
|
},
|
|
165
|
+
|
|
166
|
+
{
|
|
167
|
+
method: "POST",
|
|
168
|
+
path: "/transaction-status",
|
|
169
|
+
handler: "payone.handleTransactionStatus",
|
|
170
|
+
config: {
|
|
171
|
+
policies: ["plugin::strapi-plugin-payone-provider.is-payone-notification"],
|
|
172
|
+
auth: false
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
|
|
165
176
|
]
|
|
166
177
|
}
|
|
167
178
|
};
|