strapi-plugin-payone-provider 5.6.11 → 5.6.13
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 +102 -545
- package/admin/src/components/PluginIcon/index.jsx +14 -3
- package/admin/src/pages/App/components/AppHeader.jsx +1 -1
- package/admin/src/pages/App/components/AppTabs.jsx +69 -16
- package/admin/src/pages/App/components/RenderInput.jsx +9 -25
- package/admin/src/pages/App/components/StatusBadge.jsx +69 -17
- package/admin/src/pages/App/components/configuration/ConfigurationPanel.jsx +2 -2
- package/admin/src/pages/App/components/icons/index.jsx +1 -0
- package/admin/src/pages/App/components/transaction-history/FiltersPanel.jsx +4 -3
- package/admin/src/pages/App/components/transaction-history/TransactionTable.jsx +6 -5
- package/admin/src/pages/App/components/transaction-history/details/TransactionDetails.jsx +10 -10
- package/admin/src/pages/App/index.jsx +3 -3
- package/admin/src/pages/App/styles.css +28 -23
- package/admin/src/pages/utils/api.js +3 -2
- package/admin/src/pages/utils/getInputComponent.jsx +20 -45
- package/admin/src/pages/utils/transactionTableUtils.js +2 -1
- package/package.json +1 -1
- package/server/content-types/index.js +5 -0
- package/server/content-types/transactions/index.js +5 -0
- package/server/content-types/transactions/schema.json +87 -0
- package/server/controllers/payone.js +24 -13
- package/server/index.js +2 -0
- package/server/policies/is-payone-notification.js +12 -23
- package/server/services/transactionService.js +137 -104
- package/server/services/transactionStatusService.js +55 -61
- package/server/utils/sanitize.js +42 -0
|
@@ -1,87 +1,81 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const
|
|
4
|
-
const {
|
|
3
|
+
const { getSettings } = require("./settingsService");
|
|
4
|
+
const { sanitizeSensitive } = require("../utils/sanitize");
|
|
5
5
|
|
|
6
|
-
const
|
|
7
|
-
const {
|
|
8
|
-
portalid = "",
|
|
9
|
-
aid = "",
|
|
10
|
-
txid = "",
|
|
11
|
-
sequencenumber = "",
|
|
12
|
-
price = "",
|
|
13
|
-
currency = "",
|
|
14
|
-
mode = "",
|
|
15
|
-
} = notificationData;
|
|
6
|
+
const TRANSACTION_UID = "plugin::strapi-plugin-payone-provider.transaction";
|
|
16
7
|
|
|
17
|
-
|
|
18
|
-
const
|
|
8
|
+
const genreateUpdateData = (notificationData, existing, safeNotification) => {
|
|
9
|
+
const amount = String(notificationData.clearing_amount) || String(Math.round(parseFloat(notificationData.price) * 100)) || existing.amount;
|
|
10
|
+
const raw_request = {
|
|
11
|
+
...existing.raw_request,
|
|
12
|
+
...notificationData,
|
|
13
|
+
mode: notificationData.mode,
|
|
14
|
+
amount,
|
|
15
|
+
clearingtype: notificationData.clearingtype || existing.clearingtype,
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
status: notificationData.transaction_status || existing.status,
|
|
20
|
+
currency: notificationData.currency || existing.currency,
|
|
21
|
+
reference: notificationData.reference || existing.reference,
|
|
22
|
+
amount,
|
|
23
|
+
body: {
|
|
24
|
+
...existing.body,
|
|
25
|
+
status: notificationData.transaction_status,
|
|
26
|
+
amount,
|
|
27
|
+
raw_request: sanitizeSensitive(raw_request),
|
|
28
|
+
payone_notification_data: safeNotification,
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const validateData = (notificationData, settings) => {
|
|
34
|
+
const isExist = (settings.portalid && settings.aid && settings.key) && (notificationData.portalid && notificationData.aid && notificationData.key);
|
|
35
|
+
const isMatch = notificationData.portalid === settings.portalid && notificationData.aid === settings.aid && notificationData.key === settings.key;
|
|
36
|
+
|
|
37
|
+
if (!isExist) {
|
|
38
|
+
console.log("[Payone TransactionStatus] Settings not found or payone data missing");
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
19
41
|
|
|
20
|
-
|
|
42
|
+
if (!isMatch) {
|
|
43
|
+
console.log("[Payone TransactionStatus] Payone data mismatch with settings");
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return true;
|
|
21
48
|
};
|
|
22
49
|
|
|
50
|
+
|
|
23
51
|
const processTransactionStatus = async (strapi, notificationData) => {
|
|
24
52
|
try {
|
|
25
53
|
const settings = await getSettings(strapi);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (!settings || !settings.key) {
|
|
29
|
-
console.log("[Payone TransactionStatus] Settings not found or key missing");
|
|
54
|
+
if (!validateData(notificationData, settings)) {
|
|
30
55
|
return;
|
|
31
56
|
}
|
|
32
57
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
console.log(`[Payone TransactionStatus] Hash verification failed txid: ${txid}`);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
58
|
+
const txid = notificationData.txid;
|
|
59
|
+
const existing = await strapi.db.query(TRANSACTION_UID).findOne({ where: { txid } });
|
|
38
60
|
|
|
39
|
-
if (
|
|
40
|
-
console.log(`[Payone TransactionStatus]
|
|
61
|
+
if (!existing) {
|
|
62
|
+
console.log(`[Payone TransactionStatus] Transaction ${txid} not found. Notification ignored.`);
|
|
41
63
|
return;
|
|
42
64
|
}
|
|
43
65
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Object.assign(transaction, {
|
|
51
|
-
...notificationData,
|
|
52
|
-
status: notificationData?.transaction_status,
|
|
53
|
-
txaction: notificationData?.txaction,
|
|
54
|
-
txtime: notificationData?.txtime,
|
|
55
|
-
sequencenumber: notificationData?.sequencenumber,
|
|
56
|
-
balance: notificationData?.balance,
|
|
57
|
-
receivable: notificationData?.receivable,
|
|
58
|
-
price: notificationData?.price,
|
|
59
|
-
amount: notificationData?.price ? parseFloat(notificationData?.price) * 100 : transaction?.amount,
|
|
60
|
-
userid: notificationData?.userid,
|
|
61
|
-
updated_at: new Date().toISOString(),
|
|
62
|
-
body: {
|
|
63
|
-
...transaction?.body,
|
|
64
|
-
...notificationData,
|
|
65
|
-
status: notificationData?.transaction_status
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
await pluginStore.set({
|
|
70
|
-
key: "transactionHistory",
|
|
71
|
-
value: transactionHistory,
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
console.log(`[Payone TransactionStatus] Successfully updated transaction txid: ${txid}`);
|
|
75
|
-
} else {
|
|
76
|
-
console.log(`[Payone TransactionStatus] Transaction ${txid} not found in history. Notification ignored.`);
|
|
77
|
-
}
|
|
66
|
+
const safeNotification = sanitizeSensitive({ ...notificationData });
|
|
67
|
+
const data = genreateUpdateData(notificationData, existing, safeNotification);
|
|
68
|
+
await strapi.db.query(TRANSACTION_UID).update({
|
|
69
|
+
where: { id: existing.id },
|
|
70
|
+
data,
|
|
71
|
+
});
|
|
78
72
|
|
|
73
|
+
console.log(`[Payone TransactionStatus] Successfully updated transaction txid: ${txid}`);
|
|
79
74
|
} catch (error) {
|
|
80
75
|
console.log(`[Payone TransactionStatus] Error processing notification: ${error}`);
|
|
81
76
|
}
|
|
82
77
|
};
|
|
83
78
|
|
|
84
79
|
module.exports = {
|
|
85
|
-
verifyHash,
|
|
86
80
|
processTransactionStatus,
|
|
87
81
|
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const SENSITIVE_KEYS = [
|
|
4
|
+
"cardpan",
|
|
5
|
+
"cardexpiredate",
|
|
6
|
+
"cardcvc2",
|
|
7
|
+
"iban",
|
|
8
|
+
"bic",
|
|
9
|
+
"bankaccount",
|
|
10
|
+
"bankcode",
|
|
11
|
+
"bankaccountholder",
|
|
12
|
+
"key",
|
|
13
|
+
"accesscode",
|
|
14
|
+
"accessname",
|
|
15
|
+
"token",
|
|
16
|
+
"redirecturl",
|
|
17
|
+
"Identifier"
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const maskValue = (val) => {
|
|
21
|
+
if (typeof val !== "string") return val;
|
|
22
|
+
return "*".repeat(Math.min(val.length, 20));
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const sanitizeSensitive = (obj) => {
|
|
26
|
+
if (!obj || typeof obj !== "object") return obj;
|
|
27
|
+
if (Array.isArray(obj)) return obj.map(sanitizeSensitive);
|
|
28
|
+
const out = {};
|
|
29
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
30
|
+
const keyLower = k.toLowerCase();
|
|
31
|
+
if (SENSITIVE_KEYS.includes(keyLower) && v != null) {
|
|
32
|
+
out[k] = maskValue(String(v));
|
|
33
|
+
} else if (v != null && typeof v === "object" && !Array.isArray(v)) {
|
|
34
|
+
out[k] = sanitizeSensitive(v);
|
|
35
|
+
} else {
|
|
36
|
+
out[k] = v;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return out;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
module.exports = { sanitizeSensitive };
|