@develit-services/bank 5.4.2 → 5.5.1

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.
@@ -1,10 +1,10 @@
1
1
  import { uuidv4, createInternalError, useResult, structuredAddressSchema } from '@develit-io/backend-sdk';
2
2
  import { format, parseISO } from 'date-fns';
3
+ import { s as schema, h as account, i as accountCredentials, o as ott } from './bank.BzDNLxB_.mjs';
4
+ import { defineRelations, and, not, inArray, isNull } from 'drizzle-orm';
3
5
  import { importPKCS8, SignJWT } from 'jose';
4
6
  import { z } from 'zod';
5
7
  import { CURRENCY_CODES } from '@develit-io/general-codes';
6
- import { s as schema, h as account, i as accountCredentials, o as ott } from './bank.BzDNLxB_.mjs';
7
- import { defineRelations, and, not, inArray, isNull } from 'drizzle-orm';
8
8
  import { createInsertSchema, createUpdateSchema, createSelectSchema } from 'drizzle-orm/zod';
9
9
  import 'node:crypto';
10
10
 
@@ -750,6 +750,49 @@ const mapFinbricksTransactionToPayment = (tx, account) => {
750
750
  return base;
751
751
  };
752
752
 
753
+ function mod97(string) {
754
+ let checksum = string.slice(0, 2);
755
+ let fragment = "";
756
+ for (let offset = 2; offset < string.length; offset += 7) {
757
+ fragment = checksum + string.substring(offset, offset + 7);
758
+ checksum = (parseInt(fragment, 10) % 97).toString();
759
+ }
760
+ return parseInt(checksum, 10);
761
+ }
762
+ const parseCzechIban = (iban) => {
763
+ const stripped = iban.replace(/\s/g, "").toUpperCase();
764
+ if (!stripped.startsWith("CZ") || stripped.length !== 24) {
765
+ throw new Error(`Invalid Czech IBAN: ${iban}`);
766
+ }
767
+ const bankCode = stripped.slice(4, 8);
768
+ const prefix = stripped.slice(8, 14).replace(/^0+/, "");
769
+ const main = stripped.slice(14, 24).replace(/^0+/, "");
770
+ const accountNumber = prefix ? `${prefix}-${main}` : main;
771
+ return { bankCode, accountNumber };
772
+ };
773
+ const calculateCzechIban = (accountNumber, bankCode) => {
774
+ const paddedBankCode = bankCode.padStart(4, "0");
775
+ let prefix = "";
776
+ let mainAccount = accountNumber;
777
+ if (accountNumber.includes("-")) {
778
+ const parts = accountNumber.split("-");
779
+ if (parts.length !== 2) {
780
+ throw new Error(
781
+ `Invalid account number format: expected "prefix-main" or "main", got "${accountNumber}"`
782
+ );
783
+ }
784
+ prefix = parts[0];
785
+ mainAccount = parts[1];
786
+ }
787
+ const paddedPrefix = prefix.padStart(6, "0");
788
+ const paddedAccount = mainAccount.padStart(10, "0");
789
+ const basicIban = paddedBankCode + paddedPrefix + paddedAccount;
790
+ const rearranged = basicIban + "123500";
791
+ const remainder = mod97(rearranged);
792
+ const checkDigits = (98 - remainder).toString().padStart(2, "0");
793
+ return `CZ${checkDigits}${basicIban}`;
794
+ };
795
+
753
796
  function autoVariableSymbol(paymentId) {
754
797
  let hash = 0;
755
798
  for (let i = 0; i < paymentId.length; i++) {
@@ -1061,7 +1104,7 @@ class FinbricksConnector extends IBankConnector {
1061
1104
  payment.currency
1062
1105
  );
1063
1106
  const creditorBic = payment.creditor.swiftBic ?? payment.creditor.bicCor;
1064
- const creditorAgent = creditorIdentification.type === "BBAN" && creditorBic ? {
1107
+ const creditorAgent = creditorBic ? {
1065
1108
  financialInstitutionIdentification: { bic: creditorBic }
1066
1109
  } : void 0;
1067
1110
  const reference = buildPaymentReference({
@@ -1197,6 +1240,10 @@ class FinbricksConnector extends IBankConnector {
1197
1240
  };
1198
1241
  }
1199
1242
  async initiateDomesticPayment(payment) {
1243
+ const debtorAccount = this.connectedAccounts.find(
1244
+ (acc) => acc.iban === payment.debtor.iban
1245
+ );
1246
+ const clientId = await this.getClientId(debtorAccount.id);
1200
1247
  const [response, error] = await useResult(
1201
1248
  this.finbricks.request({
1202
1249
  endpoint: FINBRICKS_ENDPOINTS.TRANSACTION_INIT,
@@ -1215,6 +1262,7 @@ class FinbricksConnector extends IBankConnector {
1215
1262
  specificSymbol: payment.ss,
1216
1263
  constantSymbol: payment.ks,
1217
1264
  callbackUrl: `${this.finbricks.REDIRECT_URI}?type=paymentRequest&paymentRequestId=${payment.id}`,
1265
+ clientId,
1218
1266
  paymentProvider: this.PROVIDER,
1219
1267
  instructionPriority: payment.instructionPriority ?? "NORM"
1220
1268
  }
@@ -2421,74 +2469,6 @@ const ottInsertSchema = createInsertSchema(ott);
2421
2469
  const ottUpdateSchema = createUpdateSchema(ott);
2422
2470
  const ottSelectSchema = createSelectSchema(ott);
2423
2471
 
2424
- class AirBankConnector extends FinbricksConnector {
2425
- constructor(config) {
2426
- super("AIRBANK", config);
2427
- }
2428
- supportsBatch() {
2429
- return false;
2430
- }
2431
- }
2432
-
2433
- class CreditasConnector extends FinbricksConnector {
2434
- constructor(config) {
2435
- super("CREDITAS", config);
2436
- }
2437
- /**
2438
- * Creditas bank doesn't support batch payments at all.
2439
- */
2440
- supportsBatch() {
2441
- return false;
2442
- }
2443
- }
2444
-
2445
- class CSASConnector extends FinbricksConnector {
2446
- constructor(config) {
2447
- super("CSAS", config);
2448
- }
2449
- supportsBatch(paymentType) {
2450
- return paymentType === "DOMESTIC";
2451
- }
2452
- }
2453
-
2454
- class FioConnector extends FinbricksConnector {
2455
- constructor(config) {
2456
- super("FIO", config);
2457
- }
2458
- /**
2459
- * FIO supports batch only for DOMESTIC (CZK) payments.
2460
- * SEPA and SWIFT batch support is planned by Finbricks.
2461
- */
2462
- supportsBatch(paymentType) {
2463
- return paymentType === "DOMESTIC";
2464
- }
2465
- }
2466
-
2467
- class MonetaConnector extends FinbricksConnector {
2468
- constructor(config) {
2469
- super("MONETA", config);
2470
- }
2471
- /**
2472
- * MONETA supports batch only for DOMESTIC (CZK) payments.
2473
- * SEPA and SWIFT batch support is planned by Finbricks.
2474
- */
2475
- supportsBatch(paymentType) {
2476
- return paymentType === "DOMESTIC";
2477
- }
2478
- /**
2479
- * MONETA rejects all special characters in endToEndIdentification.
2480
- * Boundaries between segments are unambiguous without a separator —
2481
- * `VS`/`SS`/`KS` prefixes are alphabetic and values are always numeric,
2482
- * so the parsing regex `VS[:\s]*(\d+)` extracts each value correctly.
2483
- *
2484
- * Format: `VS1234SS5678KS0308` (max 30 chars).
2485
- * Confirmed by Finbricks support (2026-04-23).
2486
- */
2487
- buildEndToEndId(payment) {
2488
- return buildEndToEndId(payment, { separator: "" });
2489
- }
2490
- }
2491
-
2492
2472
  const isDeposit = (payment, creditorIban) => {
2493
2473
  return payment.creditor.iban === creditorIban;
2494
2474
  };
@@ -2497,177 +2477,4 @@ const getPaymentDirection = (payment, iban) => {
2497
2477
  return "OUTGOING";
2498
2478
  };
2499
2479
 
2500
- const initiateConnector = async ({
2501
- bank,
2502
- env,
2503
- connectedAccounts,
2504
- resolveCredentials
2505
- }) => {
2506
- switch (bank) {
2507
- case "ERSTE":
2508
- return new ErsteConnector({
2509
- API_KEY: (await env.SECRETS_STORE.get({
2510
- secretName: "BANK_SERVICE_ERSTE_API_KEY"
2511
- })).data?.secretValue || "",
2512
- CLIENT_ID: (await env.SECRETS_STORE.get({
2513
- secretName: "BANK_SERVICE_ERSTE_CLIENT_ID"
2514
- })).data?.secretValue || "",
2515
- CLIENT_SECRET: (await env.SECRETS_STORE.get({
2516
- secretName: "BANK_SERVICE_ERSTE_CLIENT_SECRET"
2517
- })).data?.secretValue || "",
2518
- REDIRECT_URI: env.REDIRECT_URI,
2519
- AUTH_URI: env.ERSTE_AUTH_URI,
2520
- PAYMENTS_URI: env.ERSTE_PAYMENTS_URI,
2521
- ACCOUNTS_URI: env.ERSTE_ACCOUNTS_URI,
2522
- connectedAccounts,
2523
- resolveCredentials
2524
- });
2525
- case "CREDITAS":
2526
- return new CreditasConnector({
2527
- BASE_URI: env.FINBRICKS_BASE_URI,
2528
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2529
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2530
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2531
- })).data?.secretValue || "",
2532
- REDIRECT_URI: env.REDIRECT_URI,
2533
- connectedAccounts,
2534
- resolveCredentials
2535
- });
2536
- case "MOCK_COBS":
2537
- return new MockCobsConnector({
2538
- BASE_URI: env.FINBRICKS_BASE_URI,
2539
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2540
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2541
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2542
- })).data?.secretValue || "",
2543
- REDIRECT_URI: env.REDIRECT_URI,
2544
- connectedAccounts,
2545
- resolveCredentials
2546
- });
2547
- case "FIO":
2548
- return new FioConnector({
2549
- BASE_URI: env.FINBRICKS_BASE_URI,
2550
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2551
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2552
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2553
- })).data?.secretValue || "",
2554
- REDIRECT_URI: env.REDIRECT_URI,
2555
- connectedAccounts,
2556
- resolveCredentials
2557
- });
2558
- case "MONETA":
2559
- return new MonetaConnector({
2560
- BASE_URI: env.FINBRICKS_BASE_URI,
2561
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2562
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2563
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2564
- })).data?.secretValue || "",
2565
- REDIRECT_URI: env.REDIRECT_URI,
2566
- connectedAccounts,
2567
- resolveCredentials
2568
- });
2569
- case "AIRBANK":
2570
- return new AirBankConnector({
2571
- BASE_URI: env.FINBRICKS_BASE_URI,
2572
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2573
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2574
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2575
- })).data?.secretValue || "",
2576
- REDIRECT_URI: env.REDIRECT_URI,
2577
- connectedAccounts,
2578
- resolveCredentials
2579
- });
2580
- case "CSAS":
2581
- return new CSASConnector({
2582
- BASE_URI: env.FINBRICKS_BASE_URI,
2583
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2584
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2585
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2586
- })).data?.secretValue || "",
2587
- REDIRECT_URI: env.REDIRECT_URI,
2588
- connectedAccounts,
2589
- resolveCredentials
2590
- });
2591
- case "KB":
2592
- return new KBConnector({
2593
- BASE_URI: env.FINBRICKS_BASE_URI,
2594
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2595
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2596
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2597
- })).data?.secretValue || "",
2598
- REDIRECT_URI: env.REDIRECT_URI,
2599
- connectedAccounts,
2600
- resolveCredentials
2601
- });
2602
- case "CSOB":
2603
- return new CsobConnector({
2604
- BASE_URI: env.FINBRICKS_BASE_URI,
2605
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2606
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2607
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2608
- })).data?.secretValue || "",
2609
- REDIRECT_URI: env.REDIRECT_URI,
2610
- connectedAccounts,
2611
- resolveCredentials
2612
- });
2613
- case "DBU":
2614
- return new DbuConnector({
2615
- BASE_URL: env.DBUCS_BASE_URI,
2616
- USERNAME: env.DBUCS_USERNAME,
2617
- APPLICATION_CODE: env.DBUCS_APPLICATION_CODE,
2618
- KV: env.BANK_KV,
2619
- API: env.DBU_CBS_BACKOFFICE_DEV,
2620
- REDIRECT_URI: env.REDIRECT_URI,
2621
- TX_AUTH_URI: env.DBUCS_TX_AUTH_URI,
2622
- connectedAccounts
2623
- });
2624
- default:
2625
- const mockConnector = new MockConnector();
2626
- mockConnector.connectedAccounts = connectedAccounts;
2627
- return mockConnector;
2628
- }
2629
- };
2630
- function mod97(string) {
2631
- let checksum = string.slice(0, 2);
2632
- let fragment = "";
2633
- for (let offset = 2; offset < string.length; offset += 7) {
2634
- fragment = checksum + string.substring(offset, offset + 7);
2635
- checksum = (parseInt(fragment, 10) % 97).toString();
2636
- }
2637
- return parseInt(checksum, 10);
2638
- }
2639
- const parseCzechIban = (iban) => {
2640
- const stripped = iban.replace(/\s/g, "").toUpperCase();
2641
- if (!stripped.startsWith("CZ") || stripped.length !== 24) {
2642
- throw new Error(`Invalid Czech IBAN: ${iban}`);
2643
- }
2644
- const bankCode = stripped.slice(4, 8);
2645
- const prefix = stripped.slice(8, 14).replace(/^0+/, "");
2646
- const main = stripped.slice(14, 24).replace(/^0+/, "");
2647
- const accountNumber = prefix ? `${prefix}-${main}` : main;
2648
- return { bankCode, accountNumber };
2649
- };
2650
- const calculateCzechIban = (accountNumber, bankCode) => {
2651
- const paddedBankCode = bankCode.padStart(4, "0");
2652
- let prefix = "";
2653
- let mainAccount = accountNumber;
2654
- if (accountNumber.includes("-")) {
2655
- const parts = accountNumber.split("-");
2656
- if (parts.length !== 2) {
2657
- throw new Error(
2658
- `Invalid account number format: expected "prefix-main" or "main", got "${accountNumber}"`
2659
- );
2660
- }
2661
- prefix = parts[0];
2662
- mainAccount = parts[1];
2663
- }
2664
- const paddedPrefix = prefix.padStart(6, "0");
2665
- const paddedAccount = mainAccount.padStart(10, "0");
2666
- const basicIban = paddedBankCode + paddedPrefix + paddedAccount;
2667
- const rearranged = basicIban + "123500";
2668
- const remainder = mod97(rearranged);
2669
- const checkDigits = (98 - remainder).toString().padStart(2, "0");
2670
- return `CZ${checkDigits}${basicIban}`;
2671
- };
2672
-
2673
- export { useFinbricksFetch as A, BASE_TERMINAL_STATUSES as B, CsobConnector as C, DbuConnector as D, ErsteConnector as E, FINBRICKS_ENDPOINTS as F, tables as G, relations as H, IBankConnector as I, initiateConnector as J, KBConnector as K, getNonTerminalPaymentRequestsQuery as L, MockCobsConnector as M, calculateCzechIban as N, FinbricksClient as a, FinbricksConnector as b, MockConnector as c, accountCredentialsInsertSchema as d, accountCredentialsSelectSchema as e, accountCredentialsUpdateSchema as f, accountInsertSchema as g, accountSelectSchema as h, accountUpdateSchema as i, assignAccount as j, dbuAccountConfigSchema as k, hasPaymentAccountAssigned as l, isPaymentCompleted as m, isPendingStatus as n, isProcessedStatus as o, isTerminalStatus as p, ottInsertSchema as q, ottSelectSchema as r, ottUpdateSchema as s, signFinbricksJws as t, toBatchedPayment as u, toBatchedPaymentFromPaymentRequest as v, toCompletedPayment as w, toIncomingPayment as x, toPaymentRequestInsert as y, toPreparedPayment as z };
2480
+ export { useFinbricksFetch as A, BASE_TERMINAL_STATUSES as B, CsobConnector as C, DbuConnector as D, ErsteConnector as E, FINBRICKS_ENDPOINTS as F, tables as G, relations as H, IBankConnector as I, buildEndToEndId as J, KBConnector as K, getNonTerminalPaymentRequestsQuery as L, MockCobsConnector as M, calculateCzechIban as N, FinbricksClient as a, FinbricksConnector as b, MockConnector as c, accountCredentialsInsertSchema as d, accountCredentialsSelectSchema as e, accountCredentialsUpdateSchema as f, accountInsertSchema as g, accountSelectSchema as h, accountUpdateSchema as i, assignAccount as j, dbuAccountConfigSchema as k, hasPaymentAccountAssigned as l, isPaymentCompleted as m, isPendingStatus as n, isProcessedStatus as o, isTerminalStatus as p, ottInsertSchema as q, ottSelectSchema as r, ottUpdateSchema as s, signFinbricksJws as t, toBatchedPayment as u, toBatchedPaymentFromPaymentRequest as v, toCompletedPayment as w, toIncomingPayment as x, toPaymentRequestInsert as y, toPreparedPayment as z };
@@ -2,11 +2,11 @@
2
2
 
3
3
  const backendSdk = require('@develit-io/backend-sdk');
4
4
  const dateFns = require('date-fns');
5
+ const database_schema = require('./bank.9Yw4KHyl.cjs');
6
+ const drizzleOrm = require('drizzle-orm');
5
7
  const jose = require('jose');
6
8
  const zod = require('zod');
7
9
  const generalCodes = require('@develit-io/general-codes');
8
- const database_schema = require('./bank.9Yw4KHyl.cjs');
9
- const drizzleOrm = require('drizzle-orm');
10
10
  const zod$1 = require('drizzle-orm/zod');
11
11
  require('node:crypto');
12
12
 
@@ -752,6 +752,49 @@ const mapFinbricksTransactionToPayment = (tx, account) => {
752
752
  return base;
753
753
  };
754
754
 
755
+ function mod97(string) {
756
+ let checksum = string.slice(0, 2);
757
+ let fragment = "";
758
+ for (let offset = 2; offset < string.length; offset += 7) {
759
+ fragment = checksum + string.substring(offset, offset + 7);
760
+ checksum = (parseInt(fragment, 10) % 97).toString();
761
+ }
762
+ return parseInt(checksum, 10);
763
+ }
764
+ const parseCzechIban = (iban) => {
765
+ const stripped = iban.replace(/\s/g, "").toUpperCase();
766
+ if (!stripped.startsWith("CZ") || stripped.length !== 24) {
767
+ throw new Error(`Invalid Czech IBAN: ${iban}`);
768
+ }
769
+ const bankCode = stripped.slice(4, 8);
770
+ const prefix = stripped.slice(8, 14).replace(/^0+/, "");
771
+ const main = stripped.slice(14, 24).replace(/^0+/, "");
772
+ const accountNumber = prefix ? `${prefix}-${main}` : main;
773
+ return { bankCode, accountNumber };
774
+ };
775
+ const calculateCzechIban = (accountNumber, bankCode) => {
776
+ const paddedBankCode = bankCode.padStart(4, "0");
777
+ let prefix = "";
778
+ let mainAccount = accountNumber;
779
+ if (accountNumber.includes("-")) {
780
+ const parts = accountNumber.split("-");
781
+ if (parts.length !== 2) {
782
+ throw new Error(
783
+ `Invalid account number format: expected "prefix-main" or "main", got "${accountNumber}"`
784
+ );
785
+ }
786
+ prefix = parts[0];
787
+ mainAccount = parts[1];
788
+ }
789
+ const paddedPrefix = prefix.padStart(6, "0");
790
+ const paddedAccount = mainAccount.padStart(10, "0");
791
+ const basicIban = paddedBankCode + paddedPrefix + paddedAccount;
792
+ const rearranged = basicIban + "123500";
793
+ const remainder = mod97(rearranged);
794
+ const checkDigits = (98 - remainder).toString().padStart(2, "0");
795
+ return `CZ${checkDigits}${basicIban}`;
796
+ };
797
+
755
798
  function autoVariableSymbol(paymentId) {
756
799
  let hash = 0;
757
800
  for (let i = 0; i < paymentId.length; i++) {
@@ -1063,7 +1106,7 @@ class FinbricksConnector extends IBankConnector {
1063
1106
  payment.currency
1064
1107
  );
1065
1108
  const creditorBic = payment.creditor.swiftBic ?? payment.creditor.bicCor;
1066
- const creditorAgent = creditorIdentification.type === "BBAN" && creditorBic ? {
1109
+ const creditorAgent = creditorBic ? {
1067
1110
  financialInstitutionIdentification: { bic: creditorBic }
1068
1111
  } : void 0;
1069
1112
  const reference = buildPaymentReference({
@@ -1199,6 +1242,10 @@ class FinbricksConnector extends IBankConnector {
1199
1242
  };
1200
1243
  }
1201
1244
  async initiateDomesticPayment(payment) {
1245
+ const debtorAccount = this.connectedAccounts.find(
1246
+ (acc) => acc.iban === payment.debtor.iban
1247
+ );
1248
+ const clientId = await this.getClientId(debtorAccount.id);
1202
1249
  const [response, error] = await backendSdk.useResult(
1203
1250
  this.finbricks.request({
1204
1251
  endpoint: FINBRICKS_ENDPOINTS.TRANSACTION_INIT,
@@ -1217,6 +1264,7 @@ class FinbricksConnector extends IBankConnector {
1217
1264
  specificSymbol: payment.ss,
1218
1265
  constantSymbol: payment.ks,
1219
1266
  callbackUrl: `${this.finbricks.REDIRECT_URI}?type=paymentRequest&paymentRequestId=${payment.id}`,
1267
+ clientId,
1220
1268
  paymentProvider: this.PROVIDER,
1221
1269
  instructionPriority: payment.instructionPriority ?? "NORM"
1222
1270
  }
@@ -2423,74 +2471,6 @@ const ottInsertSchema = zod$1.createInsertSchema(database_schema.ott);
2423
2471
  const ottUpdateSchema = zod$1.createUpdateSchema(database_schema.ott);
2424
2472
  const ottSelectSchema = zod$1.createSelectSchema(database_schema.ott);
2425
2473
 
2426
- class AirBankConnector extends FinbricksConnector {
2427
- constructor(config) {
2428
- super("AIRBANK", config);
2429
- }
2430
- supportsBatch() {
2431
- return false;
2432
- }
2433
- }
2434
-
2435
- class CreditasConnector extends FinbricksConnector {
2436
- constructor(config) {
2437
- super("CREDITAS", config);
2438
- }
2439
- /**
2440
- * Creditas bank doesn't support batch payments at all.
2441
- */
2442
- supportsBatch() {
2443
- return false;
2444
- }
2445
- }
2446
-
2447
- class CSASConnector extends FinbricksConnector {
2448
- constructor(config) {
2449
- super("CSAS", config);
2450
- }
2451
- supportsBatch(paymentType) {
2452
- return paymentType === "DOMESTIC";
2453
- }
2454
- }
2455
-
2456
- class FioConnector extends FinbricksConnector {
2457
- constructor(config) {
2458
- super("FIO", config);
2459
- }
2460
- /**
2461
- * FIO supports batch only for DOMESTIC (CZK) payments.
2462
- * SEPA and SWIFT batch support is planned by Finbricks.
2463
- */
2464
- supportsBatch(paymentType) {
2465
- return paymentType === "DOMESTIC";
2466
- }
2467
- }
2468
-
2469
- class MonetaConnector extends FinbricksConnector {
2470
- constructor(config) {
2471
- super("MONETA", config);
2472
- }
2473
- /**
2474
- * MONETA supports batch only for DOMESTIC (CZK) payments.
2475
- * SEPA and SWIFT batch support is planned by Finbricks.
2476
- */
2477
- supportsBatch(paymentType) {
2478
- return paymentType === "DOMESTIC";
2479
- }
2480
- /**
2481
- * MONETA rejects all special characters in endToEndIdentification.
2482
- * Boundaries between segments are unambiguous without a separator —
2483
- * `VS`/`SS`/`KS` prefixes are alphabetic and values are always numeric,
2484
- * so the parsing regex `VS[:\s]*(\d+)` extracts each value correctly.
2485
- *
2486
- * Format: `VS1234SS5678KS0308` (max 30 chars).
2487
- * Confirmed by Finbricks support (2026-04-23).
2488
- */
2489
- buildEndToEndId(payment) {
2490
- return buildEndToEndId(payment, { separator: "" });
2491
- }
2492
- }
2493
-
2494
2474
  const isDeposit = (payment, creditorIban) => {
2495
2475
  return payment.creditor.iban === creditorIban;
2496
2476
  };
@@ -2499,179 +2479,6 @@ const getPaymentDirection = (payment, iban) => {
2499
2479
  return "OUTGOING";
2500
2480
  };
2501
2481
 
2502
- const initiateConnector = async ({
2503
- bank,
2504
- env,
2505
- connectedAccounts,
2506
- resolveCredentials
2507
- }) => {
2508
- switch (bank) {
2509
- case "ERSTE":
2510
- return new ErsteConnector({
2511
- API_KEY: (await env.SECRETS_STORE.get({
2512
- secretName: "BANK_SERVICE_ERSTE_API_KEY"
2513
- })).data?.secretValue || "",
2514
- CLIENT_ID: (await env.SECRETS_STORE.get({
2515
- secretName: "BANK_SERVICE_ERSTE_CLIENT_ID"
2516
- })).data?.secretValue || "",
2517
- CLIENT_SECRET: (await env.SECRETS_STORE.get({
2518
- secretName: "BANK_SERVICE_ERSTE_CLIENT_SECRET"
2519
- })).data?.secretValue || "",
2520
- REDIRECT_URI: env.REDIRECT_URI,
2521
- AUTH_URI: env.ERSTE_AUTH_URI,
2522
- PAYMENTS_URI: env.ERSTE_PAYMENTS_URI,
2523
- ACCOUNTS_URI: env.ERSTE_ACCOUNTS_URI,
2524
- connectedAccounts,
2525
- resolveCredentials
2526
- });
2527
- case "CREDITAS":
2528
- return new CreditasConnector({
2529
- BASE_URI: env.FINBRICKS_BASE_URI,
2530
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2531
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2532
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2533
- })).data?.secretValue || "",
2534
- REDIRECT_URI: env.REDIRECT_URI,
2535
- connectedAccounts,
2536
- resolveCredentials
2537
- });
2538
- case "MOCK_COBS":
2539
- return new MockCobsConnector({
2540
- BASE_URI: env.FINBRICKS_BASE_URI,
2541
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2542
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2543
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2544
- })).data?.secretValue || "",
2545
- REDIRECT_URI: env.REDIRECT_URI,
2546
- connectedAccounts,
2547
- resolveCredentials
2548
- });
2549
- case "FIO":
2550
- return new FioConnector({
2551
- BASE_URI: env.FINBRICKS_BASE_URI,
2552
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2553
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2554
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2555
- })).data?.secretValue || "",
2556
- REDIRECT_URI: env.REDIRECT_URI,
2557
- connectedAccounts,
2558
- resolveCredentials
2559
- });
2560
- case "MONETA":
2561
- return new MonetaConnector({
2562
- BASE_URI: env.FINBRICKS_BASE_URI,
2563
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2564
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2565
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2566
- })).data?.secretValue || "",
2567
- REDIRECT_URI: env.REDIRECT_URI,
2568
- connectedAccounts,
2569
- resolveCredentials
2570
- });
2571
- case "AIRBANK":
2572
- return new AirBankConnector({
2573
- BASE_URI: env.FINBRICKS_BASE_URI,
2574
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2575
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2576
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2577
- })).data?.secretValue || "",
2578
- REDIRECT_URI: env.REDIRECT_URI,
2579
- connectedAccounts,
2580
- resolveCredentials
2581
- });
2582
- case "CSAS":
2583
- return new CSASConnector({
2584
- BASE_URI: env.FINBRICKS_BASE_URI,
2585
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2586
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2587
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2588
- })).data?.secretValue || "",
2589
- REDIRECT_URI: env.REDIRECT_URI,
2590
- connectedAccounts,
2591
- resolveCredentials
2592
- });
2593
- case "KB":
2594
- return new KBConnector({
2595
- BASE_URI: env.FINBRICKS_BASE_URI,
2596
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2597
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2598
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2599
- })).data?.secretValue || "",
2600
- REDIRECT_URI: env.REDIRECT_URI,
2601
- connectedAccounts,
2602
- resolveCredentials
2603
- });
2604
- case "CSOB":
2605
- return new CsobConnector({
2606
- BASE_URI: env.FINBRICKS_BASE_URI,
2607
- MERCHANT_ID: env.FINBRICKS_MERCHANT_ID,
2608
- PRIVATE_KEY_PEM: (await env.SECRETS_STORE.get({
2609
- secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
2610
- })).data?.secretValue || "",
2611
- REDIRECT_URI: env.REDIRECT_URI,
2612
- connectedAccounts,
2613
- resolveCredentials
2614
- });
2615
- case "DBU":
2616
- return new DbuConnector({
2617
- BASE_URL: env.DBUCS_BASE_URI,
2618
- USERNAME: env.DBUCS_USERNAME,
2619
- APPLICATION_CODE: env.DBUCS_APPLICATION_CODE,
2620
- KV: env.BANK_KV,
2621
- API: env.DBU_CBS_BACKOFFICE_DEV,
2622
- REDIRECT_URI: env.REDIRECT_URI,
2623
- TX_AUTH_URI: env.DBUCS_TX_AUTH_URI,
2624
- connectedAccounts
2625
- });
2626
- default:
2627
- const mockConnector = new MockConnector();
2628
- mockConnector.connectedAccounts = connectedAccounts;
2629
- return mockConnector;
2630
- }
2631
- };
2632
- function mod97(string) {
2633
- let checksum = string.slice(0, 2);
2634
- let fragment = "";
2635
- for (let offset = 2; offset < string.length; offset += 7) {
2636
- fragment = checksum + string.substring(offset, offset + 7);
2637
- checksum = (parseInt(fragment, 10) % 97).toString();
2638
- }
2639
- return parseInt(checksum, 10);
2640
- }
2641
- const parseCzechIban = (iban) => {
2642
- const stripped = iban.replace(/\s/g, "").toUpperCase();
2643
- if (!stripped.startsWith("CZ") || stripped.length !== 24) {
2644
- throw new Error(`Invalid Czech IBAN: ${iban}`);
2645
- }
2646
- const bankCode = stripped.slice(4, 8);
2647
- const prefix = stripped.slice(8, 14).replace(/^0+/, "");
2648
- const main = stripped.slice(14, 24).replace(/^0+/, "");
2649
- const accountNumber = prefix ? `${prefix}-${main}` : main;
2650
- return { bankCode, accountNumber };
2651
- };
2652
- const calculateCzechIban = (accountNumber, bankCode) => {
2653
- const paddedBankCode = bankCode.padStart(4, "0");
2654
- let prefix = "";
2655
- let mainAccount = accountNumber;
2656
- if (accountNumber.includes("-")) {
2657
- const parts = accountNumber.split("-");
2658
- if (parts.length !== 2) {
2659
- throw new Error(
2660
- `Invalid account number format: expected "prefix-main" or "main", got "${accountNumber}"`
2661
- );
2662
- }
2663
- prefix = parts[0];
2664
- mainAccount = parts[1];
2665
- }
2666
- const paddedPrefix = prefix.padStart(6, "0");
2667
- const paddedAccount = mainAccount.padStart(10, "0");
2668
- const basicIban = paddedBankCode + paddedPrefix + paddedAccount;
2669
- const rearranged = basicIban + "123500";
2670
- const remainder = mod97(rearranged);
2671
- const checkDigits = (98 - remainder).toString().padStart(2, "0");
2672
- return `CZ${checkDigits}${basicIban}`;
2673
- };
2674
-
2675
2482
  exports.BASE_TERMINAL_STATUSES = BASE_TERMINAL_STATUSES;
2676
2483
  exports.CsobConnector = CsobConnector;
2677
2484
  exports.DbuConnector = DbuConnector;
@@ -2690,11 +2497,11 @@ exports.accountInsertSchema = accountInsertSchema;
2690
2497
  exports.accountSelectSchema = accountSelectSchema;
2691
2498
  exports.accountUpdateSchema = accountUpdateSchema;
2692
2499
  exports.assignAccount = assignAccount;
2500
+ exports.buildEndToEndId = buildEndToEndId;
2693
2501
  exports.calculateCzechIban = calculateCzechIban;
2694
2502
  exports.dbuAccountConfigSchema = dbuAccountConfigSchema;
2695
2503
  exports.getNonTerminalPaymentRequestsQuery = getNonTerminalPaymentRequestsQuery;
2696
2504
  exports.hasPaymentAccountAssigned = hasPaymentAccountAssigned;
2697
- exports.initiateConnector = initiateConnector;
2698
2505
  exports.isPaymentCompleted = isPaymentCompleted;
2699
2506
  exports.isPendingStatus = isPendingStatus;
2700
2507
  exports.isProcessedStatus = isProcessedStatus;