@unchainedshop/plugins 2.8.16 → 2.8.18
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/lib/payment/saferpay/adapter.d.ts +3 -0
- package/lib/payment/saferpay/adapter.js +181 -0
- package/lib/payment/saferpay/adapter.js.map +1 -0
- package/lib/payment/saferpay/api/api/SaferpayClient.d.ts +17 -0
- package/lib/payment/saferpay/api/api/SaferpayClient.js +44 -0
- package/lib/payment/saferpay/api/api/SaferpayClient.js.map +1 -0
- package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/api/SaferpayConnection.js +2 -4
- package/lib/payment/saferpay/api/api/SaferpayConnection.js.map +1 -0
- package/lib/payment/saferpay/api/index.js.map +1 -0
- package/lib/payment/saferpay/api/models/PaymentMethods.js.map +1 -0
- package/lib/payment/saferpay/api/models/PaymentPageAssert.js.map +1 -0
- package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentPageInitialize.d.ts +9 -6
- package/lib/payment/saferpay/api/models/PaymentPageInitialize.js.map +1 -0
- package/lib/payment/saferpay/api/models/Request.js.map +1 -0
- package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Response.d.ts +1 -1
- package/lib/payment/saferpay/api/models/Response.js.map +1 -0
- package/lib/payment/saferpay/api/models/Transaction.js.map +1 -0
- package/lib/payment/saferpay/api/models/TransactionCancel.js.map +1 -0
- package/lib/payment/saferpay/api/models/TransactionCapture.d.ts +18 -0
- package/lib/payment/saferpay/api/models/TransactionCapture.js +2 -0
- package/lib/payment/saferpay/api/models/TransactionCapture.js.map +1 -0
- package/lib/payment/saferpay/buildSignature.d.ts +1 -0
- package/lib/payment/saferpay/buildSignature.js +9 -0
- package/lib/payment/saferpay/buildSignature.js.map +1 -0
- package/lib/payment/saferpay/db/SaferpayTransactionsCollection.d.ts +7 -0
- package/lib/payment/saferpay/db/SaferpayTransactionsCollection.js +5 -0
- package/lib/payment/saferpay/db/SaferpayTransactionsCollection.js.map +1 -0
- package/lib/payment/saferpay/getReturnPath.d.ts +3 -0
- package/lib/payment/saferpay/getReturnPath.js +4 -0
- package/lib/payment/saferpay/getReturnPath.js.map +1 -0
- package/lib/payment/saferpay/index.d.ts +3 -0
- package/lib/payment/saferpay/index.js +4 -0
- package/lib/payment/saferpay/index.js.map +1 -0
- package/lib/payment/saferpay/middleware.d.ts +1 -0
- package/lib/payment/saferpay/middleware.js +57 -0
- package/lib/payment/saferpay/middleware.js.map +1 -0
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts +9 -0
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js +24 -0
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js.map +1 -0
- package/lib/plugins-index.d.ts +0 -1
- package/lib/plugins-index.js +6 -2
- package/lib/plugins-index.js.map +1 -1
- package/lib/worker/email.js +1 -1
- package/lib/worker/email.js.map +1 -1
- package/package.json +18 -18
- package/src/payment/saferpay/adapter.ts +255 -0
- package/src/payment/saferpay/api/api/SaferpayClient.ts +79 -0
- package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/api/SaferpayConnection.ts +2 -4
- package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentPageInitialize.ts +9 -6
- package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Response.ts +1 -1
- package/src/payment/saferpay/api/models/TransactionCapture.ts +20 -0
- package/src/payment/saferpay/buildSignature.ts +9 -0
- package/src/payment/saferpay/db/SaferpayTransactionsCollection.ts +13 -0
- package/src/payment/saferpay/getReturnPath.ts +10 -0
- package/src/payment/saferpay/index.ts +3 -0
- package/src/payment/saferpay/middleware.ts +74 -0
- package/src/payment/saferpay/module/configureSaferpayTransactionsModule.ts +33 -0
- package/src/plugins-index.ts +7 -2
- package/src/worker/email.ts +1 -1
- package/lib/payment/worldline-saferpay/index.d.ts +0 -1
- package/lib/payment/worldline-saferpay/index.js +0 -112
- package/lib/payment/worldline-saferpay/index.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/api/SaferpayClient.d.ts +0 -14
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/api/SaferpayClient.js +0 -29
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/api/SaferpayClient.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/api/SaferpayConnection.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/index.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/models/PaymentMethods.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/models/PaymentPageAssert.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/models/PaymentPageInitialize.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/models/Request.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/models/Response.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/models/Transaction.js.map +0 -1
- package/lib/payment/worldline-saferpay/worldline-saferpay-client/models/TransactionCancel.js.map +0 -1
- package/src/payment/worldline-saferpay/index.ts +0 -139
- package/src/payment/worldline-saferpay/worldline-saferpay-client/api/SaferpayClient.ts +0 -54
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/api/SaferpayConnection.d.ts +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/index.d.ts +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/index.js +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentMethods.d.ts +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentMethods.js +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentPageAssert.d.ts +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentPageAssert.js +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentPageInitialize.js +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Request.d.ts +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Request.js +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Response.js +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Transaction.d.ts +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Transaction.js +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/TransactionCancel.d.ts +0 -0
- /package/lib/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/TransactionCancel.js +0 -0
- /package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/index.ts +0 -0
- /package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentMethods.ts +0 -0
- /package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/PaymentPageAssert.ts +0 -0
- /package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Request.ts +0 -0
- /package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/Transaction.ts +0 -0
- /package/src/payment/{worldline-saferpay/worldline-saferpay-client → saferpay/api}/models/TransactionCancel.ts +0 -0
package/lib/plugins-index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins-index.js","sourceRoot":"","sources":["../src/plugins-index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AAEtF,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,WAAW;AACX,OAAO,oBAAoB,CAAC;AAC5B,OAAO,wBAAwB,CAAC;AAChC,OAAO,4BAA4B,CAAC;AACpC,OAAO,sBAAsB,CAAC;AAE9B,UAAU;AACV,OAAO,sBAAsB,CAAC;AAC9B,OAAO,8BAA8B,CAAC;AACtC,OAAO,8BAA8B,CAAC;AACtC,OAAO,
|
|
1
|
+
{"version":3,"file":"plugins-index.js","sourceRoot":"","sources":["../src/plugins-index.ts"],"names":[],"mappings":"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"}
|
package/lib/worker/email.js
CHANGED
|
@@ -17,7 +17,7 @@ const buildLink = ({ filename, content, href, contentType, encoding, path }) =>
|
|
|
17
17
|
return `<a href="${href}">${filename}</a>`;
|
|
18
18
|
}
|
|
19
19
|
if (content && encoding === 'base64') {
|
|
20
|
-
return `<a target="_blank" href="${`data:${contentType};base64,${content}
|
|
20
|
+
return `<a target="_blank" href="${`data:${contentType};base64,${content}`}">${filename}</a>`;
|
|
21
21
|
}
|
|
22
22
|
return '';
|
|
23
23
|
};
|
package/lib/worker/email.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/worker/email.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,UAAU,MAAM,YAAY,CAAC;AAEpC,MAAM,MAAM,GAAG,YAAY,CAAC,gCAAgC,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,EAAE;IAChD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC;AACpG,CAAC,CAAC;AAEF,MAAM,SAAS,GAAG,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE;IAC7E,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,YAAY,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,KAAK,QAAQ,MAAM,CAAC;IAC5F,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,YAAY,IAAI,KAAK,QAAQ,MAAM,CAAC;IAC7C,CAAC;IACD,IAAI,OAAO,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,4BAA4B,QAAQ,WAAW,WAAW,OAAO,
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../../src/worker/email.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/plugins",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.18",
|
|
4
4
|
"main": "lib/plugins-index.js",
|
|
5
5
|
"types": "lib/plugins-index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -87,23 +87,23 @@
|
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
89
|
"@redis/client": "^1.5.14",
|
|
90
|
-
"@types/node": "^20.12.
|
|
91
|
-
"@unchainedshop/api": "^2.8.
|
|
92
|
-
"@unchainedshop/core-delivery": "^2.8.
|
|
93
|
-
"@unchainedshop/core-enrollments": "^2.8.
|
|
94
|
-
"@unchainedshop/core-filters": "^2.8.
|
|
95
|
-
"@unchainedshop/core-messaging": "^2.8.
|
|
96
|
-
"@unchainedshop/core-orders": "^2.8.
|
|
97
|
-
"@unchainedshop/core-payment": "^2.8.
|
|
98
|
-
"@unchainedshop/core-products": "^2.8.
|
|
99
|
-
"@unchainedshop/core-quotations": "^2.8.
|
|
100
|
-
"@unchainedshop/core-warehousing": "^2.8.
|
|
101
|
-
"@unchainedshop/core-worker": "^2.8.
|
|
102
|
-
"@unchainedshop/events": "^2.8.
|
|
103
|
-
"@unchainedshop/file-upload": "^2.8.
|
|
104
|
-
"@unchainedshop/logger": "^2.8.
|
|
105
|
-
"@unchainedshop/types": "^2.8.
|
|
106
|
-
"@unchainedshop/utils": "^2.8.
|
|
90
|
+
"@types/node": "^20.12.12",
|
|
91
|
+
"@unchainedshop/api": "^2.8.18",
|
|
92
|
+
"@unchainedshop/core-delivery": "^2.8.18",
|
|
93
|
+
"@unchainedshop/core-enrollments": "^2.8.18",
|
|
94
|
+
"@unchainedshop/core-filters": "^2.8.18",
|
|
95
|
+
"@unchainedshop/core-messaging": "^2.8.18",
|
|
96
|
+
"@unchainedshop/core-orders": "^2.8.18",
|
|
97
|
+
"@unchainedshop/core-payment": "^2.8.18",
|
|
98
|
+
"@unchainedshop/core-products": "^2.8.18",
|
|
99
|
+
"@unchainedshop/core-quotations": "^2.8.18",
|
|
100
|
+
"@unchainedshop/core-warehousing": "^2.8.18",
|
|
101
|
+
"@unchainedshop/core-worker": "^2.8.18",
|
|
102
|
+
"@unchainedshop/events": "^2.8.18",
|
|
103
|
+
"@unchainedshop/file-upload": "^2.8.18",
|
|
104
|
+
"@unchainedshop/logger": "^2.8.18",
|
|
105
|
+
"@unchainedshop/types": "^2.8.18",
|
|
106
|
+
"@unchainedshop/utils": "^2.8.18",
|
|
107
107
|
"bluebird": "^3.7.2",
|
|
108
108
|
"event-iterator": "^2.0.0",
|
|
109
109
|
"express": "^4.19.2",
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { IPaymentAdapter } from '@unchainedshop/types/payments.js';
|
|
2
|
+
import { PaymentAdapter, PaymentDirector, PaymentError } from '@unchainedshop/core-payment';
|
|
3
|
+
import { UnchainedCore } from '@unchainedshop/types/core.js';
|
|
4
|
+
import { mongodb } from '@unchainedshop/mongodb';
|
|
5
|
+
import { PaymentPageInitializeInput, SaferpayClient } from './api/index.js';
|
|
6
|
+
import { buildSignature } from './buildSignature.js';
|
|
7
|
+
import { SaferpayTransactionsModule } from './module/configureSaferpayTransactionsModule.js';
|
|
8
|
+
|
|
9
|
+
export * from './middleware.js';
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
SAFERPAY_BASE_URL = 'https://test.saferpay.com/api',
|
|
13
|
+
SAFERPAY_CUSTOMER_ID,
|
|
14
|
+
SAFERPAY_WEBHOOK_PATH = '/payment/saferpay/webhook',
|
|
15
|
+
SAFERPAY_RETURN_PATH = '/saferpay/return',
|
|
16
|
+
ROOT_URL = 'http://localhost:4010',
|
|
17
|
+
EMAIL_WEBSITE_URL,
|
|
18
|
+
SAFERPAY_USER,
|
|
19
|
+
SAFERPAY_PW,
|
|
20
|
+
} = process.env;
|
|
21
|
+
|
|
22
|
+
const newSaferpayError = ({ code, message }: { code: string; message?: string }) => {
|
|
23
|
+
const error = new Error(message || code);
|
|
24
|
+
error.name = `SAFERPAY_${code}`;
|
|
25
|
+
return error;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const addTransactionId = (urlString, saferpayTransactionId) => {
|
|
29
|
+
const urlWithTransactionId = new URL(urlString);
|
|
30
|
+
urlWithTransactionId.searchParams.append('transactionId', saferpayTransactionId.toString('hex'));
|
|
31
|
+
return urlWithTransactionId.href;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const WordlineSaferpay: IPaymentAdapter = {
|
|
35
|
+
...PaymentAdapter,
|
|
36
|
+
|
|
37
|
+
key: 'shop.unchained.payment.saferpay',
|
|
38
|
+
label: 'Worldline Saferpay API',
|
|
39
|
+
version: '1.40.0',
|
|
40
|
+
|
|
41
|
+
typeSupported(type) {
|
|
42
|
+
return type === 'GENERIC';
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
actions: (params) => {
|
|
46
|
+
const { modules } = params.context as UnchainedCore & {
|
|
47
|
+
modules: { saferpayTransactions: SaferpayTransactionsModule };
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const createSaferPayClient = () => {
|
|
51
|
+
if (!SAFERPAY_CUSTOMER_ID || !SAFERPAY_USER || !SAFERPAY_PW)
|
|
52
|
+
throw new Error('Credentials not Set');
|
|
53
|
+
const saferpayClient = new SaferpayClient(
|
|
54
|
+
SAFERPAY_BASE_URL,
|
|
55
|
+
SAFERPAY_CUSTOMER_ID,
|
|
56
|
+
SAFERPAY_USER,
|
|
57
|
+
SAFERPAY_PW,
|
|
58
|
+
);
|
|
59
|
+
return saferpayClient;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const adapter = {
|
|
63
|
+
...PaymentAdapter.actions(params),
|
|
64
|
+
|
|
65
|
+
getTerminalId() {
|
|
66
|
+
return params.config.find((item) => item.key === 'terminalId')?.value;
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
// eslint-disable-next-line
|
|
70
|
+
configurationError() {
|
|
71
|
+
// eslint-disable-line
|
|
72
|
+
if (
|
|
73
|
+
!SAFERPAY_BASE_URL ||
|
|
74
|
+
!SAFERPAY_CUSTOMER_ID ||
|
|
75
|
+
!SAFERPAY_USER ||
|
|
76
|
+
!SAFERPAY_PW ||
|
|
77
|
+
!adapter.getTerminalId()
|
|
78
|
+
) {
|
|
79
|
+
return PaymentError.INCOMPLETE_CONFIGURATION;
|
|
80
|
+
}
|
|
81
|
+
return null as unknown as PaymentError;
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
isActive() {
|
|
85
|
+
if (adapter.configurationError() === null) return true;
|
|
86
|
+
return false;
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
isPayLaterAllowed() {
|
|
90
|
+
return false;
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
sign: async (transactionContext: any = {}) => {
|
|
94
|
+
const { orderPayment, order } = params.paymentContext;
|
|
95
|
+
|
|
96
|
+
if (!orderPayment || !order) {
|
|
97
|
+
throw new Error('orderPayment or order not found');
|
|
98
|
+
}
|
|
99
|
+
const pricing = modules.orders.pricingSheet(order);
|
|
100
|
+
const totalAmount = pricing?.total({ useNetPrice: false }).amount;
|
|
101
|
+
|
|
102
|
+
const saferpayTransactionId = await modules.saferpayTransactions.createTransaction(
|
|
103
|
+
orderPayment._id,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const signature = await buildSignature(saferpayTransactionId.toString('hex'), orderPayment._id);
|
|
107
|
+
const paymentPageInitInput: PaymentPageInitializeInput = {
|
|
108
|
+
...(transactionContext || {}),
|
|
109
|
+
TerminalId: adapter.getTerminalId(),
|
|
110
|
+
Payment: {
|
|
111
|
+
Amount: {
|
|
112
|
+
Value: totalAmount.toString(),
|
|
113
|
+
CurrencyCode: order.currency,
|
|
114
|
+
},
|
|
115
|
+
OrderId: order._id,
|
|
116
|
+
Description: transactionContext.description || 'Bestellung',
|
|
117
|
+
...(transactionContext?.Payment || {}),
|
|
118
|
+
},
|
|
119
|
+
ReturnUrl: {
|
|
120
|
+
Url: `${EMAIL_WEBSITE_URL || ROOT_URL}${SAFERPAY_RETURN_PATH}`,
|
|
121
|
+
...(transactionContext?.ReturnUrl || {}),
|
|
122
|
+
},
|
|
123
|
+
Notification: {
|
|
124
|
+
SuccessNotifyUrl: `${ROOT_URL}${SAFERPAY_WEBHOOK_PATH}?orderPaymentId=${orderPayment._id}&signature=${signature}`,
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
paymentPageInitInput.ReturnUrl.Url = addTransactionId(
|
|
129
|
+
paymentPageInitInput.ReturnUrl.Url,
|
|
130
|
+
saferpayTransactionId,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
paymentPageInitInput.Notification.SuccessNotifyUrl = addTransactionId(
|
|
134
|
+
paymentPageInitInput.Notification.SuccessNotifyUrl,
|
|
135
|
+
saferpayTransactionId,
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
const api = createSaferPayClient();
|
|
139
|
+
const paymentPageInit = await api.paymentPageInitialize(orderPayment, paymentPageInitInput);
|
|
140
|
+
|
|
141
|
+
await modules.saferpayTransactions.setToken(saferpayTransactionId, paymentPageInit.Token);
|
|
142
|
+
|
|
143
|
+
return JSON.stringify({
|
|
144
|
+
location: paymentPageInit.RedirectUrl,
|
|
145
|
+
token: paymentPageInit.Token,
|
|
146
|
+
transactionId: saferpayTransactionId.toString('hex'),
|
|
147
|
+
});
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
charge: async ({ transactionId }: { transactionId: string }) => {
|
|
151
|
+
const { orderPayment, order } = params.paymentContext;
|
|
152
|
+
|
|
153
|
+
if (!orderPayment || !order) {
|
|
154
|
+
throw new Error('orderPayment or order not found');
|
|
155
|
+
}
|
|
156
|
+
const pricing = modules.orders.pricingSheet(order);
|
|
157
|
+
const totalAmount = pricing.total({ useNetPrice: false }).amount;
|
|
158
|
+
|
|
159
|
+
const saferpayTransaction = await modules.saferpayTransactions.findTransactionById(
|
|
160
|
+
mongodb.ObjectId.createFromHexString(transactionId),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
const api = createSaferPayClient();
|
|
164
|
+
const paymentPageAssert = await api.paymentPageAssert(orderPayment, {
|
|
165
|
+
Token: saferpayTransaction.token,
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const success =
|
|
169
|
+
!paymentPageAssert.ErrorMessage &&
|
|
170
|
+
paymentPageAssert.Transaction.Amount.Value === totalAmount.toString() &&
|
|
171
|
+
paymentPageAssert.Transaction.Amount.CurrencyCode === order.currency &&
|
|
172
|
+
(paymentPageAssert.Transaction.Status === 'AUTHORIZED' ||
|
|
173
|
+
paymentPageAssert.Transaction.Status === 'CAPTURED');
|
|
174
|
+
if (success) {
|
|
175
|
+
return {
|
|
176
|
+
transactionId,
|
|
177
|
+
settledTransaction: paymentPageAssert.Transaction,
|
|
178
|
+
// arbitraryFields,
|
|
179
|
+
// credentials,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
throw newSaferpayError({
|
|
184
|
+
code: paymentPageAssert.ErrorName || `WRONG_STATUS_${paymentPageAssert.Transaction.Status}`,
|
|
185
|
+
message: paymentPageAssert.ErrorMessage,
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
async confirm() {
|
|
190
|
+
const { orderPayment } = params.paymentContext;
|
|
191
|
+
|
|
192
|
+
if (!orderPayment) {
|
|
193
|
+
throw new Error('orderPayment not found');
|
|
194
|
+
}
|
|
195
|
+
const { transactionId } = orderPayment;
|
|
196
|
+
if (!transactionId) return false;
|
|
197
|
+
|
|
198
|
+
const saferpayTransaction = await modules.saferpayTransactions.findTransactionById(
|
|
199
|
+
mongodb.ObjectId.createFromHexString(transactionId),
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const api = createSaferPayClient();
|
|
203
|
+
const paymentPageAssert = await api.paymentPageAssert(orderPayment, {
|
|
204
|
+
Token: saferpayTransaction.token,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
if (paymentPageAssert.Behavior === 'DO_NOT_RETRY') return false;
|
|
208
|
+
|
|
209
|
+
if (paymentPageAssert.Transaction.Status !== 'AUTHORIZED') return false;
|
|
210
|
+
const transactionCaptureRes = await api.transactionCapture(orderPayment, {
|
|
211
|
+
TransactionReference: {
|
|
212
|
+
TransactionId: paymentPageAssert.Transaction.Id,
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
return transactionCaptureRes.Status === 'CAPTURED';
|
|
217
|
+
},
|
|
218
|
+
|
|
219
|
+
cancel: async () => {
|
|
220
|
+
const { orderPayment } = params.paymentContext;
|
|
221
|
+
|
|
222
|
+
if (!orderPayment) {
|
|
223
|
+
throw new Error('orderPayment not found');
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const { transactionId } = orderPayment;
|
|
227
|
+
if (!transactionId) return false;
|
|
228
|
+
|
|
229
|
+
const saferpayTransaction = await modules.saferpayTransactions.findTransactionById(
|
|
230
|
+
mongodb.ObjectId.createFromHexString(transactionId),
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
const api = createSaferPayClient();
|
|
234
|
+
const paymentPageAssert = await api.paymentPageAssert(orderPayment, {
|
|
235
|
+
Token: saferpayTransaction.token,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
if (paymentPageAssert.Behavior === 'DO_NOT_RETRY') return false;
|
|
239
|
+
|
|
240
|
+
if (paymentPageAssert.Transaction.Status !== 'AUTHORIZED') return false;
|
|
241
|
+
const transactionCancelRes = await api.transactionCancel(orderPayment, {
|
|
242
|
+
TransactionReference: {
|
|
243
|
+
TransactionId: paymentPageAssert.Transaction.Id,
|
|
244
|
+
},
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
return transactionCancelRes.TransactionId === transactionId;
|
|
248
|
+
},
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
return adapter;
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
PaymentDirector.registerAdapter(WordlineSaferpay);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { OrderPayment } from '@unchainedshop/types/orders.payments.js';
|
|
2
|
+
import { TransactionCancelInput, TransactionCancelResponse } from '../models/TransactionCancel.js';
|
|
3
|
+
import { TransactionCaptureInput, TransactionCaptureResponse } from '../models/TransactionCapture.js';
|
|
4
|
+
import { PaymentPageAssertInput, PaymentPageAssertResponse } from '../models/PaymentPageAssert.js';
|
|
5
|
+
import {
|
|
6
|
+
PaymentPageInitializeInput,
|
|
7
|
+
PaymentPageInitializeResponse,
|
|
8
|
+
} from '../models/PaymentPageInitialize.js';
|
|
9
|
+
import { RequestHeader } from '../models/Request.js';
|
|
10
|
+
import { SaferpayConnection } from './SaferpayConnection.js';
|
|
11
|
+
|
|
12
|
+
export class SaferpayClient {
|
|
13
|
+
private conn: SaferpayConnection;
|
|
14
|
+
|
|
15
|
+
private customerId: string;
|
|
16
|
+
|
|
17
|
+
private specVersion: string;
|
|
18
|
+
|
|
19
|
+
public constructor(
|
|
20
|
+
baseUrl: string,
|
|
21
|
+
customerId: string,
|
|
22
|
+
user: string,
|
|
23
|
+
password: string,
|
|
24
|
+
specVersion?: string,
|
|
25
|
+
) {
|
|
26
|
+
this.customerId = customerId;
|
|
27
|
+
this.specVersion = specVersion || '1.40';
|
|
28
|
+
this.conn = new SaferpayConnection(baseUrl, user, password);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public buildRequestHeader(requestId: string, retryIndicator: number): RequestHeader {
|
|
32
|
+
return {
|
|
33
|
+
SpecVersion: this.specVersion,
|
|
34
|
+
CustomerId: this.customerId,
|
|
35
|
+
RequestId: requestId,
|
|
36
|
+
RetryIndicator: retryIndicator,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public async paymentPageInitialize(
|
|
41
|
+
orderPayment: OrderPayment,
|
|
42
|
+
input: Omit<PaymentPageInitializeInput, 'RequestHeader'>,
|
|
43
|
+
): Promise<PaymentPageInitializeResponse> {
|
|
44
|
+
return this.conn.post('/Payment/v1/PaymentPage/Initialize', {
|
|
45
|
+
...input,
|
|
46
|
+
RequestHeader: this.buildRequestHeader(orderPayment._id, 0),
|
|
47
|
+
}) as Promise<PaymentPageInitializeResponse>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public async paymentPageAssert(
|
|
51
|
+
orderPayment: OrderPayment,
|
|
52
|
+
input: Omit<PaymentPageAssertInput, 'RequestHeader'>,
|
|
53
|
+
): Promise<PaymentPageAssertResponse> {
|
|
54
|
+
return this.conn.post('/Payment/v1/PaymentPage/Assert', {
|
|
55
|
+
...input,
|
|
56
|
+
RequestHeader: this.buildRequestHeader(orderPayment._id, 0),
|
|
57
|
+
}) as Promise<PaymentPageAssertResponse>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public async transactionCancel(
|
|
61
|
+
orderPayment: OrderPayment,
|
|
62
|
+
input: Omit<TransactionCancelInput, 'RequestHeader'>,
|
|
63
|
+
): Promise<TransactionCancelResponse> {
|
|
64
|
+
return this.conn.post('/Payment/v1/Transaction/Cancel', {
|
|
65
|
+
...input,
|
|
66
|
+
RequestHeader: this.buildRequestHeader(orderPayment._id, 0),
|
|
67
|
+
}) as Promise<TransactionCancelResponse>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public async transactionCapture(
|
|
71
|
+
orderPayment: OrderPayment,
|
|
72
|
+
input: Omit<TransactionCaptureInput, 'RequestHeader'>,
|
|
73
|
+
): Promise<TransactionCaptureResponse> {
|
|
74
|
+
return this.conn.post('/Payment/v1/Transaction/Capture', {
|
|
75
|
+
...input,
|
|
76
|
+
RequestHeader: this.buildRequestHeader(orderPayment._id, 0),
|
|
77
|
+
}) as Promise<TransactionCaptureResponse>;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -18,7 +18,8 @@ export class SaferpayConnection {
|
|
|
18
18
|
|
|
19
19
|
private getHeaders() {
|
|
20
20
|
return {
|
|
21
|
-
'Content-Type': 'application/json',
|
|
21
|
+
'Content-Type': 'application/json; charset=utf-8',
|
|
22
|
+
Accept: 'application/json',
|
|
22
23
|
Authorization: `Basic ${Buffer.from(`${this.user}:${this.password}`, 'binary').toString(
|
|
23
24
|
'base64',
|
|
24
25
|
)}`,
|
|
@@ -29,9 +30,6 @@ export class SaferpayConnection {
|
|
|
29
30
|
const res = await fetch(this.buildUrl(uri), {
|
|
30
31
|
method: 'POST',
|
|
31
32
|
body: JSON.stringify(data),
|
|
32
|
-
// eslint-disable-next-line
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
duplex: 'half',
|
|
35
33
|
headers: this.getHeaders(),
|
|
36
34
|
});
|
|
37
35
|
return res.json();
|
|
@@ -32,19 +32,22 @@ export interface PaymentPageInitializeInput extends Request {
|
|
|
32
32
|
Wallets?: string[];
|
|
33
33
|
Payer?: {
|
|
34
34
|
IpAddress?: string;
|
|
35
|
+
Ipv6Address?: string;
|
|
35
36
|
LanguageCode?: string;
|
|
37
|
+
BillingAddress?: Map<string, string>;
|
|
38
|
+
DeliveryAddress?: Map<string, string>;
|
|
36
39
|
};
|
|
37
|
-
BillingAddress?: Map<string, string>;
|
|
38
|
-
DeliveryAddress?: Map<string, string>;
|
|
39
40
|
RegisterAlias?: {
|
|
40
41
|
IdGenerator: 'MANUAL' | 'RANDOM' | 'RANDOM_UNIQUE';
|
|
41
42
|
Id?: string;
|
|
42
43
|
Lifetime?: number;
|
|
43
44
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
ReturnUrl: {
|
|
46
|
+
Url: string;
|
|
47
|
+
};
|
|
48
|
+
Notification?: {
|
|
49
|
+
SuccessNotifyUrl?: string;
|
|
50
|
+
FailNotifyUrl?: string;
|
|
48
51
|
};
|
|
49
52
|
}
|
|
50
53
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Response } from './Response.js';
|
|
2
|
+
import { Request } from './Request.js';
|
|
3
|
+
import type { TransactionAmount } from './Transaction.js';
|
|
4
|
+
|
|
5
|
+
export interface TransactionCaptureInput extends Request {
|
|
6
|
+
TransactionReference: {
|
|
7
|
+
TransactionId: string;
|
|
8
|
+
OrderId?: string;
|
|
9
|
+
};
|
|
10
|
+
Amount?: TransactionAmount;
|
|
11
|
+
Marketplace?: any; // TODO: Implement Marketplace type
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface TransactionCaptureResponse extends Response {
|
|
15
|
+
CaptureId: string;
|
|
16
|
+
Status: 'PENDING' | 'CAPTURED';
|
|
17
|
+
OrderId?: string;
|
|
18
|
+
Date: string;
|
|
19
|
+
Invoice?: any;
|
|
20
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const buildSignature = async (transactionId, orderPaymentId) => {
|
|
2
|
+
const payload = [transactionId, orderPaymentId, process.env.SAFERPAY_PW].filter(Boolean).join(':');
|
|
3
|
+
|
|
4
|
+
const msgUint8 = new TextEncoder().encode(payload);
|
|
5
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', msgUint8);
|
|
6
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
7
|
+
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');
|
|
8
|
+
return hashHex;
|
|
9
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { mongodb } from '@unchainedshop/mongodb';
|
|
2
|
+
import { TimestampFields } from '@unchainedshop/types/common.js';
|
|
3
|
+
|
|
4
|
+
export type SaferpayTransaction = {
|
|
5
|
+
orderPaymentId: any;
|
|
6
|
+
token?: string;
|
|
7
|
+
} & TimestampFields;
|
|
8
|
+
|
|
9
|
+
export const SaferpayTransactionsCollection = async (db: mongodb.Db) => {
|
|
10
|
+
const SaferpayTransactions = db.collection<SaferpayTransaction>('payment_saferpay_transactions');
|
|
11
|
+
|
|
12
|
+
return SaferpayTransactions;
|
|
13
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const {
|
|
2
|
+
ROOT_URL,
|
|
3
|
+
SAFERPAY_WEBHOOK_PATH = '/payment/saferpay/webhook',
|
|
4
|
+
SAFERPAY_RETURN_PATH = '/saferpay/return',
|
|
5
|
+
} = process.env;
|
|
6
|
+
|
|
7
|
+
export const webhookPath = (orderPaymentId) =>
|
|
8
|
+
`${ROOT_URL}${SAFERPAY_WEBHOOK_PATH}?orderPaymentId=${orderPaymentId}`;
|
|
9
|
+
|
|
10
|
+
export default (): string => `${ROOT_URL}${SAFERPAY_RETURN_PATH}`;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Context } from '@unchainedshop/types/api.js';
|
|
2
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
3
|
+
import { buildSignature } from './buildSignature.js';
|
|
4
|
+
import { SaferpayTransactionsModule } from './module/configureSaferpayTransactionsModule.js';
|
|
5
|
+
|
|
6
|
+
const logger = createLogger('unchained:core-payment:saferpay:webhook');
|
|
7
|
+
|
|
8
|
+
export const saferpayHandler = async (request, response) => {
|
|
9
|
+
const resolvedContext = request.unchainedContext as Context & {
|
|
10
|
+
modules: { saferpayTransactions: SaferpayTransactionsModule };
|
|
11
|
+
};
|
|
12
|
+
const { modules } = resolvedContext;
|
|
13
|
+
|
|
14
|
+
const { orderPaymentId, signature, transactionId } = request.query;
|
|
15
|
+
const isValidRequest =
|
|
16
|
+
typeof orderPaymentId === 'string' &&
|
|
17
|
+
typeof signature === 'string' &&
|
|
18
|
+
typeof transactionId === 'string' &&
|
|
19
|
+
orderPaymentId &&
|
|
20
|
+
transactionId &&
|
|
21
|
+
signature;
|
|
22
|
+
|
|
23
|
+
if ((request.method !== 'GET' && request.method !== 'HEAD') || !isValidRequest) {
|
|
24
|
+
logger.warn(`unhandled http method ${request.method} or orderPaymentId missing in query`);
|
|
25
|
+
response.writeHead(404);
|
|
26
|
+
response.end();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
logger.verbose(`checkout with orderPaymentId: ${orderPaymentId}`);
|
|
32
|
+
const orderPayment = await modules.orders.payments.findOrderPayment({
|
|
33
|
+
orderPaymentId,
|
|
34
|
+
});
|
|
35
|
+
if (!orderPayment) {
|
|
36
|
+
throw new Error(`order payment not found with orderPaymentId: ${orderPaymentId}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const correctSignature = await buildSignature(transactionId, orderPaymentId);
|
|
40
|
+
|
|
41
|
+
if (correctSignature !== signature) {
|
|
42
|
+
throw new Error('Invalid signature');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const order = await modules.orders.checkout(
|
|
46
|
+
orderPayment.orderId,
|
|
47
|
+
{
|
|
48
|
+
paymentContext: {
|
|
49
|
+
transactionId,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
resolvedContext,
|
|
53
|
+
);
|
|
54
|
+
logger.info(`checkout successful`, {
|
|
55
|
+
orderPaymentId,
|
|
56
|
+
orderId: order._id,
|
|
57
|
+
});
|
|
58
|
+
response.writeHead(200);
|
|
59
|
+
response.end(
|
|
60
|
+
JSON.stringify({
|
|
61
|
+
message: 'checkout successful',
|
|
62
|
+
orderPaymentId,
|
|
63
|
+
orderId: order._id,
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
logger.error(error, {
|
|
68
|
+
orderPaymentId,
|
|
69
|
+
transactionId,
|
|
70
|
+
});
|
|
71
|
+
response.writeHead(500);
|
|
72
|
+
response.end(error.message);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { mongodb } from '@unchainedshop/mongodb';
|
|
2
|
+
import { SaferpayTransactionsCollection } from '../db/SaferpayTransactionsCollection.js';
|
|
3
|
+
|
|
4
|
+
export const configureSaferpayTransactionsModule = async ({ db }: { db: mongodb.Db }) => {
|
|
5
|
+
const SaferpayTransactions = await SaferpayTransactionsCollection(db);
|
|
6
|
+
|
|
7
|
+
return {
|
|
8
|
+
findTransactionById: async (_id: mongodb.ObjectId) => {
|
|
9
|
+
return SaferpayTransactions.findOne({
|
|
10
|
+
_id,
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
createTransaction: async (orderPaymentId) => {
|
|
15
|
+
const result = await SaferpayTransactions.insertOne({
|
|
16
|
+
created: new Date(),
|
|
17
|
+
orderPaymentId,
|
|
18
|
+
});
|
|
19
|
+
return result.insertedId;
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
setToken: async (_id: mongodb.ObjectId, token: string) => {
|
|
23
|
+
await SaferpayTransactions.updateOne(
|
|
24
|
+
{ _id },
|
|
25
|
+
{
|
|
26
|
+
$set: { token, updated: new Date() },
|
|
27
|
+
},
|
|
28
|
+
);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type SaferpayTransactionsModule = Awaited<ReturnType<typeof configureSaferpayTransactionsModule>>;
|