strapi-plugin-payone-provider 1.5.8 → 1.6.0

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 (53) hide show
  1. package/admin/src/index.js +3 -3
  2. package/admin/src/pages/App/components/ApplePayBtn.jsx +304 -0
  3. package/admin/src/pages/App/components/{ApplePayButton.js → ApplePayButton.jsx} +141 -137
  4. package/admin/src/pages/App/components/{ApplePayConfig.js → ApplePayConfig.jsx} +64 -130
  5. package/admin/src/pages/App/components/{PaymentActionsPanel.js → PaymentActionsPanel.jsx} +62 -14
  6. package/admin/src/pages/App/components/icons/index.jsx +11 -0
  7. package/admin/src/pages/App/components/paymentActions/{AuthorizationForm.js → AuthorizationForm.jsx} +45 -35
  8. package/admin/src/pages/App/components/paymentActions/{PaymentMethodSelector.js → PaymentMethodSelector.jsx} +111 -31
  9. package/admin/src/pages/App/components/paymentActions/{PreauthorizationForm.js → PreauthorizationForm.jsx} +3 -70
  10. package/admin/src/pages/constants/paymentConstants.js +1 -2
  11. package/admin/src/pages/hooks/usePaymentActions.js +1 -76
  12. package/package.json +49 -49
  13. package/server/bootstrap.js +59 -1
  14. package/server/controllers/payone.js +6 -48
  15. package/server/routes/index.js +1 -1
  16. package/server/services/applePayService.js +51 -407
  17. package/server/services/paymentService.js +0 -68
  18. package/server/services/payone.js +0 -3
  19. package/server/services/settingsService.js +0 -21
  20. package/server/services/testConnectionService.js +0 -14
  21. package/server/services/transactionService.js +2 -16
  22. package/server/utils/paymentMethodParams.js +60 -21
  23. package/server/utils/requestBuilder.js +0 -22
  24. package/admin/src/pages/App/components/icons/index.js +0 -11
  25. /package/admin/src/components/Initializer/{index.js → index.jsx} +0 -0
  26. /package/admin/src/components/PluginIcon/{index.js → index.jsx} +0 -0
  27. /package/admin/src/pages/App/components/{AppHeader.js → AppHeader.jsx} +0 -0
  28. /package/admin/src/pages/App/components/{AppTabs.js → AppTabs.jsx} +0 -0
  29. /package/admin/src/pages/App/components/{ApplePayConfigPanel.js → ApplePayConfigPanel.jsx} +0 -0
  30. /package/admin/src/pages/App/components/{ConfigurationPanel.js → ConfigurationPanel.jsx} +0 -0
  31. /package/admin/src/pages/App/components/{DocsPanel.js → DocsPanel.jsx} +0 -0
  32. /package/admin/src/pages/App/components/{GooglePayConfig.js → GooglePayConfig.jsx} +0 -0
  33. /package/admin/src/pages/App/components/{GooglePayConfigPanel.js → GooglePayConfigPanel.jsx} +0 -0
  34. /package/admin/src/pages/App/components/{GooglePaybutton.js → GooglePaybutton.jsx} +0 -0
  35. /package/admin/src/pages/App/components/{HistoryPanel.js → HistoryPanel.jsx} +0 -0
  36. /package/admin/src/pages/App/components/{StatusBadge.js → StatusBadge.jsx} +0 -0
  37. /package/admin/src/pages/App/components/{TransactionHistoryItem.js → TransactionHistoryItem.jsx} +0 -0
  38. /package/admin/src/pages/App/components/icons/{BankIcon.js → BankIcon.jsx} +0 -0
  39. /package/admin/src/pages/App/components/icons/{ChevronDownIcon.js → ChevronDownIcon.jsx} +0 -0
  40. /package/admin/src/pages/App/components/icons/{ChevronUpIcon.js → ChevronUpIcon.jsx} +0 -0
  41. /package/admin/src/pages/App/components/icons/{CreditCardIcon.js → CreditCardIcon.jsx} +0 -0
  42. /package/admin/src/pages/App/components/icons/{ErrorIcon.js → ErrorIcon.jsx} +0 -0
  43. /package/admin/src/pages/App/components/icons/{InfoIcon.js → InfoIcon.jsx} +0 -0
  44. /package/admin/src/pages/App/components/icons/{PaymentIcon.js → PaymentIcon.jsx} +0 -0
  45. /package/admin/src/pages/App/components/icons/{PendingIcon.js → PendingIcon.jsx} +0 -0
  46. /package/admin/src/pages/App/components/icons/{PersonIcon.js → PersonIcon.jsx} +0 -0
  47. /package/admin/src/pages/App/components/icons/{SuccessIcon.js → SuccessIcon.jsx} +0 -0
  48. /package/admin/src/pages/App/components/icons/{WalletIcon.js → WalletIcon.jsx} +0 -0
  49. /package/admin/src/pages/App/components/paymentActions/{CaptureForm.js → CaptureForm.jsx} +0 -0
  50. /package/admin/src/pages/App/components/paymentActions/{CardDetailsInput.js → CardDetailsInput.jsx} +0 -0
  51. /package/admin/src/pages/App/components/paymentActions/{PaymentResult.js → PaymentResult.jsx} +0 -0
  52. /package/admin/src/pages/App/components/paymentActions/{RefundForm.js → RefundForm.jsx} +0 -0
  53. /package/admin/src/pages/App/{index.js → index.jsx} +0 -0
@@ -6,9 +6,6 @@ const paymentService = require("./paymentService");
6
6
  const testConnectionService = require("./testConnectionService");
7
7
  const applePayService = require("./applePayService");
8
8
 
9
- /**
10
- * Main Payone service - aggregates all sub-services
11
- */
12
9
  module.exports = ({ strapi }) => ({
13
10
  // Settings
14
11
  async getSettings() {
@@ -2,11 +2,6 @@
2
2
 
3
3
  const PLUGIN_NAME = "strapi-plugin-payone-provider";
4
4
 
5
- /**
6
- * Get plugin store instance
7
- * @param {Object} strapi - Strapi instance
8
- * @returns {Object} Plugin store
9
- */
10
5
  const getPluginStore = (strapi) => {
11
6
  return strapi.store({
12
7
  environment: "",
@@ -15,22 +10,11 @@ const getPluginStore = (strapi) => {
15
10
  });
16
11
  };
17
12
 
18
- /**
19
- * Get Payone settings
20
- * @param {Object} strapi - Strapi instance
21
- * @returns {Promise<Object>} Settings
22
- */
23
13
  const getSettings = async (strapi) => {
24
14
  const pluginStore = getPluginStore(strapi);
25
15
  return await pluginStore.get({ key: "settings" });
26
16
  };
27
17
 
28
- /**
29
- * Update Payone settings
30
- * @param {Object} strapi - Strapi instance
31
- * @param {Object} settings - Settings to update
32
- * @returns {Promise<Object>} Updated settings
33
- */
34
18
  const updateSettings = async (strapi, settings) => {
35
19
  const pluginStore = getPluginStore(strapi);
36
20
  await pluginStore.set({
@@ -40,11 +24,6 @@ const updateSettings = async (strapi, settings) => {
40
24
  return settings;
41
25
  };
42
26
 
43
- /**
44
- * Validate settings
45
- * @param {Object} settings - Settings to validate
46
- * @returns {boolean} True if valid
47
- */
48
27
  const validateSettings = (settings) => {
49
28
  return !!(settings && settings.aid && settings.portalid && settings.key);
50
29
  };
@@ -7,11 +7,6 @@ const { getSettings, validateSettings } = require("./settingsService");
7
7
 
8
8
  const POST_GATEWAY_URL = "https://api.pay1.de/post-gateway/";
9
9
 
10
- /**
11
- * Test Payone connection
12
- * @param {Object} strapi - Strapi instance
13
- * @returns {Promise<Object>} Test result
14
- */
15
10
  const testConnection = async (strapi) => {
16
11
  try {
17
12
  const settings = await getSettings(strapi);
@@ -79,11 +74,7 @@ const testConnection = async (strapi) => {
79
74
  result.Error?.CustomerMessage ||
80
75
  "";
81
76
 
82
- strapi.log.info("Payone test connection response:", { status, errorCode });
83
-
84
- // Handle error status
85
77
  if (status === "ERROR" || status === "error") {
86
- // Authentication errors
87
78
  if (["2006", "920", "921", "922", "401", "403"].includes(errorCode)) {
88
79
  return {
89
80
  success: false,
@@ -92,7 +83,6 @@ const testConnection = async (strapi) => {
92
83
  };
93
84
  }
94
85
 
95
- // Check for invalid credentials in message
96
86
  const errorMessageStr = typeof errorMessage === "string" ? errorMessage : JSON.stringify(errorMessage);
97
87
  const errorMessageLower = (errorMessageStr || "").toLowerCase();
98
88
  const authErrorKeywords = [
@@ -118,7 +108,6 @@ const testConnection = async (strapi) => {
118
108
  };
119
109
  }
120
110
 
121
- // Reference already exists (911) means credentials are working
122
111
  if (errorCode === "911") {
123
112
  return {
124
113
  success: true,
@@ -132,7 +121,6 @@ const testConnection = async (strapi) => {
132
121
  };
133
122
  }
134
123
 
135
- // Other errors
136
124
  return {
137
125
  success: false,
138
126
  message: `Connection failed: ${customErrorMessage || errorMessageStr || "Unknown error"}`,
@@ -145,7 +133,6 @@ const testConnection = async (strapi) => {
145
133
  };
146
134
  }
147
135
 
148
- // APPROVED status means connection is OK
149
136
  if (status === "APPROVED" || status === "approved") {
150
137
  return {
151
138
  success: true,
@@ -159,7 +146,6 @@ const testConnection = async (strapi) => {
159
146
  };
160
147
  }
161
148
 
162
- // Unexpected response format
163
149
  return {
164
150
  success: false,
165
151
  message: "Unexpected response format from Payone API",
@@ -1,13 +1,7 @@
1
1
  "use strict";
2
2
 
3
- const { getPluginStore, PLUGIN_NAME } = require("./settingsService");
4
-
5
- /**
6
- * Log transaction to history
7
- * @param {Object} strapi - Strapi instance
8
- * @param {Object} transactionData - Transaction data
9
- * @returns {Promise<void>}
10
- */
3
+ const { getPluginStore } = require("./settingsService");
4
+
11
5
  const logTransaction = async (strapi, transactionData) => {
12
6
  const pluginStore = getPluginStore(strapi);
13
7
  let transactionHistory =
@@ -41,7 +35,6 @@ const logTransaction = async (strapi, transactionData) => {
41
35
 
42
36
  transactionHistory.unshift(logEntry);
43
37
 
44
- // Keep only last 1000 transactions
45
38
  if (transactionHistory.length > 1000) {
46
39
  transactionHistory = transactionHistory.slice(0, 1000);
47
40
  }
@@ -54,18 +47,11 @@ const logTransaction = async (strapi, transactionData) => {
54
47
  strapi.log.info("Transaction logged:", logEntry);
55
48
  };
56
49
 
57
- /**
58
- * Get transaction history with filters
59
- * @param {Object} strapi - Strapi instance
60
- * @param {Object} filters - Filter options
61
- * @returns {Promise<Array>} Filtered transaction history
62
- */
63
50
  const getTransactionHistory = async (strapi, filters = {}) => {
64
51
  const pluginStore = getPluginStore(strapi);
65
52
  let transactionHistory =
66
53
  (await pluginStore.get({ key: "transactionHistory" })) || [];
67
54
 
68
- // Apply filters
69
55
  if (filters.status) {
70
56
  transactionHistory = transactionHistory.filter(
71
57
  (transaction) => transaction.status === filters.status
@@ -62,7 +62,6 @@ const addPaymentMethodParams = (params, logger) => {
62
62
  }
63
63
  };
64
64
 
65
- // Handle special cases (gpp, apl) FIRST - set wallettype BEFORE changing clearingtype
66
65
  if (clearingtype === "gpp" || clearingtype === "apl") {
67
66
  if (clearingtype === "gpp") {
68
67
  updated.wallettype = "GGP";
@@ -74,34 +73,76 @@ const addPaymentMethodParams = (params, logger) => {
74
73
 
75
74
  const defaults = methodDefaults[clearingtype] || methodDefaults.cc;
76
75
 
77
- // Apply defaults (but don't override wallettype if already set)
78
76
  Object.entries(defaults).forEach(([key, value]) => {
79
77
  if (key === "wallettype" && updated.wallettype) {
80
- return; // Don't override wallettype if already set
78
+ return;
81
79
  }
82
80
  if (!updated[key]) {
83
81
  updated[key] = value;
84
82
  }
85
83
  });
86
-
87
- // Handle Apple Pay token if present
88
- if (updated.applePayToken || updated["add_paydata[paymentmethod_token_data]"]) {
89
- const token = updated.applePayToken || updated["add_paydata[paymentmethod_token_data]"];
90
- const gatewayMerchantId = updated.mid || updated.portalid || '';
91
-
92
- updated["add_paydata[paymentmethod_token_data]"] = token;
93
- updated["add_paydata[paymentmethod]"] = "APL";
94
- updated["add_paydata[paymentmethod_type]"] = "APPLEPAY";
95
- updated["add_paydata[gatewayid]"] = "payonegmbh";
96
- if (gatewayMerchantId) {
97
- updated["add_paydata[gateway_merchantid]"] = gatewayMerchantId;
84
+
85
+ if (updated.applePayToken) {
86
+ let tokenData;
87
+ try {
88
+ // Decode Base64 token
89
+ const tokenString = Buffer.from(updated.applePayToken, 'base64').toString('utf-8');
90
+ tokenData = JSON.parse(tokenString);
91
+ } catch (e) {
92
+ try {
93
+ // Try parsing as JSON string directly
94
+ tokenData = typeof updated.applePayToken === 'string'
95
+ ? JSON.parse(updated.applePayToken)
96
+ : updated.applePayToken;
97
+ } catch (e2) {
98
+ // If already an object, use as-is
99
+ tokenData = updated.applePayToken;
100
+ }
101
+ }
102
+
103
+ if (tokenData && typeof tokenData === 'object') {
104
+ const paymentData = tokenData.paymentData;
105
+
106
+ if (!paymentData) {
107
+ if (logger) {
108
+ logger.error("[Apple Pay] Invalid token structure: missing paymentData field");
109
+ }
110
+ delete updated.applePayToken;
111
+ return updated;
112
+ }
113
+
114
+ const header = paymentData.header || {};
115
+
116
+ // Payone required fields according to docs
117
+ updated["add_paydata[paymentdata_token_version]"] = paymentData.version || "EC_v1";
118
+ updated["add_paydata[paymentdata_token_data]"] = paymentData.data || "";
119
+ updated["add_paydata[paymentdata_token_signature]"] = paymentData.signature || "";
120
+ updated["add_paydata[paymentdata_token_ephemeral_publickey]"] = header.ephemeralPublicKey || "";
121
+ updated["add_paydata[paymentdata_token_publickey_hash]"] = header.publicKeyHash || "";
122
+
123
+ // Transaction ID is optional according to Payone docs
124
+ if (paymentData.transactionId || header.transactionId) {
125
+ updated["add_paydata[paymentdata_token_transaction_id]"] = paymentData.transactionId || header.transactionId || "";
126
+ }
127
+
128
+ if (!updated["add_paydata[paymentdata_token_data]"] ||
129
+ !updated["add_paydata[paymentdata_token_signature]"] ||
130
+ !updated["add_paydata[paymentdata_token_ephemeral_publickey]"] ||
131
+ !updated["add_paydata[paymentdata_token_publickey_hash]"]) {
132
+ if (logger) {
133
+ logger.error("[Apple Pay] Missing required token fields:", {
134
+ hasData: !!updated["add_paydata[paymentdata_token_data]"],
135
+ hasSignature: !!updated["add_paydata[paymentdata_token_signature]"],
136
+ hasEphemeralPublicKey: !!updated["add_paydata[paymentdata_token_ephemeral_publickey]"],
137
+ hasPublicKeyHash: !!updated["add_paydata[paymentdata_token_publickey_hash]"]
138
+ });
139
+ }
140
+ }
98
141
  }
99
-
100
- // Remove applePayToken from params as it's now in add_paydata
142
+
101
143
  delete updated.applePayToken;
102
144
  }
103
145
 
104
- // Ensure wallettype is set for wallet payments
105
146
  if (updated.clearingtype === "wlt" && !updated.wallettype) {
106
147
  if (clearingtype === "gpp" || updated.paymentMethod === "gpp" || (updated["add_paydata[paymentmethod]"] === "GGP")) {
107
148
  updated.wallettype = "GGP";
@@ -111,14 +152,12 @@ const addPaymentMethodParams = (params, logger) => {
111
152
  updated.wallettype = "PPE";
112
153
  }
113
154
  }
114
-
115
- // Remove cardtype if clearingtype is wallet payment
155
+
116
156
  if (updated.clearingtype === "wlt" && updated.cardtype) {
117
157
  delete updated.cardtype;
118
158
  }
119
159
 
120
160
 
121
- // Common defaults
122
161
  const commonDefaults = {
123
162
  salutation: "Herr",
124
163
  gender: "m",
@@ -3,13 +3,6 @@
3
3
  const crypto = require("crypto");
4
4
  const { normalizeCustomerId } = require("./normalize");
5
5
 
6
- /**
7
- * Build client request parameters for Payone API
8
- * @param {Object} settings - Payone settings
9
- * @param {Object} params - Request parameters
10
- * @param {Object|null} logger - Logger instance
11
- * @returns {Object} Built request parameters
12
- */
13
6
  const buildClientRequestParams = (settings, params, logger = null) => {
14
7
  const requestParams = {
15
8
  request: params.request,
@@ -21,29 +14,23 @@ const buildClientRequestParams = (settings, params, logger = null) => {
21
14
  ...params
22
15
  };
23
16
 
24
- // Generate MD5 hash key
25
17
  requestParams.key = crypto
26
18
  .createHash("md5")
27
19
  .update(settings.portalKey || settings.key)
28
20
  .digest("hex");
29
21
 
30
- // Normalize customer ID
31
22
  requestParams.customerid = normalizeCustomerId(
32
23
  requestParams.customerid,
33
24
  logger
34
25
  );
35
26
 
36
- // Add 3D Secure parameters if enabled and for credit card payments
37
27
  const isCreditCard = requestParams.clearingtype === "cc";
38
- // Enable 3DS if setting is true or not explicitly false (default to enabled if not set)
39
28
  const enable3DSecure = settings.enable3DSecure !== false;
40
29
 
41
30
  if (isCreditCard && enable3DSecure && (params.request === "preauthorization" || params.request === "authorization")) {
42
31
  requestParams["3dsecure"] = "yes";
43
32
  requestParams.ecommercemode = params.ecommercemode || "internet";
44
33
 
45
- // Ensure redirect URLs are always provided for 3DS
46
- // These are required for 3DS authentication flow
47
34
  if (!requestParams.successurl) {
48
35
  requestParams.successurl = params.successurl || "https://www.example.com/success";
49
36
  }
@@ -54,7 +41,6 @@ const buildClientRequestParams = (settings, params, logger = null) => {
54
41
  requestParams.backurl = params.backurl || "https://www.example.com/back";
55
42
  }
56
43
 
57
- // Log redirect URLs for debugging
58
44
  if (logger) {
59
45
  logger.info("3DS Redirect URLs:", {
60
46
  successurl: requestParams.successurl,
@@ -66,7 +52,6 @@ const buildClientRequestParams = (settings, params, logger = null) => {
66
52
  requestParams["3dsecure"] = "no";
67
53
  }
68
54
 
69
- // Set default values
70
55
  const defaults = {
71
56
  salutation: "Herr",
72
57
  gender: "m",
@@ -82,12 +67,10 @@ const buildClientRequestParams = (settings, params, logger = null) => {
82
67
  }
83
68
  });
84
69
 
85
- // Remove cardtype if clearingtype is wallet payment
86
70
  if (requestParams.clearingtype === "wlt" && requestParams.cardtype) {
87
71
  delete requestParams.cardtype;
88
72
  }
89
73
 
90
- // Ensure wallettype is set for wallet payments
91
74
  if (requestParams.clearingtype === "wlt" && !requestParams.wallettype) {
92
75
  if (requestParams["add_paydata[paymentmethod_token_data]"]) {
93
76
  requestParams.wallettype = "GGP";
@@ -99,11 +82,6 @@ const buildClientRequestParams = (settings, params, logger = null) => {
99
82
  return requestParams;
100
83
  };
101
84
 
102
- /**
103
- * Convert request parameters to form data
104
- * @param {Object} requestParams - Request parameters
105
- * @returns {URLSearchParams} Form data
106
- */
107
85
  const toFormData = (requestParams) => {
108
86
  const formData = new URLSearchParams();
109
87
  for (const [key, value] of Object.entries(requestParams)) {
@@ -1,11 +0,0 @@
1
- export { default as PaymentIcon } from './PaymentIcon';
2
- export { default as PersonIcon } from './PersonIcon';
3
- export { default as CreditCardIcon } from './CreditCardIcon';
4
- export { default as BankIcon } from './BankIcon';
5
- export { default as WalletIcon } from './WalletIcon';
6
- export { default as ErrorIcon } from './ErrorIcon';
7
- export { default as SuccessIcon } from './SuccessIcon';
8
- export { default as PendingIcon } from './PendingIcon';
9
- export { default as InfoIcon } from './InfoIcon';
10
- export { default as ChevronDownIcon } from './ChevronDownIcon';
11
- export { default as ChevronUpIcon } from './ChevronUpIcon';
File without changes