strapi-plugin-payone-provider 4.6.10 → 4.6.12

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 (68) hide show
  1. package/README.md +64 -0
  2. package/admin/src/pages/App/components/AppHeader.jsx +3 -2
  3. package/admin/src/pages/App/components/AppTabs.jsx +34 -88
  4. package/admin/src/pages/App/components/DocsPanel.jsx +1726 -1726
  5. package/admin/src/pages/App/components/GooglePaybutton.jsx +300 -300
  6. package/admin/src/pages/App/components/StatusBadge.jsx +1 -1
  7. package/admin/src/pages/App/components/common/InfoTooltip.jsx +16 -0
  8. package/admin/src/pages/App/components/{ApplePayConfig.jsx → configuration/ApplePayConfig.jsx} +191 -62
  9. package/admin/src/pages/App/components/{ApplePayConfigPanel.jsx → configuration/ApplePayConfigPanel.jsx} +71 -70
  10. package/admin/src/pages/App/components/configuration/ConfigurationFields.jsx +408 -0
  11. package/admin/src/pages/App/components/configuration/ConfigurationPanel.jsx +67 -0
  12. package/admin/src/pages/App/components/{GooglePayConfig.jsx → configuration/GooglePayConfig.jsx} +254 -254
  13. package/admin/src/pages/App/components/{GooglePayConfigPanel.jsx → configuration/GooglePayConfigPanel.jsx} +82 -82
  14. package/admin/src/pages/App/components/configuration/TestConnection.jsx +129 -0
  15. package/admin/src/pages/App/components/paymentActions/ApplePayPanel.jsx +137 -95
  16. package/admin/src/pages/App/components/paymentActions/CaptureForm.jsx +119 -14
  17. package/admin/src/pages/App/components/paymentActions/CardDetailsInput.jsx +85 -24
  18. package/admin/src/pages/App/components/paymentActions/PaymentActionsPanel.jsx +361 -0
  19. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.jsx +22 -4
  20. package/admin/src/pages/App/components/paymentActions/RefundForm.jsx +91 -20
  21. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationForm.jsx +157 -0
  22. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationFormFields.jsx +308 -0
  23. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationFormHeader.jsx +27 -0
  24. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationPaymentButtons.jsx +93 -0
  25. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationForm.jsx +134 -0
  26. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationFormFields.jsx +295 -0
  27. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationFormHeader.jsx +27 -0
  28. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationPaymentButtons.jsx +53 -0
  29. package/admin/src/pages/App/components/transaction-history/FiltersPanel.jsx +182 -0
  30. package/admin/src/pages/App/components/transaction-history/HistoryPanel.jsx +49 -0
  31. package/admin/src/pages/App/components/transaction-history/TransactionTable.jsx +199 -0
  32. package/admin/src/pages/App/components/transaction-history/TransactionTablePagination.jsx +28 -0
  33. package/admin/src/pages/App/components/transaction-history/details/TransactionDetails.jsx +155 -0
  34. package/admin/src/pages/App/index.jsx +5 -29
  35. package/admin/src/pages/hooks/usePaymentActions.js +87 -11
  36. package/admin/src/pages/hooks/useSettings.js +64 -22
  37. package/admin/src/pages/hooks/useTransactionHistory.js +121 -85
  38. package/admin/src/pages/utils/api.js +31 -3
  39. package/admin/src/pages/utils/countryLanguageUtils.js +236 -0
  40. package/admin/src/pages/utils/transactionTableUtils.js +60 -0
  41. package/package.json +2 -2
  42. package/server/bootstrap.js +6 -6
  43. package/server/content-types/index.js +5 -0
  44. package/server/content-types/transactions/index.js +5 -0
  45. package/server/content-types/transactions/schema.json +87 -0
  46. package/server/controllers/payone.js +29 -3
  47. package/server/index.js +2 -1
  48. package/server/policies/index.js +2 -1
  49. package/server/policies/is-payone-notification.js +31 -0
  50. package/server/routes/index.js +10 -0
  51. package/server/services/applePayService.js +0 -2
  52. package/server/services/payone.js +16 -4
  53. package/server/services/settingsService.js +8 -2
  54. package/server/services/testConnectionService.js +11 -72
  55. package/server/services/transactionService.js +147 -154
  56. package/server/services/transactionStatusService.js +63 -0
  57. package/server/utils/sanitize.js +41 -0
  58. package/admin/src/pages/App/components/ConfigurationPanel.jsx +0 -517
  59. package/admin/src/pages/App/components/CustomerInfoPopover.jsx +0 -147
  60. package/admin/src/pages/App/components/HistoryPanel.jsx +0 -94
  61. package/admin/src/pages/App/components/PaymentActionsPanel.jsx +0 -280
  62. package/admin/src/pages/App/components/RawDataPopover.jsx +0 -113
  63. package/admin/src/pages/App/components/TransactionHistoryItem.jsx +0 -522
  64. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTableFilters.jsx +0 -113
  65. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTablePagination.jsx +0 -180
  66. package/admin/src/pages/App/components/TransactionHistoryTable/index.jsx +0 -225
  67. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +0 -197
  68. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +0 -142
@@ -0,0 +1,60 @@
1
+ export const getStatusColor = (status) => {
2
+ switch (status) {
3
+ case "APPROVED":
4
+ return "success200";
5
+ case "ERROR":
6
+ return "danger200";
7
+ case "PENDING":
8
+ return "warning200";
9
+ case "REDIRECT":
10
+ return "success100";
11
+ default:
12
+ return "success100";
13
+ }
14
+ };
15
+
16
+ export const formatAmount = (amount, currency) => {
17
+ if (amount === null || amount === undefined) return "N/A";
18
+ return `${(amount / 100).toFixed(2)} ${currency || "EUR"}`;
19
+ };
20
+
21
+ export const formatDate = (dateString) => {
22
+ if (!dateString) return "N/A";
23
+ return new Date(dateString).toLocaleString("de-DE", {
24
+ year: "numeric",
25
+ month: "2-digit",
26
+ day: "2-digit",
27
+ hour: "2-digit",
28
+ minute: "2-digit",
29
+ });
30
+ };
31
+
32
+ export const getPaymentMethodName = (clearingtype, wallettype, cardtype) => {
33
+ switch (clearingtype) {
34
+ case "cc":
35
+ return cardtype ? `CC / ${cardtype}` : "Credit Card";
36
+ case "sb":
37
+ return "Online Banking";
38
+ case "wlt":
39
+ return wallettype === "PPE" ? "PayPal" : "Wallet";
40
+ case "elv":
41
+ return "Direct Debit (SEPA)";
42
+ default:
43
+ return clearingtype || "Unknown";
44
+ }
45
+ };
46
+
47
+ export const getCardTypeName = (cardtype) => {
48
+ switch (cardtype) {
49
+ case "V":
50
+ return "Visa";
51
+ case "M":
52
+ return "Mastercard";
53
+ case "A":
54
+ return "American Express";
55
+ default:
56
+ return cardtype || "Unknown";
57
+ }
58
+ };
59
+
60
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strapi-plugin-payone-provider",
3
- "version": "4.6.10",
3
+ "version": "4.6.12",
4
4
  "description": "Strapi plugin for Payone payment gateway integration",
5
5
  "license": "MIT",
6
6
  "maintainers": [
@@ -48,4 +48,4 @@
48
48
  "kind": "plugin",
49
49
  "displayName": "Strapi Payone Provider"
50
50
  }
51
- }
51
+ }
@@ -22,12 +22,12 @@ module.exports = async ({ strapi }) => {
22
22
  displayName: "",
23
23
  domainName: "",
24
24
  merchantIdentifier: "",
25
- enableCreditCard: true,
26
- enablePayPal: true,
27
- enableGooglePay: true,
28
- enableApplePay: true,
29
- enableSofort: true,
30
- enableSepaDirectDebit: true
25
+ enable3DSecure: false,
26
+ enableCreditCard: false,
27
+ enablePayPal: false,
28
+ enableGooglePay: false,
29
+ enableApplePay: false,
30
+ enableSepaDirectDebit: false
31
31
  }
32
32
  });
33
33
  }
@@ -0,0 +1,5 @@
1
+ const transactionsContentType = require('./transactions/index.js')
2
+
3
+ module.exports = {
4
+ 'transaction': transactionsContentType
5
+ }
@@ -0,0 +1,5 @@
1
+ const schema = require('./schema.json');
2
+
3
+ module.exports = {
4
+ schema
5
+ }
@@ -0,0 +1,87 @@
1
+ {
2
+ "kind": "collectionType",
3
+ "collectionName": "transactions",
4
+ "info": {
5
+ "singularName": "transaction",
6
+ "pluralName": "transactions",
7
+ "displayName": "Transaction"
8
+ },
9
+ "options": {
10
+ "draftAndPublish": false
11
+ },
12
+ "pluginOptions": {
13
+ "content-manager": {
14
+ "visible": false
15
+ },
16
+ "content-type-builder": {
17
+ "visible": false
18
+ }
19
+ },
20
+ "attributes": {
21
+ "txid": {
22
+ "type": "string",
23
+ "required": false,
24
+ "default": "NO TXID"
25
+ },
26
+ "reference": {
27
+ "type": "string",
28
+ "required": false,
29
+ "default": "NO REFERENCE"
30
+ },
31
+ "invoiceid": {
32
+ "type": "string",
33
+ "required": false,
34
+ "default": "NO INVOICE ID"
35
+ },
36
+ "amount": {
37
+ "type": "string",
38
+ "required": false,
39
+ "default": "0"
40
+ },
41
+ "currency": {
42
+ "type": "string",
43
+ "required": false,
44
+ "default": "EUR"
45
+ },
46
+ "status": {
47
+ "type": "string",
48
+ "required": false,
49
+ "default": "unknown"
50
+ },
51
+ "error_code": {
52
+ "type": "string",
53
+ "required": false,
54
+ "default": "NO ERROR CODE"
55
+ },
56
+ "request_type": {
57
+ "type": "string",
58
+ "required": false,
59
+ "default": "unknown"
60
+ },
61
+ "error_message": {
62
+ "type": "string",
63
+ "required": false,
64
+ "default": "NO ERROR MESSAGE"
65
+ },
66
+ "customer_message": {
67
+ "type": "string",
68
+ "required": false,
69
+ "default": "NO CUSTOMER MESSAGE"
70
+ },
71
+ "body": {
72
+ "type": "json",
73
+ "required": false,
74
+ "default": {}
75
+ },
76
+ "raw_request": {
77
+ "type": "json",
78
+ "required": false,
79
+ "default": {}
80
+ },
81
+ "raw_response": {
82
+ "type": "json",
83
+ "required": false,
84
+ "default": {}
85
+ }
86
+ }
87
+ }
@@ -118,9 +118,17 @@ module.exports = ({ strapi }) => ({
118
118
 
119
119
  async getTransactionHistory(ctx) {
120
120
  try {
121
- const filters = ctx.query || {};
122
- const history = await getPayoneService(strapi).getTransactionHistory(filters);
123
- ctx.body = { data: history };
121
+ const { filters = {}, pagination = {}, sort_by, sort_order } = ctx.query || {};
122
+ const page = parseInt(pagination.page || "1", 10);
123
+ const pageSize = parseInt(pagination.pageSize || "10", 10);
124
+
125
+ const result = await getPayoneService(strapi).getTransactionHistory({
126
+ filters: filters || {},
127
+ pagination: { page, pageSize },
128
+ sort_by: sort_by || undefined,
129
+ sort_order: sort_order || undefined,
130
+ });
131
+ ctx.body = result
124
132
  } catch (error) {
125
133
  handleError(ctx, error);
126
134
  }
@@ -246,5 +254,23 @@ module.exports = ({ strapi }) => ({
246
254
  }
247
255
  };
248
256
  }
257
+ },
258
+
259
+ async handleTransactionStatus(ctx) {
260
+ try {
261
+ const notificationData = ctx.request.body || {};
262
+ await getPayoneService(strapi).processTransactionStatus(notificationData);
263
+
264
+ ctx.status = 200;
265
+ ctx.body = "TSOK";
266
+ ctx.type = "text/plain";
267
+ console.log(`[Payone TransactionStatus] Responded TSOK`);
268
+ } catch (error) {
269
+ console.log("[Payone TransactionStatus] Error handling notification:", error);
270
+ ctx.status = 200;
271
+ ctx.body = "TSOK";
272
+ ctx.type = "text/plain";
273
+ }
249
274
  }
275
+
250
276
  });
package/server/index.js CHANGED
@@ -8,13 +8,14 @@ const controllers = require("./controllers");
8
8
  const routes = require("./routes");
9
9
  const services = require("./services");
10
10
  const policies = require("./policies");
11
-
11
+ const contentTypes = require("./content-types");
12
12
  module.exports = {
13
13
  register,
14
14
  bootstrap,
15
15
  destroy,
16
16
  config,
17
17
  controllers,
18
+ contentTypes,
18
19
  routes,
19
20
  services,
20
21
  policies
@@ -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
  };
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ module.exports = async (ctx, config, { strapi }) => {
4
+ const { request } = ctx;
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
+ };
@@ -162,6 +162,16 @@ 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
+ },
165
175
  ]
166
176
  }
167
177
  };
@@ -174,8 +174,6 @@ const validateApplePayMerchant = async (strapi, params) => {
174
174
 
175
175
  const sessionResponse = await initializeApplePaySession(strapi, params);
176
176
 
177
- // Extract add_paydata[applepay_payment_session] from response
178
- // Payone returns this in URL-encoded format: add_paydata[applepay_payment_session]=BASE64_STRING
179
177
  const applePaySessionBase64 =
180
178
  sessionResponse["add_paydata[applepay_payment_session]"] ||
181
179
  sessionResponse["add_paydata_applepay_payment_session"] ||
@@ -5,7 +5,7 @@ const transactionService = require("./transactionService");
5
5
  const paymentService = require("./paymentService");
6
6
  const testConnectionService = require("./testConnectionService");
7
7
  const applePayService = require("./applePayService");
8
-
8
+ const transactionStatusService = require("./transactionStatusService");
9
9
  module.exports = ({ strapi }) => ({
10
10
  // Settings
11
11
  async getSettings() {
@@ -38,8 +38,14 @@ module.exports = ({ strapi }) => ({
38
38
  return await transactionService.logTransaction(strapi, transactionData);
39
39
  },
40
40
 
41
- async getTransactionHistory(filters = {}) {
42
- return await transactionService.getTransactionHistory(strapi, filters);
41
+
42
+ async getTransactionHistory({ filters = {}, pagination = {}, sort_by = "createdAt", sort_order = "desc" } = {}) {
43
+ return await transactionService.getTransactionHistory(strapi, {
44
+ filters,
45
+ pagination,
46
+ sort_by,
47
+ sort_order,
48
+ });
43
49
  },
44
50
 
45
51
  // Test connection
@@ -59,5 +65,11 @@ module.exports = ({ strapi }) => ({
59
65
 
60
66
  async initializeApplePaySession(params) {
61
67
  return await applePayService.initializeApplePaySession(strapi, params);
62
- }
68
+ },
69
+
70
+ // TransactionStatus Notification
71
+ async processTransactionStatus(notificationData) {
72
+ return await transactionStatusService.processTransactionStatus(strapi, notificationData);
73
+ },
74
+
63
75
  });
@@ -17,11 +17,17 @@ const getSettings = async (strapi) => {
17
17
 
18
18
  const updateSettings = async (strapi, settings) => {
19
19
  const pluginStore = getPluginStore(strapi);
20
+ const currentSettings = await getSettings(strapi) || {};
21
+ const mergedSettings = {
22
+ ...currentSettings,
23
+ ...settings
24
+ };
25
+
20
26
  await pluginStore.set({
21
27
  key: "settings",
22
- value: settings
28
+ value: mergedSettings
23
29
  });
24
- return settings;
30
+ return mergedSettings;
25
31
  };
26
32
 
27
33
  const validateSettings = (settings) => {
@@ -55,81 +55,18 @@ const testConnection = async (strapi) => {
55
55
 
56
56
  const result = parseResponse(response.data, strapi.log);
57
57
  const status = result.status || result.Status || result.STATUS;
58
- const errorMessage =
59
- result.errormessage ||
60
- result.Errormessage ||
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
- "";
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: `Connection failed: ${customErrorMessage || errorMessageStr || "Unknown error"}`,
128
- errorcode: errorCode,
129
- details: {
130
- status,
131
- errorCode,
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
  }
@@ -147,6 +84,7 @@ const testConnection = async (strapi) => {
147
84
  };
148
85
  }
149
86
 
87
+
150
88
  return {
151
89
  success: false,
152
90
  message: "Unexpected response format from Payone API",
@@ -157,11 +95,12 @@ const testConnection = async (strapi) => {
157
95
  rawResponse: JSON.stringify(result).substring(0, 200)
158
96
  }
159
97
  };
98
+
160
99
  } catch (error) {
161
100
  strapi.log.error("Payone test connection error:", error);
162
101
  return {
163
102
  success: false,
164
- message: `Connection error: ${error.message || "Unknown error"}`,
103
+ message: `Test connection error: ${error.message || "Unknown error"}`,
165
104
  error: error.toString(),
166
105
  details: {
167
106
  errorType: error.constructor.name,