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.
Files changed (104) hide show
  1. package/README.md +156 -11
  2. package/admin/src/components/Initializer/index.jsx +3 -3
  3. package/admin/src/components/PluginIcon/index.jsx +3 -3
  4. package/admin/src/index.js +33 -11
  5. package/admin/src/pages/App/components/AppHeader.jsx +17 -32
  6. package/admin/src/pages/App/components/AppTabs.jsx +36 -162
  7. package/admin/src/pages/App/components/ApplePayBtn.jsx +9 -11
  8. package/admin/src/pages/App/components/ApplePayConfig.jsx +221 -161
  9. package/admin/src/pages/App/components/ApplePayConfigPanel.jsx +33 -45
  10. package/admin/src/pages/App/components/DocsPanel.jsx +66 -1726
  11. package/admin/src/pages/App/components/GooglePayConfig.jsx +136 -169
  12. package/admin/src/pages/App/components/GooglePayConfigPanel.jsx +37 -55
  13. package/admin/src/pages/App/components/GooglePaybutton.jsx +101 -43
  14. package/admin/src/pages/App/components/RenderInput.jsx +94 -0
  15. package/admin/src/pages/App/components/StatusBadge.jsx +24 -71
  16. package/admin/src/pages/App/components/configuration/ConfigurationFields.jsx +255 -0
  17. package/admin/src/pages/App/components/configuration/ConfigurationPanel.jsx +54 -0
  18. package/admin/src/pages/App/components/configuration/TestConnection.jsx +130 -0
  19. package/admin/src/pages/App/components/docs/ApplePaySection.jsx +260 -0
  20. package/admin/src/pages/App/components/docs/BaseUrlSection.jsx +53 -0
  21. package/admin/src/pages/App/components/docs/CaptureRefundSection.jsx +113 -0
  22. package/admin/src/pages/App/components/docs/CodeBlock.jsx +59 -0
  23. package/admin/src/pages/App/components/docs/CreditCardSection.jsx +93 -0
  24. package/admin/src/pages/App/components/docs/GooglePaySection.jsx +248 -0
  25. package/admin/src/pages/App/components/docs/PayPalSection.jsx +116 -0
  26. package/admin/src/pages/App/components/docs/PaymentMethodsSection.jsx +55 -0
  27. package/admin/src/pages/App/components/docs/TableOfContents.jsx +47 -0
  28. package/admin/src/pages/App/components/docs/TestCredentialsSection.jsx +304 -0
  29. package/admin/src/pages/App/components/docs/ThreeDSecureSection.jsx +188 -0
  30. package/admin/src/pages/App/components/icons/BankIcon.jsx +1 -1
  31. package/admin/src/pages/App/components/icons/ChevronDownIcon.jsx +1 -1
  32. package/admin/src/pages/App/components/icons/ChevronUpIcon.jsx +1 -1
  33. package/admin/src/pages/App/components/icons/CreditCardIcon.jsx +1 -1
  34. package/admin/src/pages/App/components/icons/ErrorIcon.jsx +1 -1
  35. package/admin/src/pages/App/components/icons/InfoIcon.jsx +1 -1
  36. package/admin/src/pages/App/components/icons/MarkCircle.jsx +19 -0
  37. package/admin/src/pages/App/components/icons/PaymentIcon.jsx +1 -1
  38. package/admin/src/pages/App/components/icons/PendingIcon.jsx +1 -1
  39. package/admin/src/pages/App/components/icons/PersonIcon.jsx +1 -1
  40. package/admin/src/pages/App/components/icons/SuccessIcon.jsx +1 -1
  41. package/admin/src/pages/App/components/icons/WalletIcon.jsx +1 -1
  42. package/admin/src/pages/App/components/payment-actions/ApplePayPanel.jsx +51 -0
  43. package/admin/src/pages/App/components/payment-actions/AuthorizationForm.jsx +341 -0
  44. package/admin/src/pages/App/components/payment-actions/CaptureForm.jsx +128 -0
  45. package/admin/src/pages/App/components/{paymentActions → payment-actions}/CardDetailsInput.jsx +77 -72
  46. package/admin/src/pages/App/components/payment-actions/PaymentActionsPanel.jsx +194 -0
  47. package/admin/src/pages/App/components/payment-actions/PaymentMethodSelector.jsx +313 -0
  48. package/admin/src/pages/App/components/payment-actions/PaymentResult.jsx +133 -0
  49. package/admin/src/pages/App/components/payment-actions/PreauthorizationForm.jsx +280 -0
  50. package/admin/src/pages/App/components/payment-actions/RefundForm.jsx +121 -0
  51. package/admin/src/pages/App/components/transaction-history/FiltersPanel.jsx +145 -0
  52. package/admin/src/pages/App/components/transaction-history/HistoryPanel.jsx +50 -0
  53. package/admin/src/pages/App/components/transaction-history/TransactionTable.jsx +163 -0
  54. package/admin/src/pages/App/components/transaction-history/details/TransactionDetails.jsx +156 -0
  55. package/admin/src/pages/App/components/{TransactionHistoryItem.jsx → transaction-history/details/TransactionHistoryItem.jsx} +16 -28
  56. package/admin/src/pages/App/index.jsx +27 -70
  57. package/admin/src/pages/App/styles.css +46 -169
  58. package/admin/src/pages/constants/paymentConstants.js +52 -16
  59. package/admin/src/pages/hooks/use-system-theme.js +27 -0
  60. package/admin/src/pages/hooks/usePaymentActions.js +273 -210
  61. package/admin/src/pages/hooks/useSettings.js +87 -48
  62. package/admin/src/pages/hooks/useTransactionHistory.js +105 -108
  63. package/admin/src/pages/utils/api.js +57 -72
  64. package/admin/src/pages/utils/applePayConstants.js +2 -28
  65. package/admin/src/pages/utils/countryLanguageUtils.js +280 -0
  66. package/admin/src/pages/utils/getInputComponent.jsx +225 -0
  67. package/admin/src/pages/utils/googlePayConstants.js +2 -9
  68. package/admin/src/pages/utils/paymentUtils.js +13 -26
  69. package/admin/src/pages/utils/tooltipHelpers.js +18 -0
  70. package/admin/src/pages/utils/transactionTableUtils.js +60 -0
  71. package/package.json +8 -14
  72. package/server/config/index.js +18 -2
  73. package/server/controllers/payone.js +98 -31
  74. package/server/policies/index.js +2 -1
  75. package/server/policies/is-auth.js +9 -3
  76. package/server/policies/is-payone-notification.js +31 -0
  77. package/server/policies/isSuperAdmin.js +7 -5
  78. package/server/routes/index.js +11 -0
  79. package/server/services/paymentService.js +6 -22
  80. package/server/services/payone.js +10 -3
  81. package/server/services/settingsService.js +13 -3
  82. package/server/services/testConnectionService.js +11 -73
  83. package/server/services/transactionService.js +62 -99
  84. package/server/services/transactionStatusService.js +87 -0
  85. package/server/utils/normalize.js +0 -12
  86. package/server/utils/paymentMethodParams.js +0 -1
  87. package/server/utils/requestBuilder.js +34 -5
  88. package/server/utils/responseParser.js +9 -14
  89. package/strapi-admin.js +3 -1
  90. package/admin/src/pages/App/components/ConfigurationPanel.jsx +0 -517
  91. package/admin/src/pages/App/components/CustomerInfoPopover.jsx +0 -147
  92. package/admin/src/pages/App/components/HistoryPanel.jsx +0 -94
  93. package/admin/src/pages/App/components/PaymentActionsPanel.jsx +0 -280
  94. package/admin/src/pages/App/components/RawDataPopover.jsx +0 -113
  95. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTableFilters.jsx +0 -113
  96. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTablePagination.jsx +0 -180
  97. package/admin/src/pages/App/components/TransactionHistoryTable/index.jsx +0 -225
  98. package/admin/src/pages/App/components/paymentActions/ApplePayPanel.jsx +0 -95
  99. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +0 -197
  100. package/admin/src/pages/App/components/paymentActions/CaptureForm.jsx +0 -65
  101. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.jsx +0 -306
  102. package/admin/src/pages/App/components/paymentActions/PaymentResult.jsx +0 -192
  103. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +0 -142
  104. 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": // Credit Card (Visa, Mastercard, Amex)
149
+ case "cc":
162
150
  return {
163
151
  clearingtype: "cc",
164
- cardtype: finalCardType, // V = Visa, M = Mastercard, A = Amex
165
- cardpan: cardpan || "4111111111111111", // Test Visa card
152
+ cardtype: finalCardType,
153
+ cardpan: cardpan || "4111111111111111",
166
154
  cardexpiredate: getValidCardExpiryDate(cardexpiredate),
167
- cardcvc2: cardcvc2 || "123" // 3-digit security code
155
+ cardcvc2: cardcvc2 || "123"
168
156
  };
169
157
 
170
- case "wlt": // PayPal
158
+ case "wlt":
171
159
  return {
172
160
  clearingtype: "wlt",
173
- wallettype: "PPE", // PayPal Express
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": // Apple Pay
185
+ case "apl":
198
186
  const applePayParams = {
199
187
  clearingtype: "wlt",
200
- wallettype: "APL", // Apple Pay
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": // Sofort Banking
205
+ case "sb":
218
206
  return {
219
207
  clearingtype: "sb",
220
208
  bankcountry: "DE",
221
- onlinebanktransfertype: "PNT" // Sofort Banking
209
+ onlinebanktransfertype: "PNT"
222
210
  };
223
211
 
224
- case "elv": // SEPA Direct Debit
212
+ case "elv":
225
213
  return {
226
214
  clearingtype: "elv",
227
215
  bankcountry: "DE",
228
- iban: iban || "DE89370400440532013000", // Test IBAN
229
- bic: bic || "COBADEFFXXX", // Test BIC
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": "4.6.9",
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": "^4.0",
26
- "react": "^17.0.0 || ^18.0.0",
27
- "react-dom": "^17.0.0 || ^18.0.0",
28
- "react-router-dom": "^5.2.0",
29
- "styled-components": "^5.2.1"
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",
@@ -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
- if (error.response || error.status >= 400) {
11
- ctx.strapi.log.error("Payone controller error:", {
12
- status: error.status || error.response?.status,
13
- message: error.message
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
- ctx.throw(500, error);
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 = { data: hideKey(settings) };
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 { body } = ctx.request;
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 (body.key === "***HIDDEN***" || !body.key) {
69
- body.key = currentSettings?.key;
87
+ if (bodyData.key === "***HIDDEN***" || !bodyData.key) {
88
+ bodyData.key = currentSettings?.key;
70
89
  }
71
90
 
72
- const settings = await getPayoneService(strapi).updateSettings(body);
73
- ctx.body = { data: hideKey(settings) };
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 = { data: result };
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 = { data: result };
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 = { data: result };
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 = { data: result };
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 history = await getPayoneService(strapi).getTransactionHistory(filters);
123
- ctx.body = { data: history };
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 = { data: result };
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 ? ctx.query : ctx.request.body;
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 = { data: result };
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 = { data: result };
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
  });
@@ -2,5 +2,6 @@
2
2
 
3
3
  module.exports = {
4
4
  "is-auth": require("./is-auth"),
5
- "is-super-admin": require("./isSuperAdmin")
5
+ "is-super-admin": require("./isSuperAdmin"),
6
+ "is-payone-notification": require("./is-payone-notification")
6
7
  };
@@ -1,13 +1,19 @@
1
1
  "use strict";
2
2
 
3
- module.exports = async (ctx, config, { strapi }) => {
4
- const { authorization } = ctx.request.header || {};
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.services["admin::api-token"];
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 (ctx, next) => {
4
- const adminUser = ctx.state && ctx.state.user;
3
+ module.exports = async (policyContext, config, { strapi }) => {
4
+ const adminUser = policyContext.state && policyContext.state.user;
5
5
 
6
6
  if (!adminUser) {
7
- return ctx.unauthorized("Admin authentication required");
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
- return ctx.forbidden("Only super admins can access this resource");
15
+ policyContext.forbidden("Only super admins can access this resource");
16
+ return false;
15
17
  }
16
18
 
17
- return next();
19
+ return true;
18
20
  };
@@ -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
  };