@develit-services/bank 0.0.28 → 0.0.30
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.cjs +10 -1
- 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/database/schema.mjs +8 -1
- package/dist/export/worker.cjs +888 -575
- package/dist/export/worker.d.cts +210 -12
- package/dist/export/worker.d.mts +210 -12
- package/dist/export/worker.d.ts +210 -12
- package/dist/export/worker.mjs +859 -546
- package/dist/export/wrangler.cjs +1 -11
- package/dist/export/wrangler.d.cts +8 -9
- package/dist/export/wrangler.d.mts +8 -9
- package/dist/export/wrangler.d.ts +8 -9
- package/dist/export/wrangler.mjs +1 -11
- package/dist/shared/{bank.Cy_TcyKb.cjs → bank.BMRBXGF1.cjs} +347 -106
- package/dist/shared/{bank.CEZKAEiY.d.cts → bank.BchnXQDL.d.cts} +2 -2
- package/dist/shared/{bank.CEZKAEiY.d.mts → bank.BchnXQDL.d.mts} +2 -2
- package/dist/shared/{bank.CEZKAEiY.d.ts → bank.BchnXQDL.d.ts} +2 -2
- package/dist/shared/bank.CtUeOz8i.d.ts +1648 -0
- package/dist/shared/bank.D8o86NLF.d.mts +1648 -0
- package/dist/shared/bank.DUalSuEK.d.cts +1648 -0
- package/dist/shared/bank.DbNuuGvb.mjs +9 -0
- package/dist/shared/bank.DuY4d2y_.cjs +11 -0
- package/dist/shared/{bank.BuNG2S8h.d.cts → bank.Nf6oaNfB.d.cts} +547 -11
- package/dist/shared/{bank.BuNG2S8h.d.mts → bank.Nf6oaNfB.d.mts} +547 -11
- package/dist/shared/{bank.BuNG2S8h.d.ts → bank.Nf6oaNfB.d.ts} +547 -11
- package/dist/shared/{bank.DnDcNEvX.mjs → bank.YCUhOduX.mjs} +330 -107
- package/dist/types.cjs +32 -20
- package/dist/types.d.cts +496 -35
- package/dist/types.d.mts +496 -35
- package/dist/types.d.ts +496 -35
- package/dist/types.mjs +5 -4
- package/package.json +1 -1
- package/dist/shared/bank.BkLncGmL.d.ts +0 -122
- package/dist/shared/bank.C9jAvwna.mjs +0 -90
- package/dist/shared/bank.DWVLVMDa.d.mts +0 -122
- package/dist/shared/bank.DmypH3Au.d.cts +0 -122
- package/dist/shared/bank.P9gDUycr.cjs +0 -98
|
@@ -1,34 +1,13 @@
|
|
|
1
|
-
import { uuidv4, useResult, createInternalError } from '@develit-io/backend-sdk';
|
|
2
|
-
import { s as schema, C as CONNECTOR_KEYS } from './bank.C9jAvwna.mjs';
|
|
1
|
+
import { uuidv4, useResult, createInternalError, bankAccount, base } from '@develit-io/backend-sdk';
|
|
3
2
|
import { and, eq } from 'drizzle-orm';
|
|
4
|
-
import { z } from 'zod';
|
|
5
3
|
import { COUNTRY_CODES_2, CURRENCY_CODES } from '@develit-io/general-codes';
|
|
4
|
+
import { z } from 'zod';
|
|
6
5
|
import { importPKCS8, SignJWT } from 'jose';
|
|
7
|
-
import '
|
|
6
|
+
import { createInsertSchema, createUpdateSchema, createSelectSchema } from 'drizzle-zod';
|
|
7
|
+
import { sqliteTable, integer, text, unique, real } from 'drizzle-orm/sqlite-core';
|
|
8
8
|
import { format, parseISO } from 'date-fns';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const PAYMENT_TYPES = ["SEPA", "SWIFT", "IFSC", "DOMESTIC"];
|
|
13
|
-
const PAYMENT_STATUSES = [
|
|
14
|
-
"PREPARED",
|
|
15
|
-
"INITIALIZED",
|
|
16
|
-
"FAILED",
|
|
17
|
-
"PENDING",
|
|
18
|
-
"COMPLETED",
|
|
19
|
-
"CREATED"
|
|
20
|
-
];
|
|
21
|
-
const PAYMENT_DIRECTIONS = ["INCOMING", "OUTGOING"];
|
|
22
|
-
const BATCH_STATUSES = [
|
|
23
|
-
"OPEN",
|
|
24
|
-
"WAITING_FOR_PROCESSING",
|
|
25
|
-
"PROCESSING",
|
|
26
|
-
"READY_TO_SIGN",
|
|
27
|
-
"PREPARED",
|
|
28
|
-
"COMPLETED",
|
|
29
|
-
"FAILED"
|
|
30
|
-
];
|
|
31
|
-
const COUNTRY_CODES = COUNTRY_CODES_2;
|
|
9
|
+
import { relations } from 'drizzle-orm/relations';
|
|
10
|
+
import 'superjson';
|
|
32
11
|
|
|
33
12
|
class IBankConnector {
|
|
34
13
|
}
|
|
@@ -128,6 +107,7 @@ const FINBRICKS_ENDPOINTS = {
|
|
|
128
107
|
ACCOUNT_TRANSACTIONS: "/account/transactions",
|
|
129
108
|
TRANSACTION_INIT: "/transaction/platform/init",
|
|
130
109
|
TRANSACTION_STATUS: "/transaction/platform/status",
|
|
110
|
+
TRANSACTION_SEPA_INIT: "/transaction/platform/sepa/init",
|
|
131
111
|
TRANSACTION_BATCH_INIT: "/transaction/platform/batchPayment/init",
|
|
132
112
|
BATCH_STATUS: "/transaction/platform/batchPayment/status"
|
|
133
113
|
};
|
|
@@ -201,6 +181,7 @@ const mapFinbricksTransactionToPayment = (tx, account) => {
|
|
|
201
181
|
const related = tx.entryDetails?.transactionDetails?.relatedParties;
|
|
202
182
|
const base = {
|
|
203
183
|
id: uuidv4(),
|
|
184
|
+
connectorKey: account.connectorKey,
|
|
204
185
|
bankRefId: tx.entryReference || tx.fbxReference,
|
|
205
186
|
amount: tx.amount?.value || 0,
|
|
206
187
|
currency: tx.amount?.currency || "CZK",
|
|
@@ -213,49 +194,65 @@ const mapFinbricksTransactionToPayment = (tx, account) => {
|
|
|
213
194
|
),
|
|
214
195
|
debtorHolderName: isIncoming ? related?.debtor?.name || "Unknown" : "Unknown",
|
|
215
196
|
creditorHolderName: isIncoming ? "Unknown" : related?.creditor?.name || "Unknown",
|
|
216
|
-
debtorIban: isIncoming ? related
|
|
217
|
-
creditorIban: isIncoming ? account.
|
|
197
|
+
debtorIban: isIncoming ? related.debtorAccount?.identification?.iban || account.iban : account.iban,
|
|
198
|
+
creditorIban: isIncoming ? account.iban : related.creditorAccount?.identification?.iban || account.iban,
|
|
218
199
|
direction: "INCOMING"
|
|
219
200
|
// přepíšeme správným směrem níže
|
|
220
201
|
};
|
|
221
|
-
base.direction = getPaymentDirection(base, account.
|
|
202
|
+
base.direction = getPaymentDirection(base, account.iban);
|
|
222
203
|
return base;
|
|
223
204
|
};
|
|
224
205
|
|
|
206
|
+
const mapFinbricksAccountInsert = ({
|
|
207
|
+
account,
|
|
208
|
+
connectorKey,
|
|
209
|
+
status
|
|
210
|
+
}) => ({
|
|
211
|
+
id: account.id,
|
|
212
|
+
connectorKey,
|
|
213
|
+
status,
|
|
214
|
+
sync: false,
|
|
215
|
+
currency: account.currency,
|
|
216
|
+
number: account.identification.accountNumber,
|
|
217
|
+
bankCode: account.servicer.bankCode,
|
|
218
|
+
// For now we are using CZE as fallback because finbricks does not provide country code 100% of the time
|
|
219
|
+
countryCode: account.servicer.countryCode || "CZE",
|
|
220
|
+
holderName: account.ownersNames.join(", "),
|
|
221
|
+
iban: account.identification.iban
|
|
222
|
+
});
|
|
223
|
+
|
|
225
224
|
class FinbricksConnector extends IBankConnector {
|
|
226
225
|
constructor(provider, {
|
|
227
226
|
BASE_URI,
|
|
228
227
|
MERCHANT_ID,
|
|
229
228
|
PRIVATE_KEY_PEM,
|
|
230
229
|
REDIRECT_URI,
|
|
231
|
-
|
|
230
|
+
connectedAccounts
|
|
232
231
|
}) {
|
|
233
232
|
super();
|
|
234
233
|
this.connectorKey = "FINBRICKS";
|
|
235
|
-
this.
|
|
234
|
+
this.connectedAccounts = [];
|
|
236
235
|
this.PROVIDER = provider;
|
|
237
|
-
this.kv = KV;
|
|
238
236
|
this.finbricks = new FinbricksClient(
|
|
239
237
|
BASE_URI,
|
|
240
238
|
MERCHANT_ID,
|
|
241
239
|
PRIVATE_KEY_PEM,
|
|
242
240
|
REDIRECT_URI
|
|
243
241
|
);
|
|
242
|
+
this.connectedAccounts = connectedAccounts;
|
|
244
243
|
}
|
|
245
244
|
static {
|
|
246
245
|
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
247
246
|
}
|
|
248
|
-
async getAuthUri({
|
|
249
|
-
accountId,
|
|
250
|
-
ott
|
|
251
|
-
}) {
|
|
247
|
+
async getAuthUri({ ott }) {
|
|
252
248
|
const clientId = uuidv4();
|
|
253
249
|
const body = {
|
|
254
250
|
merchantId: this.finbricks.MERCHANT_ID,
|
|
255
251
|
clientId,
|
|
256
252
|
paymentProvider: this.PROVIDER,
|
|
257
253
|
scope: "AISP_PISP",
|
|
258
|
-
|
|
254
|
+
// finbricks automatically adds the clientId to the callbackUrl
|
|
255
|
+
callbackUrl: `${this.finbricks.REDIRECT_URI}?ott=${ott}`
|
|
259
256
|
};
|
|
260
257
|
const [response, error] = await useResult(
|
|
261
258
|
this.finbricks.request({
|
|
@@ -271,35 +268,13 @@ class FinbricksConnector extends IBankConnector {
|
|
|
271
268
|
}
|
|
272
269
|
return response.redirectUrl;
|
|
273
270
|
}
|
|
274
|
-
|
|
275
|
-
return `${this.connectorKey}:auth`;
|
|
276
|
-
}
|
|
277
|
-
async getClientIds() {
|
|
278
|
-
let saved = await this.kv.get(this.storageKey);
|
|
279
|
-
if (!saved) {
|
|
280
|
-
const empty = Object.fromEntries(CONNECTOR_KEYS.map((v) => [v, ""]));
|
|
281
|
-
empty["FIO"] = "d32a83cf-d352-41f3-96d7-4d2961336ddc";
|
|
282
|
-
await this.kv.put(this.storageKey, JSON.stringify(empty));
|
|
283
|
-
saved = JSON.stringify(empty);
|
|
284
|
-
}
|
|
285
|
-
this._clientIds = JSON.parse(saved);
|
|
286
|
-
return this._clientIds;
|
|
287
|
-
}
|
|
288
|
-
async setClientIds(value) {
|
|
289
|
-
this._clientIds = value;
|
|
290
|
-
void this.kv.put(this.storageKey, JSON.stringify(value));
|
|
291
|
-
}
|
|
292
|
-
async authorizeAccount({
|
|
293
|
-
urlParams
|
|
294
|
-
}) {
|
|
271
|
+
async authorizeAccount({ urlParams }) {
|
|
295
272
|
const params = new URLSearchParams(urlParams);
|
|
296
273
|
const clientId = params.get("clientId");
|
|
297
274
|
if (!clientId)
|
|
298
275
|
throw createInternalError(null, {
|
|
299
276
|
message: "Finbricks: clientId is missing"
|
|
300
277
|
});
|
|
301
|
-
let savedClientIds = await this.getClientIds();
|
|
302
|
-
await this.setClientIds({ ...savedClientIds, [this.PROVIDER]: clientId });
|
|
303
278
|
const expired = await this.isClientIdExpired({ clientId });
|
|
304
279
|
if (expired) {
|
|
305
280
|
throw createInternalError(null, {
|
|
@@ -308,7 +283,34 @@ class FinbricksConnector extends IBankConnector {
|
|
|
308
283
|
status: 401
|
|
309
284
|
});
|
|
310
285
|
}
|
|
311
|
-
|
|
286
|
+
const accounts = await this.getAccountsForClient({ clientId });
|
|
287
|
+
console.log(accounts, "accs finbricks");
|
|
288
|
+
const credentials = accounts.map((acc) => ({
|
|
289
|
+
accountId: acc.id,
|
|
290
|
+
connectorKey: this.PROVIDER,
|
|
291
|
+
expiresAt: new Date(Date.now() + 36e5),
|
|
292
|
+
type: "CLIENT_ID",
|
|
293
|
+
value: clientId
|
|
294
|
+
}));
|
|
295
|
+
this.connectedAccounts.push(
|
|
296
|
+
...accounts.map((acc) => ({
|
|
297
|
+
connectorKey: this.PROVIDER,
|
|
298
|
+
currency: acc.currency,
|
|
299
|
+
iban: acc.identification.iban,
|
|
300
|
+
id: acc.id,
|
|
301
|
+
token: clientId
|
|
302
|
+
}))
|
|
303
|
+
);
|
|
304
|
+
return {
|
|
305
|
+
credentials,
|
|
306
|
+
accounts: accounts.map(
|
|
307
|
+
(account) => mapFinbricksAccountInsert({
|
|
308
|
+
account,
|
|
309
|
+
connectorKey: this.PROVIDER,
|
|
310
|
+
status: "AUTHORIZED"
|
|
311
|
+
})
|
|
312
|
+
)
|
|
313
|
+
};
|
|
312
314
|
}
|
|
313
315
|
async authenticate(code) {
|
|
314
316
|
return "";
|
|
@@ -356,13 +358,9 @@ class FinbricksConnector extends IBankConnector {
|
|
|
356
358
|
const validTo = new Date(record.validTo);
|
|
357
359
|
return validTo.getTime() < Date.now();
|
|
358
360
|
}
|
|
359
|
-
async
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
message: "Finbricks: missing valid clientId",
|
|
363
|
-
code: "FINBRICKS_CLIENT_ID_MISSING"
|
|
364
|
-
});
|
|
365
|
-
}
|
|
361
|
+
async getAccountsForClient({
|
|
362
|
+
clientId
|
|
363
|
+
}) {
|
|
366
364
|
const [response, error] = await useResult(
|
|
367
365
|
this.finbricks.request({
|
|
368
366
|
endpoint: FINBRICKS_ENDPOINTS.ACCOUNT_LIST,
|
|
@@ -370,17 +368,40 @@ class FinbricksConnector extends IBankConnector {
|
|
|
370
368
|
query: {
|
|
371
369
|
merchantId: this.finbricks.MERCHANT_ID,
|
|
372
370
|
paymentProvider: this.PROVIDER,
|
|
373
|
-
clientId
|
|
371
|
+
clientId
|
|
374
372
|
}
|
|
375
373
|
})
|
|
376
374
|
);
|
|
377
375
|
if (error || !response) {
|
|
376
|
+
console.log(error, "err");
|
|
377
|
+
console.log(response, "res");
|
|
378
378
|
throw createInternalError(error, {
|
|
379
379
|
message: "Finbricks: failed to list accounts"
|
|
380
380
|
});
|
|
381
381
|
}
|
|
382
382
|
return response.accounts;
|
|
383
383
|
}
|
|
384
|
+
async listAccounts() {
|
|
385
|
+
const accounts = (await Promise.all(
|
|
386
|
+
this.connectedAccounts.map(
|
|
387
|
+
(acc) => this.getAccountsForClient({ clientId: acc.token })
|
|
388
|
+
)
|
|
389
|
+
)).flat();
|
|
390
|
+
const uniqueAccounts = Array.from(
|
|
391
|
+
new Map(accounts.map((acc) => [acc.identification.iban, acc])).values()
|
|
392
|
+
);
|
|
393
|
+
return uniqueAccounts.map((acc) => ({
|
|
394
|
+
connectorKey: this.connectorKey,
|
|
395
|
+
currency: acc.currency,
|
|
396
|
+
sync: false,
|
|
397
|
+
status: "AUTHORIZED",
|
|
398
|
+
countryCode: acc.servicer.countryCode,
|
|
399
|
+
bankCode: acc.servicer.bankCode,
|
|
400
|
+
number: acc.identification.accountNumber,
|
|
401
|
+
iban: acc.identification.iban,
|
|
402
|
+
holderName: acc.ownersNames.join(", ")
|
|
403
|
+
}));
|
|
404
|
+
}
|
|
384
405
|
async preparePayment(payment) {
|
|
385
406
|
const bankRefId = uuidv4();
|
|
386
407
|
return {
|
|
@@ -397,6 +418,13 @@ class FinbricksConnector extends IBankConnector {
|
|
|
397
418
|
payments
|
|
398
419
|
}) {
|
|
399
420
|
const batchId = uuidv4();
|
|
421
|
+
const authorizedClient = this.connectedAccounts.find(
|
|
422
|
+
(acc) => acc.iban === payments[0].debtorIban
|
|
423
|
+
);
|
|
424
|
+
if (!authorizedClient)
|
|
425
|
+
throw createInternalError(null, {
|
|
426
|
+
message: `Batch for unauthorized client with iban: ${payments[0].debtorIban}`
|
|
427
|
+
});
|
|
400
428
|
const [response, error] = await useResult(
|
|
401
429
|
this.finbricks.request({
|
|
402
430
|
endpoint: FINBRICKS_ENDPOINTS.TRANSACTION_BATCH_INIT,
|
|
@@ -405,7 +433,7 @@ class FinbricksConnector extends IBankConnector {
|
|
|
405
433
|
batchPaymentIdentification: {
|
|
406
434
|
merchantId: this.finbricks.MERCHANT_ID,
|
|
407
435
|
debtorAccountIban: payments[0].debtorIban,
|
|
408
|
-
clientId:
|
|
436
|
+
clientId: authorizedClient.token,
|
|
409
437
|
callbackUrl: "https://example.com/callback",
|
|
410
438
|
merchantBatchId: batchId
|
|
411
439
|
},
|
|
@@ -428,6 +456,47 @@ class FinbricksConnector extends IBankConnector {
|
|
|
428
456
|
payments: payments.map((p) => ({ ...p, status: "INITIALIZED" }))
|
|
429
457
|
};
|
|
430
458
|
}
|
|
459
|
+
async initiateSEPAPayment(payment) {
|
|
460
|
+
const [response, error] = await useResult(
|
|
461
|
+
this.finbricks.request({
|
|
462
|
+
endpoint: FINBRICKS_ENDPOINTS.TRANSACTION_SEPA_INIT,
|
|
463
|
+
method: "POST",
|
|
464
|
+
body: {
|
|
465
|
+
merchantIdentification: {
|
|
466
|
+
merchantId: this.finbricks.MERCHANT_ID,
|
|
467
|
+
clientId: this.connectedAccounts.find(
|
|
468
|
+
(acc) => acc.iban === payment.debtorIban
|
|
469
|
+
).token
|
|
470
|
+
},
|
|
471
|
+
paymentIdentification: {
|
|
472
|
+
merchantTransactionId: payment.bankRefId
|
|
473
|
+
},
|
|
474
|
+
amount: payment.amount,
|
|
475
|
+
debtor: {
|
|
476
|
+
debtorAccountIban: payment.debtorIban,
|
|
477
|
+
debtorName: payment.debtorHolderName || "Devizov\xE1 burza",
|
|
478
|
+
paymentProvider: this.PROVIDER
|
|
479
|
+
},
|
|
480
|
+
creditor: {
|
|
481
|
+
creditorAccountIban: payment.creditorIban,
|
|
482
|
+
creditorName: payment.creditorHolderName
|
|
483
|
+
},
|
|
484
|
+
callbackUrl: "https://www.example.com"
|
|
485
|
+
}
|
|
486
|
+
})
|
|
487
|
+
);
|
|
488
|
+
if (error || !response) {
|
|
489
|
+
console.log(error, "err");
|
|
490
|
+
console.log(response, "res");
|
|
491
|
+
throw createInternalError(error, {
|
|
492
|
+
message: "Finbricks: failed to initiate SEPA payment"
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
return {
|
|
496
|
+
authorizationUrl: response.redirectUrl,
|
|
497
|
+
payment: { ...payment, status: "INITIALIZED" }
|
|
498
|
+
};
|
|
499
|
+
}
|
|
431
500
|
async initiateSinglePayment(payment) {
|
|
432
501
|
const [response, error] = await useResult(
|
|
433
502
|
this.finbricks.request({
|
|
@@ -440,14 +509,16 @@ class FinbricksConnector extends IBankConnector {
|
|
|
440
509
|
debtorAccountIban: payment.debtorIban,
|
|
441
510
|
creditorAccountIban: payment.creditorIban,
|
|
442
511
|
creditorName: payment.creditorHolderName,
|
|
443
|
-
description: payment.message
|
|
444
|
-
variableSymbol: payment.vs
|
|
512
|
+
description: payment.message,
|
|
513
|
+
variableSymbol: payment.vs,
|
|
445
514
|
callbackUrl: "https://example.com/callback",
|
|
446
515
|
paymentProvider: this.PROVIDER
|
|
447
516
|
}
|
|
448
517
|
})
|
|
449
518
|
);
|
|
450
519
|
if (error || !response) {
|
|
520
|
+
console.log(error, "err");
|
|
521
|
+
console.log(response, "res");
|
|
451
522
|
throw createInternalError(error, {
|
|
452
523
|
message: "Finbricks: failed to initiate payment"
|
|
453
524
|
});
|
|
@@ -473,11 +544,11 @@ class FinbricksConnector extends IBankConnector {
|
|
|
473
544
|
endpoint: FINBRICKS_ENDPOINTS.ACCOUNT_TRANSACTIONS,
|
|
474
545
|
query: {
|
|
475
546
|
merchantId: this.finbricks.MERCHANT_ID,
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
547
|
+
clientId: this.connectedAccounts.find(
|
|
548
|
+
(acc) => acc.iban === account.iban
|
|
549
|
+
).token,
|
|
479
550
|
paymentProvider: this.PROVIDER,
|
|
480
|
-
bankAccountId: account.
|
|
551
|
+
bankAccountId: account.id,
|
|
481
552
|
dateFrom,
|
|
482
553
|
dateTo,
|
|
483
554
|
currency: account.currency,
|
|
@@ -564,17 +635,17 @@ class ErsteConnector extends IBankConnector {
|
|
|
564
635
|
this.AUTH_URI = config.AUTH_URI;
|
|
565
636
|
this.PAYMENTS_URI = config.PAYMENTS_URI;
|
|
566
637
|
this.ACCOUNTS_URI = config.ACCOUNTS_URI;
|
|
567
|
-
this.
|
|
638
|
+
this.connectedAccounts = config.connectedAccounts;
|
|
639
|
+
}
|
|
640
|
+
initiateSEPAPayment(payment) {
|
|
641
|
+
throw new Error("Method not implemented.");
|
|
568
642
|
}
|
|
569
643
|
static {
|
|
570
644
|
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
571
645
|
}
|
|
572
|
-
async getAuthUri({
|
|
573
|
-
accountId,
|
|
574
|
-
ott
|
|
575
|
-
}) {
|
|
646
|
+
async getAuthUri({ ott }) {
|
|
576
647
|
const params = new URLSearchParams({
|
|
577
|
-
redirect_uri: `${this.REDIRECT_URI}
|
|
648
|
+
redirect_uri: `${this.REDIRECT_URI}?&ott=${ott}`,
|
|
578
649
|
client_id: this.CLIENT_ID,
|
|
579
650
|
response_type: "code",
|
|
580
651
|
access_type: "offline",
|
|
@@ -583,17 +654,25 @@ class ErsteConnector extends IBankConnector {
|
|
|
583
654
|
});
|
|
584
655
|
return `${this.AUTH_URI}/auth?${params.toString()}`;
|
|
585
656
|
}
|
|
586
|
-
async authorizeAccount({
|
|
587
|
-
urlParams
|
|
588
|
-
}) {
|
|
657
|
+
async authorizeAccount({ urlParams }) {
|
|
589
658
|
const params = new URLSearchParams(urlParams);
|
|
590
659
|
const code = params.get("code");
|
|
591
660
|
if (!code)
|
|
592
661
|
throw createInternalError(null, {
|
|
593
662
|
message: "Missing code in params"
|
|
594
663
|
});
|
|
595
|
-
|
|
596
|
-
|
|
664
|
+
return {
|
|
665
|
+
accounts: [],
|
|
666
|
+
credentials: [
|
|
667
|
+
{
|
|
668
|
+
accountId: "",
|
|
669
|
+
connectorKey: this.connectorKey,
|
|
670
|
+
type: "AUTH_TOKEN",
|
|
671
|
+
expiresAt: new Date(Date.now() + 1e3 * 60 * 60 * 24 * 30),
|
|
672
|
+
value: code
|
|
673
|
+
}
|
|
674
|
+
]
|
|
675
|
+
};
|
|
597
676
|
}
|
|
598
677
|
async authenticate(tokens) {
|
|
599
678
|
const grantType = tokens?.refreshToken ? "refresh_token" : "authorization_code";
|
|
@@ -602,11 +681,10 @@ class ErsteConnector extends IBankConnector {
|
|
|
602
681
|
client_secret: this.CLIENT_SECRET,
|
|
603
682
|
grant_type: grantType
|
|
604
683
|
};
|
|
605
|
-
|
|
606
|
-
if (token) {
|
|
684
|
+
if (tokens?.token) {
|
|
607
685
|
bodyParams = {
|
|
608
686
|
...bodyParams,
|
|
609
|
-
code: token,
|
|
687
|
+
code: tokens.token,
|
|
610
688
|
redirect_uri: this.REDIRECT_URI
|
|
611
689
|
};
|
|
612
690
|
}
|
|
@@ -787,6 +865,7 @@ class ErsteConnector extends IBankConnector {
|
|
|
787
865
|
const symbols = mapReferencesToPayment(reference);
|
|
788
866
|
const paymentInsert = {
|
|
789
867
|
id: uuidv4(),
|
|
868
|
+
connectorKey: "ERSTE",
|
|
790
869
|
bankRefId: payment.entryReference,
|
|
791
870
|
amount: payment.amount.value,
|
|
792
871
|
currency: payment.amount.currency.code,
|
|
@@ -807,10 +886,7 @@ class ErsteConnector extends IBankConnector {
|
|
|
807
886
|
};
|
|
808
887
|
return {
|
|
809
888
|
...paymentInsert,
|
|
810
|
-
direction: getPaymentDirection(
|
|
811
|
-
paymentInsert,
|
|
812
|
-
account.identification.iban
|
|
813
|
-
)
|
|
889
|
+
direction: getPaymentDirection(paymentInsert, account.iban)
|
|
814
890
|
};
|
|
815
891
|
});
|
|
816
892
|
return payments;
|
|
@@ -824,10 +900,13 @@ class ErsteConnector extends IBankConnector {
|
|
|
824
900
|
}
|
|
825
901
|
|
|
826
902
|
class MockConnector extends IBankConnector {
|
|
827
|
-
constructor(
|
|
903
|
+
constructor() {
|
|
828
904
|
super();
|
|
829
905
|
this.connectorKey = "MOCK";
|
|
830
|
-
this.
|
|
906
|
+
this.connectedAccounts = [];
|
|
907
|
+
}
|
|
908
|
+
initiateSEPAPayment(payment) {
|
|
909
|
+
throw new Error("Method not implemented.");
|
|
831
910
|
}
|
|
832
911
|
static {
|
|
833
912
|
this.FETCH_INTERVAL = 60 * 60 * 5;
|
|
@@ -839,13 +918,15 @@ class MockConnector extends IBankConnector {
|
|
|
839
918
|
return [];
|
|
840
919
|
}
|
|
841
920
|
async getAuthUri({
|
|
842
|
-
accountId
|
|
843
|
-
ott
|
|
921
|
+
accountId
|
|
844
922
|
}) {
|
|
845
923
|
return `<base-uri>/auth?ott=ott&accountId=${accountId}`;
|
|
846
924
|
}
|
|
847
|
-
async authorizeAccount() {
|
|
848
|
-
return
|
|
925
|
+
async authorizeAccount({}) {
|
|
926
|
+
return {
|
|
927
|
+
credentials: [],
|
|
928
|
+
accounts: []
|
|
929
|
+
};
|
|
849
930
|
}
|
|
850
931
|
async preparePayment(payment) {
|
|
851
932
|
const bankRefId = uuidv4();
|
|
@@ -902,11 +983,27 @@ class MockConnector extends IBankConnector {
|
|
|
902
983
|
}
|
|
903
984
|
}
|
|
904
985
|
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
986
|
+
const PAYMENT_TYPES = ["SEPA", "SWIFT", "IFSC", "DOMESTIC"];
|
|
987
|
+
const PAYMENT_STATUSES = [
|
|
988
|
+
"PREPARED",
|
|
989
|
+
"INITIALIZED",
|
|
990
|
+
"FAILED",
|
|
991
|
+
"PENDING",
|
|
992
|
+
"COMPLETED",
|
|
993
|
+
"CREATED"
|
|
994
|
+
];
|
|
995
|
+
const PAYMENT_DIRECTIONS = ["INCOMING", "OUTGOING"];
|
|
996
|
+
const BATCH_STATUSES = [
|
|
997
|
+
"OPEN",
|
|
998
|
+
"PROCESSING",
|
|
999
|
+
"READY_TO_SIGN",
|
|
1000
|
+
"WAITING_FOR_PROCESSING",
|
|
1001
|
+
"PREPARED",
|
|
1002
|
+
"COMPLETED",
|
|
1003
|
+
"FAILED"
|
|
1004
|
+
];
|
|
1005
|
+
const ACCOUNT_STATUSES = ["AUTHORIZED", "DISABLED", "EXPIRED"];
|
|
1006
|
+
const COUNTRY_CODES = COUNTRY_CODES_2;
|
|
910
1007
|
|
|
911
1008
|
const paymentInsertTypeZod = z.object({
|
|
912
1009
|
refId: z.string(),
|
|
@@ -929,4 +1026,130 @@ const paymentInsertTypeZod = z.object({
|
|
|
929
1026
|
debtorHolderName: z.string().nullable()
|
|
930
1027
|
});
|
|
931
1028
|
|
|
932
|
-
|
|
1029
|
+
const CONNECTOR_KEYS = [
|
|
1030
|
+
"ERSTE",
|
|
1031
|
+
"FINBRICKS",
|
|
1032
|
+
"MOCK",
|
|
1033
|
+
"CREDITAS",
|
|
1034
|
+
"MOCK_COBS",
|
|
1035
|
+
"FIO",
|
|
1036
|
+
"MONETA"
|
|
1037
|
+
];
|
|
1038
|
+
const CREDENTIALS_TYPES = [
|
|
1039
|
+
"AUTH_TOKEN",
|
|
1040
|
+
"REFRESH_TOKEN",
|
|
1041
|
+
"CLIENT_ID",
|
|
1042
|
+
"API_KEY"
|
|
1043
|
+
];
|
|
1044
|
+
const TOKEN_TYPES = ["ACCOUNT_AUTHORIZATION"];
|
|
1045
|
+
|
|
1046
|
+
const account = sqliteTable(
|
|
1047
|
+
"account",
|
|
1048
|
+
{
|
|
1049
|
+
...base,
|
|
1050
|
+
...bankAccount,
|
|
1051
|
+
connectorKey: text("connector_key", {
|
|
1052
|
+
enum: CONNECTOR_KEYS
|
|
1053
|
+
}).$type().notNull(),
|
|
1054
|
+
status: text("status", { enum: ACCOUNT_STATUSES }).$type().notNull(),
|
|
1055
|
+
sync: integer("sync", { mode: "boolean" }).default(false).notNull(),
|
|
1056
|
+
syncPeriod: integer("sync_period"),
|
|
1057
|
+
lastSyncedAt: integer("last_synced_at", { mode: "timestamp_ms" })
|
|
1058
|
+
},
|
|
1059
|
+
(t) => [unique().on(t.iban)]
|
|
1060
|
+
);
|
|
1061
|
+
|
|
1062
|
+
const accountInsertSchema = createInsertSchema(account);
|
|
1063
|
+
const accountUpdateSchema = createUpdateSchema(account);
|
|
1064
|
+
const accountSelectSchema = createSelectSchema(account);
|
|
1065
|
+
|
|
1066
|
+
const accountCredentials = sqliteTable("account_credentials", {
|
|
1067
|
+
...base,
|
|
1068
|
+
accountId: text("account_id").references(() => account.id).notNull(),
|
|
1069
|
+
connectorKey: text("connector_key", {
|
|
1070
|
+
enum: CONNECTOR_KEYS
|
|
1071
|
+
}).$type().notNull(),
|
|
1072
|
+
type: text("type", {
|
|
1073
|
+
enum: CREDENTIALS_TYPES
|
|
1074
|
+
}).$type().notNull(),
|
|
1075
|
+
value: text("value").notNull(),
|
|
1076
|
+
expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull()
|
|
1077
|
+
});
|
|
1078
|
+
|
|
1079
|
+
const accountCredentialsInsertSchema = createInsertSchema(accountCredentials);
|
|
1080
|
+
const accountCredentialsUpdateSchema = createUpdateSchema(accountCredentials);
|
|
1081
|
+
const accountCredentialsSelectSchema = createSelectSchema(accountCredentials);
|
|
1082
|
+
|
|
1083
|
+
const ott = sqliteTable("ott", {
|
|
1084
|
+
...base,
|
|
1085
|
+
oneTimeToken: text("one_time_token").notNull(),
|
|
1086
|
+
refId: text("ref_id").notNull(),
|
|
1087
|
+
tokenType: text("token_type", { enum: TOKEN_TYPES }).$type().notNull(),
|
|
1088
|
+
expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull()
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
const ottInsertSchema = createInsertSchema(ott);
|
|
1092
|
+
const ottUpdateSchema = createUpdateSchema(ott);
|
|
1093
|
+
const ottSelectSchema = createSelectSchema(ott);
|
|
1094
|
+
|
|
1095
|
+
const batch = sqliteTable("batch", {
|
|
1096
|
+
...base,
|
|
1097
|
+
batchPaymentInitiatedAt: integer("batch_payment_initiated_at", {
|
|
1098
|
+
mode: "timestamp_ms"
|
|
1099
|
+
}),
|
|
1100
|
+
authorizationUrls: text("authorization_urls", { mode: "json" }).$type(),
|
|
1101
|
+
accountId: text("account_id"),
|
|
1102
|
+
status: text("status", { enum: BATCH_STATUSES }).$type(),
|
|
1103
|
+
payments: text("payments", { mode: "json" }).$type().notNull(),
|
|
1104
|
+
metadata: text("metadata", { mode: "json" }).$type()
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
const payment = sqliteTable("payment", {
|
|
1108
|
+
...base,
|
|
1109
|
+
refId: text("ref_id"),
|
|
1110
|
+
bankRefId: text("bank_ref_id"),
|
|
1111
|
+
accountId: text("account_id").references(() => account.id).notNull(),
|
|
1112
|
+
connectorKey: text("connector_key", { enum: CONNECTOR_KEYS }).$type().notNull(),
|
|
1113
|
+
amount: real("amount").notNull(),
|
|
1114
|
+
direction: text("direction").$type().notNull(),
|
|
1115
|
+
paymentType: text("payment_type").$type(),
|
|
1116
|
+
currency: text("currency").$type().notNull(),
|
|
1117
|
+
status: text("status").$type().notNull(),
|
|
1118
|
+
statusReason: text("status_reason"),
|
|
1119
|
+
batchId: text("bank_execution_batch_id"),
|
|
1120
|
+
initiatedAt: integer("initiated_at", {
|
|
1121
|
+
mode: "timestamp_ms"
|
|
1122
|
+
}),
|
|
1123
|
+
vs: text("vs"),
|
|
1124
|
+
ss: text("ss"),
|
|
1125
|
+
ks: text("ks"),
|
|
1126
|
+
message: text("message"),
|
|
1127
|
+
processedAt: integer("processed_at", {
|
|
1128
|
+
mode: "timestamp_ms"
|
|
1129
|
+
}),
|
|
1130
|
+
creditorHolderName: text("creditor_holder_name").notNull(),
|
|
1131
|
+
creditorAccountNumberWithBankCode: text(
|
|
1132
|
+
"creditor_account_number_with_bank_code"
|
|
1133
|
+
),
|
|
1134
|
+
creditorIban: text("creditor_iban"),
|
|
1135
|
+
debtorIban: text("debtor_iban"),
|
|
1136
|
+
debtorHolderName: text("debtor_holder_name"),
|
|
1137
|
+
debtorAccountNumberWithBankCode: text("debtor_account_number_with_bank_code")
|
|
1138
|
+
});
|
|
1139
|
+
const paymentRelations = relations(payment, ({ one }) => ({
|
|
1140
|
+
batch: one(batch, { fields: [payment.batchId], references: [batch.id] })
|
|
1141
|
+
}));
|
|
1142
|
+
|
|
1143
|
+
const schema = {
|
|
1144
|
+
__proto__: null,
|
|
1145
|
+
account: account,
|
|
1146
|
+
accountCredentials: accountCredentials,
|
|
1147
|
+
batch: batch,
|
|
1148
|
+
ott: ott,
|
|
1149
|
+
payment: payment,
|
|
1150
|
+
paymentRelations: paymentRelations
|
|
1151
|
+
};
|
|
1152
|
+
|
|
1153
|
+
const tables = schema;
|
|
1154
|
+
|
|
1155
|
+
export { ACCOUNT_STATUSES as A, BATCH_STATUSES as B, COUNTRY_CODES as C, ErsteConnector as E, FinbricksConnector as F, IBankConnector as I, MockConnector as M, PAYMENT_TYPES as P, TOKEN_TYPES as T, FinbricksClient as a, FINBRICKS_ENDPOINTS as b, PAYMENT_STATUSES as c, PAYMENT_DIRECTIONS as d, CONNECTOR_KEYS as e, CREDENTIALS_TYPES as f, accountInsertSchema as g, accountUpdateSchema as h, accountSelectSchema as i, accountCredentialsInsertSchema as j, accountCredentialsUpdateSchema as k, accountCredentialsSelectSchema as l, ottUpdateSchema as m, ottSelectSchema as n, ottInsertSchema as o, paymentInsertTypeZod as p, getPaymentDirection as q, batch as r, signFinbricksJws as s, tables as t, useFinbricksFetch as u, payment as v, paymentRelations as w, ott as x, account as y, accountCredentials as z };
|