@develit-services/bank 0.0.13 → 0.0.14
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/dist/export/worker.cjs +1 -1
- package/dist/export/worker.d.cts +1 -1
- package/dist/export/worker.d.mts +1 -1
- package/dist/export/worker.d.ts +1 -1
- package/dist/export/worker.mjs +1 -1
- package/dist/export/wrangler.d.cts +4 -3
- package/dist/export/wrangler.d.mts +4 -3
- package/dist/export/wrangler.d.ts +4 -3
- package/dist/shared/{bank.DxGqqFhD.d.cts → bank.CJFy17-g.d.cts} +3 -1
- package/dist/shared/{bank.DxGqqFhD.d.mts → bank.CJFy17-g.d.mts} +3 -1
- package/dist/shared/{bank.DxGqqFhD.d.ts → bank.CJFy17-g.d.ts} +3 -1
- package/dist/shared/{bank.BU2_AKRG.cjs → bank.DD0U00q7.cjs} +256 -255
- package/dist/shared/{bank.TOYdvcg7.mjs → bank.D_KtNZfn.mjs} +257 -256
- package/dist/{@types.cjs → types.cjs} +3 -2
- package/dist/{@types.d.cts → types.d.cts} +13 -8
- package/dist/{@types.d.mts → types.d.mts} +13 -8
- package/dist/{@types.d.ts → types.d.ts} +13 -8
- package/dist/{@types.mjs → types.mjs} +3 -2
- package/package.json +4 -4
- package/dist/shared/{bank.BYxCT5rk.d.ts → bank.BZqjlltW.d.ts} +4 -4
- package/dist/shared/{bank.Dxfp5h5B.d.mts → bank.CKtJPLds.d.mts} +4 -4
- package/dist/shared/{bank.BULPVep1.d.cts → bank.CXskd9OZ.d.cts} +4 -4
package/dist/export/worker.cjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
const backendSdk = require('@develit-io/backend-sdk');
|
|
6
|
-
const db = require('../shared/bank.
|
|
6
|
+
const db = require('../shared/bank.DD0U00q7.cjs');
|
|
7
7
|
const cloudflare_workers = require('cloudflare:workers');
|
|
8
8
|
const d1 = require('drizzle-orm/d1');
|
|
9
9
|
const zod = require('zod');
|
package/dist/export/worker.d.cts
CHANGED
|
@@ -4,7 +4,7 @@ import { P as PaymentSelectType, B as BatchSelectType, t as tables, a as Payment
|
|
|
4
4
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
5
5
|
import { DrizzleD1Database } from 'drizzle-orm/d1';
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import { C as ConfigEnvironmentBankAccount, I as IBankConnector, a as ConfigBankAccount, b as ConnectorKey, B as BankAccountWithLastSync } from '../shared/bank.
|
|
7
|
+
import { C as ConfigEnvironmentBankAccount, I as IBankConnector, a as ConfigBankAccount, b as ConnectorKey, B as BankAccountWithLastSync } from '../shared/bank.CXskd9OZ.cjs';
|
|
8
8
|
import 'drizzle-orm/sqlite-core';
|
|
9
9
|
import 'drizzle-orm';
|
|
10
10
|
import '@develit-io/general-codes';
|
package/dist/export/worker.d.mts
CHANGED
|
@@ -4,7 +4,7 @@ import { P as PaymentSelectType, B as BatchSelectType, t as tables, a as Payment
|
|
|
4
4
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
5
5
|
import { DrizzleD1Database } from 'drizzle-orm/d1';
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import { C as ConfigEnvironmentBankAccount, I as IBankConnector, a as ConfigBankAccount, b as ConnectorKey, B as BankAccountWithLastSync } from '../shared/bank.
|
|
7
|
+
import { C as ConfigEnvironmentBankAccount, I as IBankConnector, a as ConfigBankAccount, b as ConnectorKey, B as BankAccountWithLastSync } from '../shared/bank.CKtJPLds.mjs';
|
|
8
8
|
import 'drizzle-orm/sqlite-core';
|
|
9
9
|
import 'drizzle-orm';
|
|
10
10
|
import '@develit-io/general-codes';
|
package/dist/export/worker.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { P as PaymentSelectType, B as BatchSelectType, t as tables, a as Payment
|
|
|
4
4
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
5
5
|
import { DrizzleD1Database } from 'drizzle-orm/d1';
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import { C as ConfigEnvironmentBankAccount, I as IBankConnector, a as ConfigBankAccount, b as ConnectorKey, B as BankAccountWithLastSync } from '../shared/bank.
|
|
7
|
+
import { C as ConfigEnvironmentBankAccount, I as IBankConnector, a as ConfigBankAccount, b as ConnectorKey, B as BankAccountWithLastSync } from '../shared/bank.BZqjlltW.js';
|
|
8
8
|
import 'drizzle-orm/sqlite-core';
|
|
9
9
|
import 'drizzle-orm';
|
|
10
10
|
import '@develit-io/general-codes';
|
package/dist/export/worker.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { uuidv4, useResult, createInternalError, develitWorker, first, RPCResponse, action } from '@develit-io/backend-sdk';
|
|
2
|
-
import { P as PAYMENT_TYPES, t as tables, F as FinbricksConnector, M as MockConnector, a as MockCobsConnector, E as ErsteConnector, g as getPaymentDirection } from '../shared/bank.
|
|
2
|
+
import { P as PAYMENT_TYPES, t as tables, F as FinbricksConnector, M as MockConnector, a as MockCobsConnector, E as ErsteConnector, g as getPaymentDirection } from '../shared/bank.D_KtNZfn.mjs';
|
|
3
3
|
import { WorkerEntrypoint } from 'cloudflare:workers';
|
|
4
4
|
import { drizzle } from 'drizzle-orm/d1';
|
|
5
5
|
import { z } from 'zod';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BankServiceWranglerConfig } from '../shared/bank.
|
|
1
|
+
import { B as BankServiceWranglerConfig } from '../shared/bank.CJFy17-g.cjs';
|
|
2
2
|
|
|
3
3
|
declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
4
4
|
vars: {
|
|
@@ -17,7 +17,9 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
17
17
|
ERSTE_CLIENT_SECRET: string;
|
|
18
18
|
ERSTE_CLIENT_ID: string;
|
|
19
19
|
};
|
|
20
|
-
triggers:
|
|
20
|
+
triggers: {
|
|
21
|
+
crons: string[];
|
|
22
|
+
};
|
|
21
23
|
kv_namespaces: {
|
|
22
24
|
binding: string;
|
|
23
25
|
id: string;
|
|
@@ -54,7 +56,6 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
54
56
|
invocation_logs: boolean;
|
|
55
57
|
};
|
|
56
58
|
};
|
|
57
|
-
preview_urls: boolean;
|
|
58
59
|
workers_dev: boolean;
|
|
59
60
|
keep_vars: boolean;
|
|
60
61
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BankServiceWranglerConfig } from '../shared/bank.
|
|
1
|
+
import { B as BankServiceWranglerConfig } from '../shared/bank.CJFy17-g.mjs';
|
|
2
2
|
|
|
3
3
|
declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
4
4
|
vars: {
|
|
@@ -17,7 +17,9 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
17
17
|
ERSTE_CLIENT_SECRET: string;
|
|
18
18
|
ERSTE_CLIENT_ID: string;
|
|
19
19
|
};
|
|
20
|
-
triggers:
|
|
20
|
+
triggers: {
|
|
21
|
+
crons: string[];
|
|
22
|
+
};
|
|
21
23
|
kv_namespaces: {
|
|
22
24
|
binding: string;
|
|
23
25
|
id: string;
|
|
@@ -54,7 +56,6 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
54
56
|
invocation_logs: boolean;
|
|
55
57
|
};
|
|
56
58
|
};
|
|
57
|
-
preview_urls: boolean;
|
|
58
59
|
workers_dev: boolean;
|
|
59
60
|
keep_vars: boolean;
|
|
60
61
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BankServiceWranglerConfig } from '../shared/bank.
|
|
1
|
+
import { B as BankServiceWranglerConfig } from '../shared/bank.CJFy17-g.js';
|
|
2
2
|
|
|
3
3
|
declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
4
4
|
vars: {
|
|
@@ -17,7 +17,9 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
17
17
|
ERSTE_CLIENT_SECRET: string;
|
|
18
18
|
ERSTE_CLIENT_ID: string;
|
|
19
19
|
};
|
|
20
|
-
triggers:
|
|
20
|
+
triggers: {
|
|
21
|
+
crons: string[];
|
|
22
|
+
};
|
|
21
23
|
kv_namespaces: {
|
|
22
24
|
binding: string;
|
|
23
25
|
id: string;
|
|
@@ -54,7 +56,6 @@ declare function defineBankServiceWrangler(config: BankServiceWranglerConfig): {
|
|
|
54
56
|
invocation_logs: boolean;
|
|
55
57
|
};
|
|
56
58
|
};
|
|
57
|
-
preview_urls: boolean;
|
|
58
59
|
workers_dev: boolean;
|
|
59
60
|
keep_vars: boolean;
|
|
60
61
|
};
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
const backendSdk = require('@develit-io/backend-sdk');
|
|
4
4
|
const database_schema = require('./bank.CrAQe4PH.cjs');
|
|
5
5
|
const drizzleOrm = require('drizzle-orm');
|
|
6
|
+
const zod = require('zod');
|
|
7
|
+
const generalCodes = require('@develit-io/general-codes');
|
|
8
|
+
require('superjson');
|
|
6
9
|
const dateFns = require('date-fns');
|
|
7
10
|
const jose = require('jose');
|
|
8
|
-
const generalCodes = require('@develit-io/general-codes');
|
|
9
|
-
const zod = require('zod');
|
|
10
11
|
|
|
11
12
|
const tables = database_schema.schema;
|
|
12
13
|
|
|
@@ -34,14 +35,6 @@ const COUNTRY_CODES = generalCodes.COUNTRY_CODES_2;
|
|
|
34
35
|
class IBankConnector {
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
const isDeposit = (payment, creditorIban) => {
|
|
38
|
-
return payment.creditorIban === creditorIban;
|
|
39
|
-
};
|
|
40
|
-
const getPaymentDirection = (payment, iban) => {
|
|
41
|
-
if (isDeposit(payment, iban)) return "INCOMING";
|
|
42
|
-
return "OUTGOING";
|
|
43
|
-
};
|
|
44
|
-
|
|
45
38
|
const mapReferencesToPayment = (reference) => {
|
|
46
39
|
const symbols = {
|
|
47
40
|
vs: void 0,
|
|
@@ -65,251 +58,6 @@ const mapReferencesToPayment = (reference) => {
|
|
|
65
58
|
return symbols;
|
|
66
59
|
};
|
|
67
60
|
|
|
68
|
-
class ErsteConnector extends IBankConnector {
|
|
69
|
-
constructor(config) {
|
|
70
|
-
super();
|
|
71
|
-
this.connectorKey = "ERSTE";
|
|
72
|
-
this.accessToken = null;
|
|
73
|
-
this.API_KEY = config.API_KEY;
|
|
74
|
-
this.CLIENT_ID = config.CLIENT_ID;
|
|
75
|
-
this.CLIENT_SECRET = config.CLIENT_SECRET;
|
|
76
|
-
this.REDIRECT_URI = config.REDIRECT_URI;
|
|
77
|
-
this.AUTH_URI = config.AUTH_URI;
|
|
78
|
-
this.PAYMENTS_URI = config.PAYMENTS_URI;
|
|
79
|
-
this.ACCOUNTS_URI = config.ACCOUNTS_URI;
|
|
80
|
-
}
|
|
81
|
-
static {
|
|
82
|
-
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
83
|
-
}
|
|
84
|
-
get adminCodeCreationURI() {
|
|
85
|
-
const params = new URLSearchParams({
|
|
86
|
-
redirect_uri: `${this.REDIRECT_URI}`,
|
|
87
|
-
client_id: this.CLIENT_ID,
|
|
88
|
-
response_type: "code",
|
|
89
|
-
access_type: "offline",
|
|
90
|
-
state: "csas-auth",
|
|
91
|
-
prompt: "consent"
|
|
92
|
-
});
|
|
93
|
-
return `${this.AUTH_URI}/auth?${params.toString()}`;
|
|
94
|
-
}
|
|
95
|
-
async authenticate({ token, refreshToken }) {
|
|
96
|
-
const grantType = refreshToken ? "refresh_token" : "authorization_code";
|
|
97
|
-
let bodyParams = {
|
|
98
|
-
client_id: this.CLIENT_ID,
|
|
99
|
-
client_secret: this.CLIENT_SECRET,
|
|
100
|
-
grant_type: grantType
|
|
101
|
-
};
|
|
102
|
-
if (token) {
|
|
103
|
-
bodyParams = {
|
|
104
|
-
...bodyParams,
|
|
105
|
-
code: token,
|
|
106
|
-
redirect_uri: this.REDIRECT_URI
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
if (refreshToken) bodyParams.refresh_token = refreshToken;
|
|
110
|
-
const body = new URLSearchParams(bodyParams);
|
|
111
|
-
const result = await fetch(`${this.AUTH_URI}/token`, {
|
|
112
|
-
method: "POST",
|
|
113
|
-
body: body.toString(),
|
|
114
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded" }
|
|
115
|
-
});
|
|
116
|
-
if (result.status !== 200) {
|
|
117
|
-
throw backendSdk.createInternalError(null, {
|
|
118
|
-
message: await result.text()
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
const json = await result.json();
|
|
122
|
-
this.accessToken = json.access_token;
|
|
123
|
-
return json.refresh_token || "";
|
|
124
|
-
}
|
|
125
|
-
async preparePayment(payment) {
|
|
126
|
-
if (!this.accessToken) {
|
|
127
|
-
throw backendSdk.createInternalError(null, {
|
|
128
|
-
message: "Internal authentication failed",
|
|
129
|
-
status: 500
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
const paymentBody = {
|
|
133
|
-
paymentIdentification: {
|
|
134
|
-
endToEndIdentification: payment.id,
|
|
135
|
-
instructionIdentification: payment.id
|
|
136
|
-
},
|
|
137
|
-
paymentTypeInformation: { instructionPriority: "NORM" },
|
|
138
|
-
amount: {
|
|
139
|
-
instructedAmount: { value: payment.amount, currency: payment.currency }
|
|
140
|
-
},
|
|
141
|
-
debtorAccount: { identification: { iban: payment.debtorIban } },
|
|
142
|
-
creditorAccount: { identification: { iban: payment.creditorIban } },
|
|
143
|
-
creditor: {
|
|
144
|
-
name: payment.creditorHolderName
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
const [data, error] = await backendSdk.useResult(
|
|
148
|
-
fetch(`${this.PAYMENTS_URI}/my/payments`, {
|
|
149
|
-
method: "POST",
|
|
150
|
-
headers: {
|
|
151
|
-
"WEB-API-key": this.API_KEY,
|
|
152
|
-
"Content-Type": "application/json",
|
|
153
|
-
Authorization: `Bearer ${this.accessToken}`
|
|
154
|
-
},
|
|
155
|
-
body: JSON.stringify(paymentBody)
|
|
156
|
-
})
|
|
157
|
-
);
|
|
158
|
-
if (error || !data) {
|
|
159
|
-
throw error;
|
|
160
|
-
}
|
|
161
|
-
const erstePayment = await data.json();
|
|
162
|
-
return {
|
|
163
|
-
...payment,
|
|
164
|
-
id: backendSdk.uuidv4(),
|
|
165
|
-
bankRefId: erstePayment.signInfo?.signId,
|
|
166
|
-
refId: payment.refId,
|
|
167
|
-
direction: "OUTGOING",
|
|
168
|
-
paymentType: "DOMESTIC",
|
|
169
|
-
status: "PREPARED",
|
|
170
|
-
initiatedAt: /* @__PURE__ */ new Date()
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
async initiateBatchFromPayments({
|
|
174
|
-
payments
|
|
175
|
-
}) {
|
|
176
|
-
const allRefIds = payments.map((payment) => payment.bankRefId);
|
|
177
|
-
const batchId = backendSdk.uuidv4();
|
|
178
|
-
if (allRefIds.length === 0) {
|
|
179
|
-
throw backendSdk.createInternalError(null, {
|
|
180
|
-
message: "No valid payments to include in batch",
|
|
181
|
-
status: 400
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
const [signInfo, signError] = await backendSdk.useResult(
|
|
185
|
-
this.sendBatchPaymentForAuthorization(allRefIds)
|
|
186
|
-
);
|
|
187
|
-
if (signError) {
|
|
188
|
-
throw backendSdk.createInternalError(signError);
|
|
189
|
-
}
|
|
190
|
-
const [authUri, authUriError] = await backendSdk.useResult(
|
|
191
|
-
this.getBatchAuthorizationURI(signInfo)
|
|
192
|
-
);
|
|
193
|
-
if (authUriError) {
|
|
194
|
-
throw backendSdk.createInternalError(authUriError);
|
|
195
|
-
}
|
|
196
|
-
return {
|
|
197
|
-
id: batchId,
|
|
198
|
-
authorizationUrls: [authUri || ""],
|
|
199
|
-
payments: payments.map((payment) => ({
|
|
200
|
-
...payment,
|
|
201
|
-
status: "INITIALIZED"
|
|
202
|
-
})),
|
|
203
|
-
metadata: signInfo
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
initiateSinglePayment() {
|
|
207
|
-
throw new Error("Method not implemented.");
|
|
208
|
-
}
|
|
209
|
-
async sendBatchPaymentForAuthorization(paymentIds) {
|
|
210
|
-
const [data, error] = await backendSdk.useResult(
|
|
211
|
-
fetch(`${this.PAYMENTS_URI}/my/batchpayments`, {
|
|
212
|
-
method: "POST",
|
|
213
|
-
headers: {
|
|
214
|
-
"Content-Type": "application/json",
|
|
215
|
-
Authorization: `Bearer ${this.accessToken}`,
|
|
216
|
-
"WEB-API-key": this.CLIENT_SECRET
|
|
217
|
-
},
|
|
218
|
-
body: JSON.stringify({
|
|
219
|
-
exchangeIdentification: "658576010faf0a23dc",
|
|
220
|
-
payments: paymentIds
|
|
221
|
-
})
|
|
222
|
-
})
|
|
223
|
-
);
|
|
224
|
-
if (error) throw error;
|
|
225
|
-
const batch = await data.json();
|
|
226
|
-
return {
|
|
227
|
-
signHash: batch.signInfo.hash,
|
|
228
|
-
signId: batch.signInfo.signId
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
async getBatchAuthorizationURI({
|
|
232
|
-
signId,
|
|
233
|
-
signHash
|
|
234
|
-
}) {
|
|
235
|
-
const [data, error] = await backendSdk.useResult(
|
|
236
|
-
fetch(
|
|
237
|
-
`${this.PAYMENTS_URI}/my/batchpayments/federate/sign/${signId}/hash/${signHash}`,
|
|
238
|
-
{
|
|
239
|
-
method: "GET",
|
|
240
|
-
headers: {
|
|
241
|
-
"Callback-Uri": `${this.REDIRECT_URI}/payment-authorization-complete`,
|
|
242
|
-
Authorization: `Bearer ${this.accessToken}`,
|
|
243
|
-
"WEB-API-key": this.CLIENT_SECRET
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
)
|
|
247
|
-
);
|
|
248
|
-
if (error) {
|
|
249
|
-
throw error;
|
|
250
|
-
}
|
|
251
|
-
return (await data.json()).signingUrl;
|
|
252
|
-
}
|
|
253
|
-
async getAllAccountPayments({
|
|
254
|
-
account,
|
|
255
|
-
lastSync
|
|
256
|
-
}) {
|
|
257
|
-
const erstePayments = [];
|
|
258
|
-
const dateFormat = "yyyy-MM-dd";
|
|
259
|
-
const fromDate = dateFns.format(lastSync.lastSyncedAt, dateFormat);
|
|
260
|
-
const toDate = dateFns.format(/* @__PURE__ */ new Date(), dateFormat);
|
|
261
|
-
let page = 0;
|
|
262
|
-
const pageSize = 200;
|
|
263
|
-
const pageCount = 1;
|
|
264
|
-
while (page < pageCount) {
|
|
265
|
-
const response = await fetch(
|
|
266
|
-
`${this.ACCOUNTS_URI}/my/accounts/${account.id}/transactions?fromDate=${fromDate}&toDate=${toDate}&size=${pageSize}&page=${page}&sort=bookingDate&order=desc`,
|
|
267
|
-
{
|
|
268
|
-
headers: {
|
|
269
|
-
"WEB-API-key": this.API_KEY,
|
|
270
|
-
Authorization: `Bearer ${this.accessToken}`
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
);
|
|
274
|
-
const data = await response.json();
|
|
275
|
-
erstePayments.push(...data.transactions);
|
|
276
|
-
page += 1;
|
|
277
|
-
}
|
|
278
|
-
const payments = erstePayments.map((payment) => {
|
|
279
|
-
const reference = payment.entryDetails.transactionDetails.remittanceInformation?.structured.creditorReferenceInformation?.reference || [];
|
|
280
|
-
const symbols = mapReferencesToPayment(reference);
|
|
281
|
-
const paymentInsert = {
|
|
282
|
-
id: backendSdk.uuidv4(),
|
|
283
|
-
bankRefId: payment.entryReference,
|
|
284
|
-
amount: payment.amount.value,
|
|
285
|
-
currency: payment.amount.currency.code,
|
|
286
|
-
debtorHolderName: payment.entryDetails.transactionDetails.relatedParties.debtor?.name,
|
|
287
|
-
debtorIban: payment.entryDetails.transactionDetails.relatedParties.debtorAccount?.identification.iban,
|
|
288
|
-
debtorAccountNumberWithBankCode: payment.entryDetails.transactionDetails.relatedParties.debtorAccount?.identification.other?.identification,
|
|
289
|
-
creditorHolderName: payment.entryDetails.transactionDetails.relatedParties.creditor?.name || "",
|
|
290
|
-
creditorIban: payment.entryDetails.transactionDetails.relatedParties.creditorAccount?.identification.iban,
|
|
291
|
-
creditorAccountNumberWithBankCode: payment.entryDetails.transactionDetails.relatedParties.creditorAccount?.identification.other?.identification,
|
|
292
|
-
paymentType: "DOMESTIC",
|
|
293
|
-
direction: "INCOMING",
|
|
294
|
-
message: payment.entryDetails.transactionDetails.remittanceInformation?.unstructured,
|
|
295
|
-
vs: symbols.vs,
|
|
296
|
-
ss: symbols.ss,
|
|
297
|
-
ks: symbols.ks,
|
|
298
|
-
processedAt: dateFns.parseISO(payment.bookingDate.date),
|
|
299
|
-
status: "COMPLETED"
|
|
300
|
-
};
|
|
301
|
-
return {
|
|
302
|
-
...paymentInsert,
|
|
303
|
-
direction: getPaymentDirection(
|
|
304
|
-
paymentInsert,
|
|
305
|
-
account.identification.iban
|
|
306
|
-
)
|
|
307
|
-
};
|
|
308
|
-
});
|
|
309
|
-
return payments;
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
|
|
313
61
|
const mapFinbricksStatus = (status) => {
|
|
314
62
|
switch (status) {
|
|
315
63
|
case "BOOK":
|
|
@@ -624,6 +372,259 @@ class FinbricksConnector extends IBankConnector {
|
|
|
624
372
|
}
|
|
625
373
|
}
|
|
626
374
|
|
|
375
|
+
const isDeposit = (payment, creditorIban) => {
|
|
376
|
+
return payment.creditorIban === creditorIban;
|
|
377
|
+
};
|
|
378
|
+
const getPaymentDirection = (payment, iban) => {
|
|
379
|
+
if (isDeposit(payment, iban)) return "INCOMING";
|
|
380
|
+
return "OUTGOING";
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
class ErsteConnector extends IBankConnector {
|
|
384
|
+
constructor(config) {
|
|
385
|
+
super();
|
|
386
|
+
this.connectorKey = "ERSTE";
|
|
387
|
+
this.accessToken = null;
|
|
388
|
+
this.API_KEY = config.API_KEY;
|
|
389
|
+
this.CLIENT_ID = config.CLIENT_ID;
|
|
390
|
+
this.CLIENT_SECRET = config.CLIENT_SECRET;
|
|
391
|
+
this.REDIRECT_URI = config.REDIRECT_URI;
|
|
392
|
+
this.AUTH_URI = config.AUTH_URI;
|
|
393
|
+
this.PAYMENTS_URI = config.PAYMENTS_URI;
|
|
394
|
+
this.ACCOUNTS_URI = config.ACCOUNTS_URI;
|
|
395
|
+
}
|
|
396
|
+
static {
|
|
397
|
+
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
398
|
+
}
|
|
399
|
+
get adminCodeCreationURI() {
|
|
400
|
+
const params = new URLSearchParams({
|
|
401
|
+
redirect_uri: `${this.REDIRECT_URI}`,
|
|
402
|
+
client_id: this.CLIENT_ID,
|
|
403
|
+
response_type: "code",
|
|
404
|
+
access_type: "offline",
|
|
405
|
+
state: "csas-auth",
|
|
406
|
+
prompt: "consent"
|
|
407
|
+
});
|
|
408
|
+
return `${this.AUTH_URI}/auth?${params.toString()}`;
|
|
409
|
+
}
|
|
410
|
+
async authenticate({ token, refreshToken }) {
|
|
411
|
+
const grantType = refreshToken ? "refresh_token" : "authorization_code";
|
|
412
|
+
let bodyParams = {
|
|
413
|
+
client_id: this.CLIENT_ID,
|
|
414
|
+
client_secret: this.CLIENT_SECRET,
|
|
415
|
+
grant_type: grantType
|
|
416
|
+
};
|
|
417
|
+
if (token) {
|
|
418
|
+
bodyParams = {
|
|
419
|
+
...bodyParams,
|
|
420
|
+
code: token,
|
|
421
|
+
redirect_uri: this.REDIRECT_URI
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
if (refreshToken) bodyParams.refresh_token = refreshToken;
|
|
425
|
+
const body = new URLSearchParams(bodyParams);
|
|
426
|
+
const result = await fetch(`${this.AUTH_URI}/token`, {
|
|
427
|
+
method: "POST",
|
|
428
|
+
body: body.toString(),
|
|
429
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" }
|
|
430
|
+
});
|
|
431
|
+
if (result.status !== 200) {
|
|
432
|
+
throw backendSdk.createInternalError(null, {
|
|
433
|
+
message: await result.text()
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
const json = await result.json();
|
|
437
|
+
this.accessToken = json.access_token;
|
|
438
|
+
return json.refresh_token || "";
|
|
439
|
+
}
|
|
440
|
+
async preparePayment(payment) {
|
|
441
|
+
if (!this.accessToken) {
|
|
442
|
+
throw backendSdk.createInternalError(null, {
|
|
443
|
+
message: "Internal authentication failed",
|
|
444
|
+
status: 500
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
const paymentBody = {
|
|
448
|
+
paymentIdentification: {
|
|
449
|
+
endToEndIdentification: payment.id,
|
|
450
|
+
instructionIdentification: payment.id
|
|
451
|
+
},
|
|
452
|
+
paymentTypeInformation: { instructionPriority: "NORM" },
|
|
453
|
+
amount: {
|
|
454
|
+
instructedAmount: { value: payment.amount, currency: payment.currency }
|
|
455
|
+
},
|
|
456
|
+
debtorAccount: { identification: { iban: payment.debtorIban } },
|
|
457
|
+
creditorAccount: { identification: { iban: payment.creditorIban } },
|
|
458
|
+
creditor: {
|
|
459
|
+
name: payment.creditorHolderName
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
const [data, error] = await backendSdk.useResult(
|
|
463
|
+
fetch(`${this.PAYMENTS_URI}/my/payments`, {
|
|
464
|
+
method: "POST",
|
|
465
|
+
headers: {
|
|
466
|
+
"WEB-API-key": this.API_KEY,
|
|
467
|
+
"Content-Type": "application/json",
|
|
468
|
+
Authorization: `Bearer ${this.accessToken}`
|
|
469
|
+
},
|
|
470
|
+
body: JSON.stringify(paymentBody)
|
|
471
|
+
})
|
|
472
|
+
);
|
|
473
|
+
if (error || !data) {
|
|
474
|
+
throw error;
|
|
475
|
+
}
|
|
476
|
+
const erstePayment = await data.json();
|
|
477
|
+
return {
|
|
478
|
+
...payment,
|
|
479
|
+
id: backendSdk.uuidv4(),
|
|
480
|
+
bankRefId: erstePayment.signInfo?.signId,
|
|
481
|
+
refId: payment.refId,
|
|
482
|
+
direction: "OUTGOING",
|
|
483
|
+
paymentType: "DOMESTIC",
|
|
484
|
+
status: "PREPARED",
|
|
485
|
+
initiatedAt: /* @__PURE__ */ new Date()
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
async initiateBatchFromPayments({
|
|
489
|
+
payments
|
|
490
|
+
}) {
|
|
491
|
+
const allRefIds = payments.map((payment) => payment.bankRefId);
|
|
492
|
+
const batchId = backendSdk.uuidv4();
|
|
493
|
+
if (allRefIds.length === 0) {
|
|
494
|
+
throw backendSdk.createInternalError(null, {
|
|
495
|
+
message: "No valid payments to include in batch",
|
|
496
|
+
status: 400
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
const [signInfo, signError] = await backendSdk.useResult(
|
|
500
|
+
this.sendBatchPaymentForAuthorization(allRefIds)
|
|
501
|
+
);
|
|
502
|
+
if (signError) {
|
|
503
|
+
throw backendSdk.createInternalError(signError);
|
|
504
|
+
}
|
|
505
|
+
const [authUri, authUriError] = await backendSdk.useResult(
|
|
506
|
+
this.getBatchAuthorizationURI(signInfo)
|
|
507
|
+
);
|
|
508
|
+
if (authUriError) {
|
|
509
|
+
throw backendSdk.createInternalError(authUriError);
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
id: batchId,
|
|
513
|
+
authorizationUrls: [authUri || ""],
|
|
514
|
+
payments: payments.map((payment) => ({
|
|
515
|
+
...payment,
|
|
516
|
+
status: "INITIALIZED"
|
|
517
|
+
})),
|
|
518
|
+
metadata: signInfo
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
initiateSinglePayment() {
|
|
522
|
+
throw new Error("Method not implemented.");
|
|
523
|
+
}
|
|
524
|
+
async sendBatchPaymentForAuthorization(paymentIds) {
|
|
525
|
+
const [data, error] = await backendSdk.useResult(
|
|
526
|
+
fetch(`${this.PAYMENTS_URI}/my/batchpayments`, {
|
|
527
|
+
method: "POST",
|
|
528
|
+
headers: {
|
|
529
|
+
"Content-Type": "application/json",
|
|
530
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
531
|
+
"WEB-API-key": this.CLIENT_SECRET
|
|
532
|
+
},
|
|
533
|
+
body: JSON.stringify({
|
|
534
|
+
exchangeIdentification: "658576010faf0a23dc",
|
|
535
|
+
payments: paymentIds
|
|
536
|
+
})
|
|
537
|
+
})
|
|
538
|
+
);
|
|
539
|
+
if (error) throw error;
|
|
540
|
+
const batch = await data.json();
|
|
541
|
+
return {
|
|
542
|
+
signHash: batch.signInfo.hash,
|
|
543
|
+
signId: batch.signInfo.signId
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
async getBatchAuthorizationURI({
|
|
547
|
+
signId,
|
|
548
|
+
signHash
|
|
549
|
+
}) {
|
|
550
|
+
const [data, error] = await backendSdk.useResult(
|
|
551
|
+
fetch(
|
|
552
|
+
`${this.PAYMENTS_URI}/my/batchpayments/federate/sign/${signId}/hash/${signHash}`,
|
|
553
|
+
{
|
|
554
|
+
method: "GET",
|
|
555
|
+
headers: {
|
|
556
|
+
"Callback-Uri": `${this.REDIRECT_URI}/payment-authorization-complete`,
|
|
557
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
558
|
+
"WEB-API-key": this.CLIENT_SECRET
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
)
|
|
562
|
+
);
|
|
563
|
+
if (error) {
|
|
564
|
+
throw error;
|
|
565
|
+
}
|
|
566
|
+
return (await data.json()).signingUrl;
|
|
567
|
+
}
|
|
568
|
+
async getAllAccountPayments({
|
|
569
|
+
account,
|
|
570
|
+
lastSync
|
|
571
|
+
}) {
|
|
572
|
+
const erstePayments = [];
|
|
573
|
+
const dateFormat = "yyyy-MM-dd";
|
|
574
|
+
const fromDate = dateFns.format(lastSync.lastSyncedAt, dateFormat);
|
|
575
|
+
const toDate = dateFns.format(/* @__PURE__ */ new Date(), dateFormat);
|
|
576
|
+
let page = 0;
|
|
577
|
+
const pageSize = 200;
|
|
578
|
+
const pageCount = 1;
|
|
579
|
+
while (page < pageCount) {
|
|
580
|
+
const response = await fetch(
|
|
581
|
+
`${this.ACCOUNTS_URI}/my/accounts/${account.id}/transactions?fromDate=${fromDate}&toDate=${toDate}&size=${pageSize}&page=${page}&sort=bookingDate&order=desc`,
|
|
582
|
+
{
|
|
583
|
+
headers: {
|
|
584
|
+
"WEB-API-key": this.API_KEY,
|
|
585
|
+
Authorization: `Bearer ${this.accessToken}`
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
);
|
|
589
|
+
const data = await response.json();
|
|
590
|
+
erstePayments.push(...data.transactions);
|
|
591
|
+
page += 1;
|
|
592
|
+
}
|
|
593
|
+
const payments = erstePayments.map((payment) => {
|
|
594
|
+
const reference = payment.entryDetails.transactionDetails.remittanceInformation?.structured.creditorReferenceInformation?.reference || [];
|
|
595
|
+
const symbols = mapReferencesToPayment(reference);
|
|
596
|
+
const paymentInsert = {
|
|
597
|
+
id: backendSdk.uuidv4(),
|
|
598
|
+
bankRefId: payment.entryReference,
|
|
599
|
+
amount: payment.amount.value,
|
|
600
|
+
currency: payment.amount.currency.code,
|
|
601
|
+
debtorHolderName: payment.entryDetails.transactionDetails.relatedParties.debtor?.name,
|
|
602
|
+
debtorIban: payment.entryDetails.transactionDetails.relatedParties.debtorAccount?.identification.iban,
|
|
603
|
+
debtorAccountNumberWithBankCode: payment.entryDetails.transactionDetails.relatedParties.debtorAccount?.identification.other?.identification,
|
|
604
|
+
creditorHolderName: payment.entryDetails.transactionDetails.relatedParties.creditor?.name || "",
|
|
605
|
+
creditorIban: payment.entryDetails.transactionDetails.relatedParties.creditorAccount?.identification.iban,
|
|
606
|
+
creditorAccountNumberWithBankCode: payment.entryDetails.transactionDetails.relatedParties.creditorAccount?.identification.other?.identification,
|
|
607
|
+
paymentType: "DOMESTIC",
|
|
608
|
+
direction: "INCOMING",
|
|
609
|
+
message: payment.entryDetails.transactionDetails.remittanceInformation?.unstructured,
|
|
610
|
+
vs: symbols.vs,
|
|
611
|
+
ss: symbols.ss,
|
|
612
|
+
ks: symbols.ks,
|
|
613
|
+
processedAt: dateFns.parseISO(payment.bookingDate.date),
|
|
614
|
+
status: "COMPLETED"
|
|
615
|
+
};
|
|
616
|
+
return {
|
|
617
|
+
...paymentInsert,
|
|
618
|
+
direction: getPaymentDirection(
|
|
619
|
+
paymentInsert,
|
|
620
|
+
account.identification.iban
|
|
621
|
+
)
|
|
622
|
+
};
|
|
623
|
+
});
|
|
624
|
+
return payments;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
|
|
627
628
|
class MockConnector extends IBankConnector {
|
|
628
629
|
constructor() {
|
|
629
630
|
super(...arguments);
|