@develit-services/bank 0.0.13 → 0.0.15
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/database/schema.d.cts +1 -1
- package/dist/database/schema.d.mts +1 -1
- package/dist/database/schema.d.ts +1 -1
- package/dist/export/worker.cjs +42 -24
- package/dist/export/worker.d.cts +5 -4
- package/dist/export/worker.d.mts +5 -4
- package/dist/export/worker.d.ts +5 -4
- package/dist/export/worker.mjs +43 -25
- 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.BYxCT5rk.d.ts → bank.BlmUZQ6s.d.cts} +20 -8
- 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.Ce58djRL.cjs} +500 -320
- package/dist/shared/{bank.TOYdvcg7.mjs → bank.DZS4d3MJ.mjs} +498 -322
- package/dist/shared/{bank.CBNQZ5Pd.d.cts → bank.DiMNzl60.d.cts} +8 -6
- package/dist/shared/{bank.CBNQZ5Pd.d.mts → bank.DiMNzl60.d.mts} +8 -6
- package/dist/shared/{bank.CBNQZ5Pd.d.ts → bank.DiMNzl60.d.ts} +8 -6
- package/dist/shared/{bank.BULPVep1.d.cts → bank.j2Z-uViN.d.ts} +20 -8
- package/dist/shared/{bank.Dxfp5h5B.d.mts → bank.tyFkXmr8.d.mts} +20 -8
- package/dist/{@types.cjs → types.cjs} +8 -3
- package/dist/{@types.d.cts → types.d.cts} +142 -22
- package/dist/{@types.d.mts → types.d.mts} +142 -22
- package/dist/{@types.d.ts → types.d.ts} +142 -22
- package/dist/types.mjs +11 -0
- package/package.json +4 -4
- package/dist/@types.mjs +0 -10
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { uuidv4, useResult, createInternalError } from '@develit-io/backend-sdk';
|
|
2
2
|
import { s as schema } from './bank.BeH-ZCJJ.mjs';
|
|
3
3
|
import { and, eq } from 'drizzle-orm';
|
|
4
|
-
import { format, parseISO } from 'date-fns';
|
|
5
|
-
import { importPKCS8, SignJWT } from 'jose';
|
|
6
|
-
import { COUNTRY_CODES_2, CURRENCY_CODES } from '@develit-io/general-codes';
|
|
7
4
|
import { z } from 'zod';
|
|
5
|
+
import { COUNTRY_CODES_2, CURRENCY_CODES } from '@develit-io/general-codes';
|
|
6
|
+
import { importPKCS8, SignJWT } from 'jose';
|
|
7
|
+
import 'superjson';
|
|
8
|
+
import { format, parseISO } from 'date-fns';
|
|
8
9
|
|
|
9
10
|
const tables = schema;
|
|
10
11
|
|
|
@@ -32,12 +33,102 @@ const COUNTRY_CODES = COUNTRY_CODES_2;
|
|
|
32
33
|
class IBankConnector {
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
async function signFinbricksJws({
|
|
37
|
+
privateKeyPem,
|
|
38
|
+
merchantId,
|
|
39
|
+
jwsData
|
|
40
|
+
}) {
|
|
41
|
+
const privateKey = await importPKCS8(privateKeyPem, "RS256");
|
|
42
|
+
const payload = JSON.stringify(jwsData);
|
|
43
|
+
const jws = await new SignJWT(JSON.parse(payload)).setProtectedHeader({
|
|
44
|
+
alg: "RS256",
|
|
45
|
+
kid: merchantId,
|
|
46
|
+
typ: "JWT"
|
|
47
|
+
}).sign(privateKey);
|
|
48
|
+
const [header, , signature] = jws.split(".");
|
|
49
|
+
return `${header}..${signature}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const useFinbricksFetch = async (config, init) => {
|
|
53
|
+
const {
|
|
54
|
+
baseUrl,
|
|
55
|
+
endpoint,
|
|
56
|
+
method = "GET",
|
|
57
|
+
merchantId,
|
|
58
|
+
privateKeyPem,
|
|
59
|
+
query,
|
|
60
|
+
body,
|
|
61
|
+
correlationId,
|
|
62
|
+
psuIp = "88.205.47.1",
|
|
63
|
+
psuAgent = "Develit/BankService"
|
|
64
|
+
} = config;
|
|
65
|
+
const url = new URL(`${baseUrl}${endpoint}`);
|
|
66
|
+
if (query) {
|
|
67
|
+
for (const [k, v] of Object.entries(query)) {
|
|
68
|
+
if (v !== void 0 && v !== null)
|
|
69
|
+
url.searchParams.append(k, v.toString());
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const uriWithQuery = `${endpoint}${url.search ? `?${url.searchParams.toString()}` : ""}`;
|
|
73
|
+
const bodyString = body ? JSON.stringify(body) : "";
|
|
74
|
+
const jwsSignature = await signFinbricksJws({
|
|
75
|
+
privateKeyPem,
|
|
76
|
+
merchantId,
|
|
77
|
+
jwsData: {
|
|
78
|
+
uri: uriWithQuery,
|
|
79
|
+
body: bodyString
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const headers = {
|
|
83
|
+
"Content-Type": "application/json",
|
|
84
|
+
"JWS-Signature": jwsSignature,
|
|
85
|
+
"PSU-IP-Address": psuIp,
|
|
86
|
+
"PSU-User-Agent": psuAgent,
|
|
87
|
+
...init?.headers
|
|
88
|
+
};
|
|
89
|
+
if (correlationId) {
|
|
90
|
+
headers["Correlation-ID"] = correlationId;
|
|
91
|
+
}
|
|
92
|
+
const res = await fetch(url.toString(), {
|
|
93
|
+
method,
|
|
94
|
+
headers,
|
|
95
|
+
body: method !== "GET" ? bodyString : void 0
|
|
96
|
+
});
|
|
97
|
+
if (!res.ok) {
|
|
98
|
+
const text = await res.text().catch(() => "unknown error");
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Finbricks API error: ${res.status} ${res.statusText} \u2013 ${text}`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return await res.json();
|
|
37
104
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
105
|
+
class FinbricksClient {
|
|
106
|
+
constructor(baseUrl, merchantId, privateKeyPem) {
|
|
107
|
+
this.BASE_URL = baseUrl;
|
|
108
|
+
this.MERCHANT_ID = merchantId;
|
|
109
|
+
this.PRIVATE_KEY_PEM = privateKeyPem;
|
|
110
|
+
}
|
|
111
|
+
async request(params) {
|
|
112
|
+
return useFinbricksFetch({
|
|
113
|
+
baseUrl: this.BASE_URL,
|
|
114
|
+
merchantId: this.MERCHANT_ID,
|
|
115
|
+
privateKeyPem: this.PRIVATE_KEY_PEM,
|
|
116
|
+
...params
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const FINBRICKS_ENDPOINTS = {
|
|
122
|
+
AUTHENTICATE_V2: "/v2/auth/authenticate",
|
|
123
|
+
AUTH_TOKEN_STATUS: "/auth/token",
|
|
124
|
+
AUTH_TOKEN_REVOKE: "/auth/revoke",
|
|
125
|
+
ACCOUNT_LIST: "/account/list",
|
|
126
|
+
ACCOUNT_BALANCE: "/account/balance",
|
|
127
|
+
ACCOUNT_TRANSACTIONS: "/account/transactions",
|
|
128
|
+
TRANSACTION_INIT: "/transaction/platform/init",
|
|
129
|
+
TRANSACTION_STATUS: "/transaction/platform/status",
|
|
130
|
+
TRANSACTION_BATCH_INIT: "/transaction/platform/batchPayment/init",
|
|
131
|
+
BATCH_STATUS: "/transaction/platform/batchPayment/status"
|
|
41
132
|
};
|
|
42
133
|
|
|
43
134
|
const mapReferencesToPayment = (reference) => {
|
|
@@ -63,6 +154,376 @@ const mapReferencesToPayment = (reference) => {
|
|
|
63
154
|
return symbols;
|
|
64
155
|
};
|
|
65
156
|
|
|
157
|
+
const mapFinbricksStatus = (status) => {
|
|
158
|
+
switch (status) {
|
|
159
|
+
case "BOOK":
|
|
160
|
+
return "COMPLETED";
|
|
161
|
+
case "PDNG":
|
|
162
|
+
return "PENDING";
|
|
163
|
+
case "CANCL":
|
|
164
|
+
return "FAILED";
|
|
165
|
+
case "RJCT":
|
|
166
|
+
return "FAILED";
|
|
167
|
+
case "SCHDL":
|
|
168
|
+
return "PENDING";
|
|
169
|
+
case "HOLD":
|
|
170
|
+
return "PENDING";
|
|
171
|
+
case "INFO":
|
|
172
|
+
return "PENDING";
|
|
173
|
+
default:
|
|
174
|
+
return "PENDING";
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const mapFinbricksTransactionStatus = (status) => {
|
|
178
|
+
switch (status) {
|
|
179
|
+
case "OPENED":
|
|
180
|
+
return "CREATED";
|
|
181
|
+
case "AUTHORIZED":
|
|
182
|
+
return "PENDING";
|
|
183
|
+
case "COMPLETED":
|
|
184
|
+
return "COMPLETED";
|
|
185
|
+
case "BOOKED":
|
|
186
|
+
return "PENDING";
|
|
187
|
+
case "SETTLED":
|
|
188
|
+
return "COMPLETED";
|
|
189
|
+
case "REJECTED":
|
|
190
|
+
return "FAILED";
|
|
191
|
+
case "CLOSED":
|
|
192
|
+
return "FAILED";
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
const mapFinbricksBatchStatus = (status) => {
|
|
196
|
+
return status === "REJECTED" ? "FAILED" : status === "AUTHORIZED" ? "PROCESSING" : "READY_TO_SIGN";
|
|
197
|
+
};
|
|
198
|
+
const mapFinbricksTransactionToPayment = (tx, account) => {
|
|
199
|
+
const isIncoming = tx.creditDebitIndicator === "CRDT";
|
|
200
|
+
const related = tx.entryDetails.transactionDetails.relatedParties;
|
|
201
|
+
const base = {
|
|
202
|
+
id: uuidv4(),
|
|
203
|
+
bankRefId: tx.entryReference || tx.fbxReference,
|
|
204
|
+
amount: tx.amount?.value || 0,
|
|
205
|
+
currency: tx.amount?.currency || "CZK",
|
|
206
|
+
paymentType: "DOMESTIC",
|
|
207
|
+
status: mapFinbricksStatus(tx.status),
|
|
208
|
+
message: tx.entryDetails.transactionDetails.remittanceInformation?.unstructured || tx.entryDetails.transactionDetails.additionalRemittanceInformation || null,
|
|
209
|
+
processedAt: new Date(tx.bookingDate.date),
|
|
210
|
+
...mapReferencesToPayment(
|
|
211
|
+
tx.entryDetails.transactionDetails.remittanceInformation?.structured?.creditorReferenceInformation?.reference || tx.entryDetails.transactionDetails.references?.endToEndIdentification
|
|
212
|
+
),
|
|
213
|
+
debtorHolderName: isIncoming ? related.debtor?.name || "Unknown" : "Unknown",
|
|
214
|
+
creditorHolderName: isIncoming ? "Unknown" : related.creditor?.name || "Unknown",
|
|
215
|
+
debtorIban: isIncoming ? related.debtorAccount?.identification?.iban || account.identification.iban : account.identification.iban,
|
|
216
|
+
creditorIban: isIncoming ? account.identification.iban : related.creditorAccount?.identification?.iban || account.identification.iban,
|
|
217
|
+
direction: "INCOMING"
|
|
218
|
+
// přepíšeme správným směrem níže
|
|
219
|
+
};
|
|
220
|
+
base.direction = getPaymentDirection(base, account.identification.iban);
|
|
221
|
+
return base;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
class FinbricksConnector extends IBankConnector {
|
|
225
|
+
constructor(provider, { BASE_URI, MERCHANT_ID, PRIVATE_KEY_PEM }) {
|
|
226
|
+
super();
|
|
227
|
+
this.connectorKey = "FINBRICKS";
|
|
228
|
+
this.PROVIDER = provider;
|
|
229
|
+
this.finbricks = new FinbricksClient(BASE_URI, MERCHANT_ID, PRIVATE_KEY_PEM);
|
|
230
|
+
}
|
|
231
|
+
static {
|
|
232
|
+
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
233
|
+
}
|
|
234
|
+
async connectUserAccount() {
|
|
235
|
+
const clientId = uuidv4();
|
|
236
|
+
const body = {
|
|
237
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
238
|
+
clientId,
|
|
239
|
+
paymentProvider: this.PROVIDER,
|
|
240
|
+
scope: "AISP_PISP",
|
|
241
|
+
callbackUrl: "https://example.com/callback"
|
|
242
|
+
};
|
|
243
|
+
const [response, error] = await useResult(
|
|
244
|
+
this.finbricks.request({
|
|
245
|
+
endpoint: FINBRICKS_ENDPOINTS.AUTHENTICATE_V2,
|
|
246
|
+
method: "POST",
|
|
247
|
+
body
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
if (error || !response) {
|
|
251
|
+
throw createInternalError(error, {
|
|
252
|
+
message: "Finbricks: failed to connect user"
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
redirectUrl: response.redirectUrl,
|
|
257
|
+
clientId
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
async authenticate({ token: clientId }) {
|
|
261
|
+
if (!!clientId) {
|
|
262
|
+
const isExpired = await this.isClientIdExpired(clientId);
|
|
263
|
+
if (!isExpired) {
|
|
264
|
+
this.lastValidClientId = clientId;
|
|
265
|
+
return clientId;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const newClientId = uuidv4();
|
|
269
|
+
const body = {
|
|
270
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
271
|
+
paymentProvider: this.PROVIDER,
|
|
272
|
+
clientId: newClientId,
|
|
273
|
+
scope: "AISP_PISP",
|
|
274
|
+
callbackUrl: `www.example.com/callback`
|
|
275
|
+
};
|
|
276
|
+
const [res, error] = await useResult(
|
|
277
|
+
this.finbricks.request({
|
|
278
|
+
endpoint: "/v2/auth/authenticate",
|
|
279
|
+
method: "POST",
|
|
280
|
+
body
|
|
281
|
+
})
|
|
282
|
+
);
|
|
283
|
+
if (error || !res) {
|
|
284
|
+
throw createInternalError(error, {
|
|
285
|
+
message: `Finbricks: authentication request failed (${this.PROVIDER})`
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
this.lastValidClientId = newClientId;
|
|
289
|
+
return res.redirectUrl;
|
|
290
|
+
}
|
|
291
|
+
async revokeAuthentication(clientId) {
|
|
292
|
+
const [_, error] = await useResult(
|
|
293
|
+
this.finbricks.request({
|
|
294
|
+
endpoint: FINBRICKS_ENDPOINTS.AUTH_TOKEN_REVOKE,
|
|
295
|
+
method: "DELETE",
|
|
296
|
+
query: {
|
|
297
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
298
|
+
clientId,
|
|
299
|
+
provider: this.PROVIDER
|
|
300
|
+
}
|
|
301
|
+
})
|
|
302
|
+
);
|
|
303
|
+
if (error) {
|
|
304
|
+
throw createInternalError(error, {
|
|
305
|
+
message: `Finbricks: failed to revoke authentication for clientId ${clientId}`
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
this.lastValidClientId = "";
|
|
309
|
+
}
|
|
310
|
+
async isClientIdExpired(clientId) {
|
|
311
|
+
const [response, error] = await useResult(
|
|
312
|
+
this.finbricks.request({
|
|
313
|
+
endpoint: FINBRICKS_ENDPOINTS.AUTH_TOKEN_STATUS,
|
|
314
|
+
method: "GET",
|
|
315
|
+
query: {
|
|
316
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
317
|
+
clientId,
|
|
318
|
+
provider: this.PROVIDER
|
|
319
|
+
}
|
|
320
|
+
})
|
|
321
|
+
);
|
|
322
|
+
if (error) {
|
|
323
|
+
throw createInternalError(error, {
|
|
324
|
+
message: `Finbricks: failed to fetch token info for clientId: ${clientId}`
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
if (!response || response.length === 0) return true;
|
|
328
|
+
const record = response.find((token) => token.clientId === clientId);
|
|
329
|
+
if (!record) return true;
|
|
330
|
+
const validTo = new Date(record.validTo);
|
|
331
|
+
return validTo.getTime() < Date.now();
|
|
332
|
+
}
|
|
333
|
+
async listAccounts() {
|
|
334
|
+
if (!this.lastValidClientId) {
|
|
335
|
+
throw createInternalError(null, {
|
|
336
|
+
message: "Finbricks: missing valid clientId",
|
|
337
|
+
code: "FINBRICKS_CLIENT_ID_MISSING"
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
const [response, error] = await useResult(
|
|
341
|
+
this.finbricks.request({
|
|
342
|
+
endpoint: FINBRICKS_ENDPOINTS.ACCOUNT_LIST,
|
|
343
|
+
method: "GET",
|
|
344
|
+
query: {
|
|
345
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
346
|
+
paymentProvider: this.PROVIDER,
|
|
347
|
+
clientId: this.lastValidClientId
|
|
348
|
+
}
|
|
349
|
+
})
|
|
350
|
+
);
|
|
351
|
+
if (error || !response) {
|
|
352
|
+
throw createInternalError(error, {
|
|
353
|
+
message: "Finbricks: failed to list accounts"
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return response.accounts;
|
|
357
|
+
}
|
|
358
|
+
async preparePayment(payment) {
|
|
359
|
+
const bankRefId = uuidv4();
|
|
360
|
+
return {
|
|
361
|
+
...payment,
|
|
362
|
+
id: uuidv4(),
|
|
363
|
+
bankRefId,
|
|
364
|
+
direction: "OUTGOING",
|
|
365
|
+
paymentType: "DOMESTIC",
|
|
366
|
+
status: "PREPARED",
|
|
367
|
+
initiatedAt: /* @__PURE__ */ new Date()
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
async initiateBatchFromPayments({
|
|
371
|
+
payments
|
|
372
|
+
}) {
|
|
373
|
+
const batchId = uuidv4();
|
|
374
|
+
const [response, error] = await useResult(
|
|
375
|
+
this.finbricks.request({
|
|
376
|
+
endpoint: FINBRICKS_ENDPOINTS.TRANSACTION_BATCH_INIT,
|
|
377
|
+
method: "POST",
|
|
378
|
+
body: {
|
|
379
|
+
batchPaymentIdentification: {
|
|
380
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
381
|
+
debtorAccountIban: payments[0].debtorIban,
|
|
382
|
+
clientId: this.lastValidClientId,
|
|
383
|
+
callbackUrl: "https://example.com/callback",
|
|
384
|
+
merchantBatchId: batchId
|
|
385
|
+
},
|
|
386
|
+
payments: payments.map((p) => ({
|
|
387
|
+
merchantTransactionId: p.bankRefId,
|
|
388
|
+
creditorAccountIban: p.creditorIban,
|
|
389
|
+
amount: p.amount
|
|
390
|
+
}))
|
|
391
|
+
}
|
|
392
|
+
})
|
|
393
|
+
);
|
|
394
|
+
if (error || !response) {
|
|
395
|
+
throw createInternalError(error, {
|
|
396
|
+
message: "Finbricks: failed to initiate batch payment"
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
id: batchId,
|
|
401
|
+
authorizationUrls: [response.redirectUrl],
|
|
402
|
+
payments: payments.map((p) => ({ ...p, status: "INITIALIZED" }))
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
async initiateSinglePayment(payment) {
|
|
406
|
+
const [response, error] = await useResult(
|
|
407
|
+
this.finbricks.request({
|
|
408
|
+
endpoint: FINBRICKS_ENDPOINTS.TRANSACTION_INIT,
|
|
409
|
+
method: "POST",
|
|
410
|
+
body: {
|
|
411
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
412
|
+
merchantTransactionId: payment.bankRefId,
|
|
413
|
+
totalPrice: payment.amount,
|
|
414
|
+
debtorAccountIban: payment.debtorIban,
|
|
415
|
+
creditorAccountIban: payment.creditorIban,
|
|
416
|
+
creditorName: payment.creditorHolderName,
|
|
417
|
+
description: payment.message || "",
|
|
418
|
+
variableSymbol: payment.vs || "",
|
|
419
|
+
callbackUrl: "https://example.com/callback",
|
|
420
|
+
paymentProvider: this.PROVIDER
|
|
421
|
+
}
|
|
422
|
+
})
|
|
423
|
+
);
|
|
424
|
+
if (error || !response) {
|
|
425
|
+
throw createInternalError(error, {
|
|
426
|
+
message: "Finbricks: failed to initiate payment"
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
authorizationUrl: response.redirectUrl,
|
|
431
|
+
payment: { ...payment, status: "INITIALIZED" }
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
async getAllAccountPayments({
|
|
435
|
+
account,
|
|
436
|
+
lastSync
|
|
437
|
+
}) {
|
|
438
|
+
const dateFormat = "yyyy-MM-dd";
|
|
439
|
+
const dateFrom = format(lastSync.lastSyncedAt, dateFormat);
|
|
440
|
+
const dateTo = format(/* @__PURE__ */ new Date(), dateFormat);
|
|
441
|
+
let cursor = null;
|
|
442
|
+
const allPayments = [];
|
|
443
|
+
const fetchTransactions = async (cursor2) => {
|
|
444
|
+
return useResult(
|
|
445
|
+
this.finbricks.request({
|
|
446
|
+
method: "GET",
|
|
447
|
+
endpoint: FINBRICKS_ENDPOINTS.ACCOUNT_TRANSACTIONS,
|
|
448
|
+
query: {
|
|
449
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
450
|
+
clientId: this.lastValidClientId,
|
|
451
|
+
paymentProvider: this.PROVIDER,
|
|
452
|
+
bankAccountId: account.identification.number,
|
|
453
|
+
dateFrom,
|
|
454
|
+
dateTo,
|
|
455
|
+
currency: account.currency,
|
|
456
|
+
size: "20",
|
|
457
|
+
cursor: cursor2 ?? void 0
|
|
458
|
+
}
|
|
459
|
+
})
|
|
460
|
+
);
|
|
461
|
+
};
|
|
462
|
+
do {
|
|
463
|
+
{
|
|
464
|
+
const [response, error] = await fetchTransactions(cursor);
|
|
465
|
+
if (error || !response) {
|
|
466
|
+
throw createInternalError(error, {
|
|
467
|
+
message: "Finbricks: failed to fetch account transactions"
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
const { transactions, links } = response;
|
|
471
|
+
cursor = links?.[0]?.value || null;
|
|
472
|
+
for (const tx of transactions) {
|
|
473
|
+
allPayments.push(mapFinbricksTransactionToPayment(tx, account));
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
} while (cursor != null);
|
|
477
|
+
return allPayments;
|
|
478
|
+
}
|
|
479
|
+
async getPaymentStatus({
|
|
480
|
+
paymentId
|
|
481
|
+
}) {
|
|
482
|
+
const [response, error] = await useResult(
|
|
483
|
+
this.finbricks.request({
|
|
484
|
+
method: "GET",
|
|
485
|
+
endpoint: FINBRICKS_ENDPOINTS.TRANSACTION_STATUS,
|
|
486
|
+
query: {
|
|
487
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
488
|
+
merchantTransactionId: paymentId
|
|
489
|
+
}
|
|
490
|
+
})
|
|
491
|
+
);
|
|
492
|
+
if (error || !response) {
|
|
493
|
+
throw createInternalError(error, {
|
|
494
|
+
message: "Finbricks: failed to fetch payment status"
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
return mapFinbricksTransactionStatus(response.resultCode);
|
|
498
|
+
}
|
|
499
|
+
async getBatchStatus({ batchId }) {
|
|
500
|
+
const [response, error] = await useResult(
|
|
501
|
+
this.finbricks.request({
|
|
502
|
+
method: "POST",
|
|
503
|
+
endpoint: FINBRICKS_ENDPOINTS.BATCH_STATUS,
|
|
504
|
+
body: {
|
|
505
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
506
|
+
merchantBatchId: batchId
|
|
507
|
+
}
|
|
508
|
+
})
|
|
509
|
+
);
|
|
510
|
+
if (error || !response) {
|
|
511
|
+
throw createInternalError(error, {
|
|
512
|
+
message: "Finbricks: failed to fetch batch status"
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
return mapFinbricksBatchStatus(response.batchResultCode);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
const isDeposit = (payment, creditorIban) => {
|
|
520
|
+
return payment.creditorIban === creditorIban;
|
|
521
|
+
};
|
|
522
|
+
const getPaymentDirection = (payment, iban) => {
|
|
523
|
+
if (isDeposit(payment, iban)) return "INCOMING";
|
|
524
|
+
return "OUTGOING";
|
|
525
|
+
};
|
|
526
|
+
|
|
66
527
|
class ErsteConnector extends IBankConnector {
|
|
67
528
|
constructor(config) {
|
|
68
529
|
super();
|
|
@@ -76,6 +537,9 @@ class ErsteConnector extends IBankConnector {
|
|
|
76
537
|
this.PAYMENTS_URI = config.PAYMENTS_URI;
|
|
77
538
|
this.ACCOUNTS_URI = config.ACCOUNTS_URI;
|
|
78
539
|
}
|
|
540
|
+
connectUserAccount() {
|
|
541
|
+
throw new Error("Method not implemented.");
|
|
542
|
+
}
|
|
79
543
|
static {
|
|
80
544
|
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
81
545
|
}
|
|
@@ -120,6 +584,9 @@ class ErsteConnector extends IBankConnector {
|
|
|
120
584
|
this.accessToken = json.access_token;
|
|
121
585
|
return json.refresh_token || "";
|
|
122
586
|
}
|
|
587
|
+
listAccounts() {
|
|
588
|
+
throw new Error("Method not implemented.");
|
|
589
|
+
}
|
|
123
590
|
async preparePayment(payment) {
|
|
124
591
|
if (!this.accessToken) {
|
|
125
592
|
throw createInternalError(null, {
|
|
@@ -306,319 +773,11 @@ class ErsteConnector extends IBankConnector {
|
|
|
306
773
|
});
|
|
307
774
|
return payments;
|
|
308
775
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const mapFinbricksStatus = (status) => {
|
|
312
|
-
switch (status) {
|
|
313
|
-
case "BOOK":
|
|
314
|
-
return "COMPLETED";
|
|
315
|
-
case "PDNG":
|
|
316
|
-
return "PENDING";
|
|
317
|
-
case "CANCL":
|
|
318
|
-
return "FAILED";
|
|
319
|
-
case "RJCT":
|
|
320
|
-
return "FAILED";
|
|
321
|
-
case "SCHDL":
|
|
322
|
-
return "PENDING";
|
|
323
|
-
case "HOLD":
|
|
324
|
-
return "PENDING";
|
|
325
|
-
case "INFO":
|
|
326
|
-
return "PENDING";
|
|
327
|
-
default:
|
|
328
|
-
return "PENDING";
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
|
|
332
|
-
class FinbricksConnector extends IBankConnector {
|
|
333
|
-
constructor(PROVIDER, { BASE_URI, MERCHANT_ID, PRIVATE_KEY_PEM }) {
|
|
334
|
-
super();
|
|
335
|
-
this.connectorKey = "FINBRICKS";
|
|
336
|
-
this.apiDictionary = /* @__PURE__ */ new Map([
|
|
337
|
-
["single-payment-domestic", "/transaction/platform/init"],
|
|
338
|
-
["batch-payment-domestic", "/transaction/platform/batchPayment/init"],
|
|
339
|
-
["get-accounts", "/account/list"],
|
|
340
|
-
["get-account-transactions", "/account/transactions"],
|
|
341
|
-
["authenticate-client", "/v2/auth/authenticate"],
|
|
342
|
-
["expiration", "/auth/token"]
|
|
343
|
-
]);
|
|
344
|
-
this.PROVIDER = PROVIDER;
|
|
345
|
-
this.BASE_URI = BASE_URI;
|
|
346
|
-
this.MERCHANT_ID = MERCHANT_ID;
|
|
347
|
-
this.PRIVATE_KEY_PEM = PRIVATE_KEY_PEM;
|
|
348
|
-
}
|
|
349
|
-
static {
|
|
350
|
-
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
351
|
-
}
|
|
352
|
-
async signFinbricksJws({ jwsData }) {
|
|
353
|
-
const privateKey = await importPKCS8(this.PRIVATE_KEY_PEM, "RS256");
|
|
354
|
-
const payload = JSON.stringify(jwsData);
|
|
355
|
-
const jws = await new SignJWT(JSON.parse(payload)).setProtectedHeader({
|
|
356
|
-
alg: "RS256",
|
|
357
|
-
kid: this.MERCHANT_ID,
|
|
358
|
-
typ: "JWT"
|
|
359
|
-
}).sign(privateKey);
|
|
360
|
-
return jws;
|
|
361
|
-
}
|
|
362
|
-
async authenticate({ token }) {
|
|
363
|
-
this.lastValidClientId = token;
|
|
364
|
-
return this.lastValidClientId;
|
|
365
|
-
}
|
|
366
|
-
async isClientIdExpired(clientId) {
|
|
367
|
-
const query = new URLSearchParams({
|
|
368
|
-
merchantId: this.MERCHANT_ID,
|
|
369
|
-
provider: this.PROVIDER,
|
|
370
|
-
clientId
|
|
371
|
-
});
|
|
372
|
-
const uri = this.apiDictionary.get("expiration");
|
|
373
|
-
const fullUri = `${uri}?${query.toString()}`;
|
|
374
|
-
const signature = await this.signFinbricksJws({
|
|
375
|
-
jwsData: {
|
|
376
|
-
body: "",
|
|
377
|
-
uri: fullUri
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
const [data, error] = await useResult(
|
|
381
|
-
fetch(`${this.BASE_URI}${fullUri}`, {
|
|
382
|
-
method: "POST",
|
|
383
|
-
headers: {
|
|
384
|
-
"JWS-Signature": signature,
|
|
385
|
-
"Content-Type": "application/json"
|
|
386
|
-
},
|
|
387
|
-
body: ""
|
|
388
|
-
})
|
|
389
|
-
);
|
|
390
|
-
if (error) {
|
|
391
|
-
const body = await data?.json();
|
|
392
|
-
throw createInternalError(error, {
|
|
393
|
-
message: body?.message || "Finbricks API error"
|
|
394
|
-
});
|
|
395
|
-
}
|
|
396
|
-
if (!data?.ok) {
|
|
397
|
-
const body = await data.json();
|
|
398
|
-
throw createInternalError(null, {
|
|
399
|
-
message: body.message || "Finbricks API error",
|
|
400
|
-
code: "FINBRICKS_API_ERROR",
|
|
401
|
-
status: data?.status || 500
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
const tokens = await data.json();
|
|
405
|
-
return !!tokens.find((token) => token.clientId === clientId);
|
|
406
|
-
}
|
|
407
|
-
async preparePayment(payment) {
|
|
408
|
-
const bankRefId = uuidv4();
|
|
409
|
-
return {
|
|
410
|
-
...payment,
|
|
411
|
-
id: uuidv4(),
|
|
412
|
-
bankRefId,
|
|
413
|
-
direction: "OUTGOING",
|
|
414
|
-
paymentType: "DOMESTIC",
|
|
415
|
-
status: "PREPARED",
|
|
416
|
-
initiatedAt: /* @__PURE__ */ new Date()
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
async initiateBatchFromPayments({
|
|
420
|
-
payments
|
|
421
|
-
}) {
|
|
422
|
-
const uri = this.apiDictionary.get("batch-payment-domestic");
|
|
423
|
-
const batchId = uuidv4();
|
|
424
|
-
const batchBody = {
|
|
425
|
-
batchPaymentIdentification: {
|
|
426
|
-
merchantId: this.MERCHANT_ID,
|
|
427
|
-
debtorAccountIban: payments[0].debtorIban,
|
|
428
|
-
clientId: this.lastValidClientId,
|
|
429
|
-
callbackUrl: "https://example.com/callback",
|
|
430
|
-
merchantBatchId: batchId
|
|
431
|
-
},
|
|
432
|
-
payments: payments.map((payment) => ({
|
|
433
|
-
merchantTransactionId: payment.bankRefId,
|
|
434
|
-
creditorAccountIban: payment.creditorIban,
|
|
435
|
-
amount: payment.amount
|
|
436
|
-
}))
|
|
437
|
-
};
|
|
438
|
-
const payload = JSON.stringify(batchBody);
|
|
439
|
-
const jwsData = {
|
|
440
|
-
uri,
|
|
441
|
-
body: payload
|
|
442
|
-
};
|
|
443
|
-
const signature = await this.signFinbricksJws({
|
|
444
|
-
jwsData
|
|
445
|
-
});
|
|
446
|
-
const [data, error] = await useResult(
|
|
447
|
-
fetch(`${this.BASE_URI}${uri}`, {
|
|
448
|
-
method: "POST",
|
|
449
|
-
headers: {
|
|
450
|
-
"JWS-Signature": signature,
|
|
451
|
-
"Content-Type": "application/json"
|
|
452
|
-
},
|
|
453
|
-
body: payload
|
|
454
|
-
})
|
|
455
|
-
);
|
|
456
|
-
const body = await data?.json();
|
|
457
|
-
if (error) {
|
|
458
|
-
throw createInternalError(error, {
|
|
459
|
-
message: body?.message || "Finbricks API error"
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
if (!data?.ok) {
|
|
463
|
-
console.log("FINBRICKSBODY", body);
|
|
464
|
-
throw createInternalError(null, {
|
|
465
|
-
message: body?.message || "Finbricks API error",
|
|
466
|
-
code: "FINBRICKS_API_ERROR",
|
|
467
|
-
status: data?.status || 500
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
const { redirectUrl } = body;
|
|
471
|
-
return {
|
|
472
|
-
id: batchId,
|
|
473
|
-
authorizationUrls: [redirectUrl],
|
|
474
|
-
payments: payments.map((payment) => ({
|
|
475
|
-
...payment,
|
|
476
|
-
status: "INITIALIZED"
|
|
477
|
-
}))
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
async initiateSinglePayment(payment) {
|
|
481
|
-
const uri = this.apiDictionary.get("single-payment-domestic");
|
|
482
|
-
const paymentBody = {
|
|
483
|
-
merchantId: this.MERCHANT_ID,
|
|
484
|
-
merchantTransactionId: payment.bankRefId,
|
|
485
|
-
totalPrice: payment.amount,
|
|
486
|
-
creditorAccountIban: payment.creditorIban,
|
|
487
|
-
debtorAccountIban: payment.debtorIban,
|
|
488
|
-
creditorName: payment.creditorHolderName,
|
|
489
|
-
description: payment.message || "",
|
|
490
|
-
variableSymbol: payment.vs || "",
|
|
491
|
-
callbackUrl: "example.com",
|
|
492
|
-
paymentProvider: this.PROVIDER
|
|
493
|
-
};
|
|
494
|
-
const signature = await this.signFinbricksJws({
|
|
495
|
-
jwsData: {
|
|
496
|
-
body: JSON.stringify(paymentBody),
|
|
497
|
-
uri
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
const [data, error] = await useResult(
|
|
501
|
-
fetch(`${this.BASE_URI}${uri}`, {
|
|
502
|
-
method: "POST",
|
|
503
|
-
headers: {
|
|
504
|
-
"JWS-Signature": signature,
|
|
505
|
-
"Content-Type": "application/json"
|
|
506
|
-
},
|
|
507
|
-
body: JSON.stringify(paymentBody)
|
|
508
|
-
})
|
|
509
|
-
);
|
|
510
|
-
const body = await data?.json();
|
|
511
|
-
if (error) {
|
|
512
|
-
throw createInternalError(error, {
|
|
513
|
-
message: body?.message || "Finbricks API error"
|
|
514
|
-
});
|
|
515
|
-
}
|
|
516
|
-
if (!data?.ok) {
|
|
517
|
-
console.log("FINBRICKSBODY", body);
|
|
518
|
-
throw createInternalError(null, {
|
|
519
|
-
message: body?.message || "Finbricks API error",
|
|
520
|
-
code: "FINBRICKS_API_ERROR",
|
|
521
|
-
status: data?.status || 500
|
|
522
|
-
});
|
|
523
|
-
}
|
|
524
|
-
const redirectUrl = (await data.json()).redirectUrl;
|
|
525
|
-
return {
|
|
526
|
-
authorizationUrl: redirectUrl,
|
|
527
|
-
payment: { ...payment, status: "INITIALIZED" }
|
|
528
|
-
};
|
|
776
|
+
getPaymentStatus(_) {
|
|
777
|
+
throw new Error("Method not implemented.");
|
|
529
778
|
}
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
lastSync
|
|
533
|
-
}) {
|
|
534
|
-
const uri = this.apiDictionary.get("get-account-transactions");
|
|
535
|
-
const dateFormat = "yyyy-MM-dd";
|
|
536
|
-
let cursor = null;
|
|
537
|
-
let allPayments = [];
|
|
538
|
-
const dateFrom = format(lastSync.lastSyncedAt, dateFormat);
|
|
539
|
-
const dateTo = format(/* @__PURE__ */ new Date(), dateFormat);
|
|
540
|
-
do {
|
|
541
|
-
const query = new URLSearchParams({
|
|
542
|
-
merchantId: this.MERCHANT_ID,
|
|
543
|
-
clientId: this.lastValidClientId,
|
|
544
|
-
paymentProvider: this.PROVIDER,
|
|
545
|
-
bankAccountId: account.identification.number,
|
|
546
|
-
dateFrom,
|
|
547
|
-
dateTo,
|
|
548
|
-
currency: account.currency,
|
|
549
|
-
size: "20"
|
|
550
|
-
});
|
|
551
|
-
console.log("query", query);
|
|
552
|
-
if (cursor) query.set("cursor", cursor);
|
|
553
|
-
const fullUri = `${uri}?${query.toString()}`;
|
|
554
|
-
const jwsData = {
|
|
555
|
-
uri: fullUri,
|
|
556
|
-
body: ""
|
|
557
|
-
};
|
|
558
|
-
const signature = await this.signFinbricksJws({ jwsData });
|
|
559
|
-
console.log("signature ready", signature);
|
|
560
|
-
const [data, error] = await useResult(
|
|
561
|
-
fetch(`${this.BASE_URI}${fullUri}`, {
|
|
562
|
-
method: "GET",
|
|
563
|
-
headers: {
|
|
564
|
-
"JWS-Signature": signature,
|
|
565
|
-
"Content-Type": "application/json"
|
|
566
|
-
}
|
|
567
|
-
})
|
|
568
|
-
);
|
|
569
|
-
if (error) {
|
|
570
|
-
const body = await data?.json();
|
|
571
|
-
throw createInternalError(error, {
|
|
572
|
-
message: body?.message || "Finbricks API error"
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
if (!data?.ok) {
|
|
576
|
-
const body = await data.json();
|
|
577
|
-
throw createInternalError(null, {
|
|
578
|
-
message: body.message || "Finbricks API error",
|
|
579
|
-
code: "FINBRICKS_API_ERROR",
|
|
580
|
-
status: data?.status || 500
|
|
581
|
-
});
|
|
582
|
-
}
|
|
583
|
-
const { transactions, links } = await data.json();
|
|
584
|
-
cursor = links?.[0]?.value || null;
|
|
585
|
-
allPayments = [
|
|
586
|
-
...allPayments,
|
|
587
|
-
...transactions.map((tx) => {
|
|
588
|
-
const isIncoming = tx.creditDebitIndicator === "CRDT";
|
|
589
|
-
const relatedParties = tx.entryDetails?.transactionDetails?.relatedParties;
|
|
590
|
-
const paymentInsert = {
|
|
591
|
-
id: uuidv4(),
|
|
592
|
-
bankRefId: tx.entryReference || tx.fbxReference,
|
|
593
|
-
amount: tx.amount?.value || 0,
|
|
594
|
-
currency: tx.amount?.currency || "CZK",
|
|
595
|
-
debtorHolderName: isIncoming ? relatedParties?.debtor?.name || "Unknown" : "Unknown",
|
|
596
|
-
debtorIban: isIncoming ? relatedParties?.debtorAccount?.identification?.iban || account.identification.iban : account.identification.iban,
|
|
597
|
-
debtorAccountNumberWithBankCode: isIncoming ? relatedParties?.debtorAccount?.identification?.other?.identification || `${account.identification.number}/${account.identification.bankCode}` : `${account.identification.number}/${account.identification.bankCode}`,
|
|
598
|
-
creditorHolderName: isIncoming ? "Unknown" : relatedParties?.creditor?.name || "Unknown",
|
|
599
|
-
creditorIban: isIncoming ? account.identification.iban : relatedParties?.creditorAccount?.identification?.iban || account.identification.iban,
|
|
600
|
-
creditorAccountNumberWithBankCode: isIncoming ? `${account.identification.number}/${account.identification.bankCode}` : relatedParties?.creditorAccount?.identification?.other?.identification || `${account.identification.number}/${account.identification.bankCode}`,
|
|
601
|
-
paymentType: "DOMESTIC",
|
|
602
|
-
direction: isIncoming ? "INCOMING" : "OUTGOING",
|
|
603
|
-
message: tx.entryDetails?.transactionDetails?.remittanceInformation?.unstructured || tx.entryDetails?.transactionDetails?.additionalRemittanceInformation || null,
|
|
604
|
-
...mapReferencesToPayment(
|
|
605
|
-
tx.entryDetails?.transactionDetails?.remittanceInformation?.structured?.creditorReferenceInformation?.reference || tx.entryDetails?.transactionDetails?.references?.endToEndIdentification
|
|
606
|
-
),
|
|
607
|
-
processedAt: new Date(tx.bookingDate.date),
|
|
608
|
-
status: "COMPLETED"
|
|
609
|
-
};
|
|
610
|
-
return {
|
|
611
|
-
...paymentInsert,
|
|
612
|
-
direction: getPaymentDirection(
|
|
613
|
-
paymentInsert,
|
|
614
|
-
account.identification.iban
|
|
615
|
-
),
|
|
616
|
-
status: mapFinbricksStatus(tx.status)
|
|
617
|
-
};
|
|
618
|
-
})
|
|
619
|
-
];
|
|
620
|
-
} while (cursor != null);
|
|
621
|
-
return allPayments;
|
|
779
|
+
getBatchStatus(_) {
|
|
780
|
+
throw new Error("Method not implemented.");
|
|
622
781
|
}
|
|
623
782
|
}
|
|
624
783
|
|
|
@@ -633,6 +792,15 @@ class MockConnector extends IBankConnector {
|
|
|
633
792
|
async authenticate() {
|
|
634
793
|
return "";
|
|
635
794
|
}
|
|
795
|
+
async listAccounts() {
|
|
796
|
+
return [];
|
|
797
|
+
}
|
|
798
|
+
async connectUserAccount() {
|
|
799
|
+
return {
|
|
800
|
+
clientId: uuidv4(),
|
|
801
|
+
redirectUrl: ""
|
|
802
|
+
};
|
|
803
|
+
}
|
|
636
804
|
async preparePayment(payment) {
|
|
637
805
|
const bankRefId = uuidv4();
|
|
638
806
|
return {
|
|
@@ -680,6 +848,12 @@ class MockConnector extends IBankConnector {
|
|
|
680
848
|
status: "COMPLETED"
|
|
681
849
|
}));
|
|
682
850
|
}
|
|
851
|
+
getPaymentStatus(_) {
|
|
852
|
+
throw new Error("Method not implemented.");
|
|
853
|
+
}
|
|
854
|
+
getBatchStatus(_) {
|
|
855
|
+
throw new Error("Method not implemented.");
|
|
856
|
+
}
|
|
683
857
|
}
|
|
684
858
|
|
|
685
859
|
class MockCobsConnector extends FinbricksConnector {
|
|
@@ -700,6 +874,8 @@ const paymentInsertTypeZod = z.object({
|
|
|
700
874
|
bankPaymentInitiatedAt: z.coerce.date(),
|
|
701
875
|
bankPaymentProcessedAt: z.coerce.date(),
|
|
702
876
|
bankingVs: z.string().max(10),
|
|
877
|
+
bankingSs: z.string().max(10),
|
|
878
|
+
bankingKs: z.string().max(10),
|
|
703
879
|
message: z.string(),
|
|
704
880
|
creditorIban: z.string().max(34),
|
|
705
881
|
creditorHolderName: z.string(),
|
|
@@ -707,4 +883,4 @@ const paymentInsertTypeZod = z.object({
|
|
|
707
883
|
debtorHolderName: z.string().nullable()
|
|
708
884
|
});
|
|
709
885
|
|
|
710
|
-
export { BATCH_STATUSES as B, COUNTRY_CODES as C, ErsteConnector as E, FinbricksConnector as F, IBankConnector as I, MockConnector as M, PAYMENT_TYPES as P, MockCobsConnector as a,
|
|
886
|
+
export { BATCH_STATUSES as B, COUNTRY_CODES as C, ErsteConnector as E, FinbricksConnector as F, IBankConnector as I, MockConnector as M, PAYMENT_TYPES as P, MockCobsConnector as a, FinbricksClient as b, FINBRICKS_ENDPOINTS as c, PAYMENT_STATUSES as d, PAYMENT_DIRECTIONS as e, getPaymentDirection as g, paymentInsertTypeZod as p, signFinbricksJws as s, tables as t, useFinbricksFetch as u };
|