@develit-services/bank 0.8.6 → 0.8.7

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.
Files changed (32) hide show
  1. package/dist/database/schema.cjs +1 -1
  2. package/dist/database/schema.d.cts +1 -1
  3. package/dist/database/schema.d.mts +1 -1
  4. package/dist/database/schema.d.ts +1 -1
  5. package/dist/database/schema.mjs +1 -1
  6. package/dist/export/worker.cjs +583 -146
  7. package/dist/export/worker.d.cts +251 -39
  8. package/dist/export/worker.d.mts +251 -39
  9. package/dist/export/worker.d.ts +251 -39
  10. package/dist/export/worker.mjs +584 -147
  11. package/dist/export/workflows.cjs +132 -16
  12. package/dist/export/workflows.mjs +133 -17
  13. package/dist/shared/{bank.C-T1FQxg.cjs → bank.62VzK9Aj.cjs} +1 -1
  14. package/dist/shared/{bank.SQ4Mmr8u.cjs → bank.BS7fFjGA.cjs} +34 -4
  15. package/dist/shared/{bank.B6U8sUZn.d.mts → bank.BYRq3yJf.d.ts} +17 -7
  16. package/dist/shared/{bank.C4VOdIx1.mjs → bank.C0UN6luZ.mjs} +34 -4
  17. package/dist/shared/{bank.DDHrdFgy.mjs → bank.CA5ytXxp.mjs} +1 -1
  18. package/dist/shared/{bank.BoMDujsl.d.ts → bank.CO89tR9U.d.cts} +17 -7
  19. package/dist/shared/{bank.BliD3oCT.d.ts → bank.Cns5ss41.d.cts} +47 -10
  20. package/dist/shared/{bank.BliD3oCT.d.cts → bank.Cns5ss41.d.mts} +47 -10
  21. package/dist/shared/{bank.BliD3oCT.d.mts → bank.Cns5ss41.d.ts} +47 -10
  22. package/dist/shared/{bank.lbzMqyr3.d.cts → bank.CreoSb2d.d.mts} +17 -7
  23. package/dist/shared/{bank.DRrBrAdI.mjs → bank.D1jqaHaF.mjs} +91 -31
  24. package/dist/shared/{bank.Cpy9PULF.mjs → bank.DEmzZGZW.mjs} +31 -5
  25. package/dist/shared/{bank.BOnP9p9Y.cjs → bank.Dm8GHThw.cjs} +31 -5
  26. package/dist/shared/{bank.CQURey1E.cjs → bank.DwyCCyd0.cjs} +90 -31
  27. package/dist/types.cjs +3 -4
  28. package/dist/types.d.cts +8 -16
  29. package/dist/types.d.mts +8 -16
  30. package/dist/types.d.ts +8 -16
  31. package/dist/types.mjs +3 -3
  32. package/package.json +2 -2
@@ -1,27 +1,27 @@
1
1
  import { uuidv4, first, buildMultiFilterConditions as buildMultiFilterConditions$1, bankAccountMetadataSchema, workflowInstanceStatusSchema, develitWorker, createInternalError, action, service } from '@develit-io/backend-sdk';
2
- import { t as tables, h as encrypt, d as createCredentialsResolver, u as upsertBatchCommand, a as getPaymentRequestsByBatchIdQuery, e as updatePaymentRequestStatusCommand, g as getBatchByIdQuery, i as importAesKey, f as createPaymentCommand, b as getAccountByIdQuery } from '../shared/bank.Cpy9PULF.mjs';
2
+ import { t as tables, h as encrypt, d as createCredentialsResolver, u as upsertBatchCommand, a as getPaymentRequestsByBatchIdQuery, e as updatePaymentRequestStatusCommand, g as getBatchByIdQuery, i as importAesKey, f as createPaymentCommand, b as getAccountByIdQuery } from '../shared/bank.DEmzZGZW.mjs';
3
3
  import { WorkerEntrypoint } from 'cloudflare:workers';
4
4
  import { drizzle } from 'drizzle-orm/d1';
5
- import { k as initiateConnector, m as mapFinbricksTransactionStatus, h as toIncomingPayment, d as assignAccount, i as toPaymentRequestInsert, t as toBatchedPayment, a as FinbricksClient, F as FINBRICKS_ENDPOINTS } from '../shared/bank.DRrBrAdI.mjs';
5
+ import { j as initiateConnector, m as mapFinbricksTransactionStatus, g as toIncomingPayment, d as assignAccount, t as toBatchedPayment, a as FinbricksClient, F as FINBRICKS_ENDPOINTS, h as toPaymentRequestInsert } from '../shared/bank.D1jqaHaF.mjs';
6
6
  import 'jose';
7
7
  import { z } from 'zod';
8
- import { I as INSTRUCTION_PRIORITIES, C as CHARGE_BEARERS, e as PAYMENT_TYPES, a as CONNECTOR_KEYS, B as BATCH_STATUSES, d as PAYMENT_STATUSES, P as PAYMENT_DIRECTIONS, i as accountInsertSchema } from '../shared/bank.C4VOdIx1.mjs';
8
+ import { I as INSTRUCTION_PRIORITIES, C as CHARGE_BEARERS, e as PAYMENT_TYPES, a as CONNECTOR_KEYS, B as BATCH_STATUSES, d as PAYMENT_STATUSES, P as PAYMENT_DIRECTIONS, i as accountInsertSchema } from '../shared/bank.C0UN6luZ.mjs';
9
9
  import { CURRENCY_CODES } from '@develit-io/general-codes';
10
10
  import 'date-fns';
11
- import { eq, sql, and, inArray, asc, desc, gte, lte } from 'drizzle-orm';
11
+ import { eq, sql, and, inArray, like, asc, desc, gte, lte, isNull, or, isNotNull } from 'drizzle-orm';
12
+ import { unionAll } from 'drizzle-orm/sqlite-core';
12
13
  import 'node:crypto';
13
- import '../shared/bank.DDHrdFgy.mjs';
14
+ import '../shared/bank.CA5ytXxp.mjs';
14
15
  import 'drizzle-orm/relations';
15
- import 'drizzle-orm/sqlite-core';
16
16
  import 'drizzle-zod';
17
17
 
18
18
  const upsertAccountCommand = (db, { account }) => {
19
19
  const id = account.id || uuidv4();
20
+ const { id: _id, ...accountWithoutId } = account;
20
21
  const command = db.insert(tables.account).values({ ...account, id }).onConflictDoUpdate({
21
22
  target: tables.account.iban,
22
- set: {
23
- ...account
24
- }
23
+ set: accountWithoutId
24
+ // preserve existing id on re-auth
25
25
  }).returning();
26
26
  return {
27
27
  id,
@@ -139,16 +139,25 @@ const getAllAccountsQuery = async (db, filters) => {
139
139
  filters?.filterBankRefIds
140
140
  )
141
141
  );
142
- const accountsWithExpiration = await db.select().from(tables.account).leftJoin(
143
- tables.accountCredentials,
144
- eq(tables.accountCredentials.accountId, tables.account.id)
145
- ).where(whereConditions);
146
- return accountsWithExpiration.map(({ account, account_credentials }) => {
147
- return {
148
- ...account,
149
- expiresAt: account_credentials?.expiresAt
150
- };
151
- });
142
+ const page = filters?.page ?? 1;
143
+ const limit = filters?.limit ?? 20;
144
+ const offset = (page - 1) * limit;
145
+ const [accountsWithExpiration, countResult] = await Promise.all([
146
+ db.select().from(tables.account).leftJoin(
147
+ tables.accountCredentials,
148
+ eq(tables.accountCredentials.accountId, tables.account.id)
149
+ ).where(whereConditions).limit(limit).offset(offset),
150
+ db.select({ count: sql`count(*)` }).from(tables.account).where(whereConditions)
151
+ ]);
152
+ return {
153
+ accounts: accountsWithExpiration.map(
154
+ ({ account, account_credentials }) => ({
155
+ ...account,
156
+ expiresAt: account_credentials?.expiresAt
157
+ })
158
+ ),
159
+ totalCount: countResult[0]?.count ?? 0
160
+ };
152
161
  };
153
162
 
154
163
  const getAllPendingBatchesQuery = (db) => {
@@ -189,7 +198,17 @@ const getPaymentsWithPaginationQuery = async (db, {
189
198
  filterPaymentDateFrom,
190
199
  filterPaymentDateTo,
191
200
  filterPaymentStatus,
192
- filterPaymentyDirection
201
+ filterPaymentDirection,
202
+ filterPaymentType,
203
+ filterPaymentMinAmount,
204
+ filterPaymentMaxAmount,
205
+ filterPaymentVariableSymbol,
206
+ filterPaymentSpecificSymbol,
207
+ filterPaymentConstantSymbol,
208
+ filterPaymentMessage,
209
+ filterPaymentCreditorIban,
210
+ filterPaymentDebtorIban,
211
+ filterPaymentBatchId
193
212
  }) => {
194
213
  const whereConditions = and(
195
214
  buildMultiFilterConditions(
@@ -206,9 +225,22 @@ const getPaymentsWithPaginationQuery = async (db, {
206
225
  buildMultiFilterConditions(tables.payment.status, filterPaymentStatus),
207
226
  buildMultiFilterConditions(
208
227
  tables.payment.direction,
209
- filterPaymentyDirection
228
+ filterPaymentDirection
229
+ ),
230
+ buildMultiFilterConditions(tables.payment.id, ids),
231
+ buildMultiFilterConditions(tables.payment.paymentType, filterPaymentType),
232
+ buildRangeFilterConditions(
233
+ tables.payment.amount,
234
+ filterPaymentMinAmount,
235
+ filterPaymentMaxAmount
210
236
  ),
211
- buildMultiFilterConditions(tables.payment.id, ids)
237
+ filterPaymentVariableSymbol !== void 0 ? eq(tables.payment.vs, filterPaymentVariableSymbol) : void 0,
238
+ filterPaymentSpecificSymbol !== void 0 ? eq(tables.payment.ss, filterPaymentSpecificSymbol) : void 0,
239
+ filterPaymentConstantSymbol !== void 0 ? eq(tables.payment.ks, filterPaymentConstantSymbol) : void 0,
240
+ filterPaymentMessage !== void 0 ? like(tables.payment.message, `%${filterPaymentMessage}%`) : void 0,
241
+ filterPaymentCreditorIban !== void 0 ? eq(tables.payment.creditorIban, filterPaymentCreditorIban) : void 0,
242
+ filterPaymentDebtorIban !== void 0 ? eq(tables.payment.debtorIban, filterPaymentDebtorIban) : void 0,
243
+ filterPaymentBatchId !== void 0 ? eq(tables.payment.batchId, filterPaymentBatchId) : void 0
212
244
  );
213
245
  const sortColumn = resolveColumn(tables.payment, sort.column);
214
246
  const [{ totalCount }] = await db.select({
@@ -268,28 +300,261 @@ const getOttQuery = async (db, { ott }) => {
268
300
  };
269
301
 
270
302
  const getPaymentRequestByIdQuery = async (db, { paymentId }) => {
271
- const results = await db.select().from(tables.paymentRequest).where(eq(tables.paymentRequest.id, paymentId)).limit(1);
272
- return results[0] ?? null;
303
+ const prResults = await db.select().from(tables.paymentRequest).where(
304
+ and(
305
+ eq(tables.paymentRequest.id, paymentId),
306
+ isNull(tables.paymentRequest.deletedAt)
307
+ )
308
+ ).limit(1);
309
+ if (prResults[0]) return prResults[0];
310
+ const paymentResults = await db.select().from(tables.payment).where(
311
+ or(
312
+ eq(tables.payment.paymentRequestId, paymentId),
313
+ and(
314
+ isNull(tables.payment.paymentRequestId),
315
+ eq(tables.payment.id, paymentId)
316
+ )
317
+ )
318
+ ).limit(1);
319
+ if (!paymentResults[0]) return null;
320
+ const p = paymentResults[0];
321
+ return {
322
+ ...p,
323
+ id: p.paymentRequestId ?? p.id,
324
+ authorizationUrl: null,
325
+ sendAsSinglePayment: null,
326
+ direction: p.direction ?? "OUTGOING"
327
+ };
273
328
  };
274
329
 
275
- const seperateSupportedPayments = (incomingPayments, accounts) => {
276
- const [supportedPayments, unsupportedPayments] = incomingPayments.reduce(
277
- ([valid, invalid], payment) => {
278
- const isValid = accounts.some(
279
- (acc) => acc.iban === payment.debtorIban && acc.currency === payment.currency
280
- );
281
- if (isValid) {
282
- valid.push(payment);
283
- } else {
284
- invalid.push(payment);
285
- }
286
- return [valid, invalid];
287
- },
288
- [[], []]
330
+ function isCompletedOnly(filterStatus) {
331
+ if (!filterStatus) return false;
332
+ const statuses = Array.isArray(filterStatus) ? filterStatus : [filterStatus];
333
+ return statuses.length > 0 && statuses.every((s) => s === "COMPLETED");
334
+ }
335
+ function mapPaymentToPaymentRequest(p) {
336
+ return {
337
+ id: p.id,
338
+ createdAt: p.createdAt,
339
+ createdBy: p.createdBy,
340
+ updatedAt: p.updatedAt,
341
+ updatedBy: p.updatedBy,
342
+ deletedAt: p.deletedAt,
343
+ deletedBy: p.deletedBy,
344
+ batchId: p.batchId,
345
+ accountId: p.accountId,
346
+ correlationId: p.correlationId,
347
+ refId: p.refId,
348
+ bankRefId: p.bankRefId,
349
+ connectorKey: p.connectorKey,
350
+ amount: p.amount,
351
+ paymentType: p.paymentType,
352
+ currency: p.currency,
353
+ status: p.status,
354
+ statusReason: p.statusReason,
355
+ initiatedAt: p.initiatedAt,
356
+ processedAt: p.processedAt,
357
+ vs: p.vs,
358
+ ss: p.ss,
359
+ ks: p.ks,
360
+ message: p.message,
361
+ chargeBearer: p.chargeBearer,
362
+ instructionPriority: p.instructionPriority,
363
+ creditor: p.creditor,
364
+ creditorIban: p.creditorIban,
365
+ debtor: p.debtor,
366
+ debtorIban: p.debtorIban,
367
+ authorizationUrl: null,
368
+ sendAsSinglePayment: null
369
+ };
370
+ }
371
+ const getUnionColumns = () => ({
372
+ id: tables.paymentRequest.id,
373
+ createdAt: tables.paymentRequest.createdAt,
374
+ createdBy: tables.paymentRequest.createdBy,
375
+ updatedAt: tables.paymentRequest.updatedAt,
376
+ updatedBy: tables.paymentRequest.updatedBy,
377
+ deletedAt: tables.paymentRequest.deletedAt,
378
+ deletedBy: tables.paymentRequest.deletedBy,
379
+ batchId: tables.paymentRequest.batchId,
380
+ accountId: tables.paymentRequest.accountId,
381
+ correlationId: tables.paymentRequest.correlationId,
382
+ refId: tables.paymentRequest.refId,
383
+ bankRefId: tables.paymentRequest.bankRefId,
384
+ connectorKey: tables.paymentRequest.connectorKey,
385
+ amount: tables.paymentRequest.amount,
386
+ paymentType: tables.paymentRequest.paymentType,
387
+ currency: tables.paymentRequest.currency,
388
+ status: tables.paymentRequest.status,
389
+ statusReason: tables.paymentRequest.statusReason,
390
+ authorizationUrl: tables.paymentRequest.authorizationUrl,
391
+ initiatedAt: tables.paymentRequest.initiatedAt,
392
+ processedAt: tables.paymentRequest.processedAt,
393
+ vs: tables.paymentRequest.vs,
394
+ ss: tables.paymentRequest.ss,
395
+ ks: tables.paymentRequest.ks,
396
+ message: tables.paymentRequest.message,
397
+ chargeBearer: tables.paymentRequest.chargeBearer,
398
+ instructionPriority: tables.paymentRequest.instructionPriority,
399
+ creditor: tables.paymentRequest.creditor,
400
+ creditorIban: tables.paymentRequest.creditorIban,
401
+ debtor: tables.paymentRequest.debtor,
402
+ debtorIban: tables.paymentRequest.debtorIban,
403
+ sendAsSinglePayment: tables.paymentRequest.sendAsSinglePayment,
404
+ // payment_request je vždy OUTGOING — typ musí být kompatibilní s payment.direction
405
+ direction: sql`'OUTGOING'`.as("direction")
406
+ });
407
+ const getPaymentUnionColumns = () => ({
408
+ id: sql`COALESCE(${tables.payment.paymentRequestId}, ${tables.payment.id})`.as(
409
+ "id"
410
+ ),
411
+ createdAt: tables.payment.createdAt,
412
+ createdBy: tables.payment.createdBy,
413
+ updatedAt: tables.payment.updatedAt,
414
+ updatedBy: tables.payment.updatedBy,
415
+ deletedAt: tables.payment.deletedAt,
416
+ deletedBy: tables.payment.deletedBy,
417
+ batchId: tables.payment.batchId,
418
+ accountId: tables.payment.accountId,
419
+ correlationId: tables.payment.correlationId,
420
+ refId: tables.payment.refId,
421
+ bankRefId: tables.payment.bankRefId,
422
+ connectorKey: tables.payment.connectorKey,
423
+ amount: tables.payment.amount,
424
+ paymentType: tables.payment.paymentType,
425
+ currency: tables.payment.currency,
426
+ status: tables.payment.status,
427
+ statusReason: tables.payment.statusReason,
428
+ authorizationUrl: sql`NULL`.as("authorization_url"),
429
+ initiatedAt: tables.payment.initiatedAt,
430
+ processedAt: tables.payment.processedAt,
431
+ vs: tables.payment.vs,
432
+ ss: tables.payment.ss,
433
+ ks: tables.payment.ks,
434
+ message: tables.payment.message,
435
+ chargeBearer: tables.payment.chargeBearer,
436
+ instructionPriority: tables.payment.instructionPriority,
437
+ creditor: tables.payment.creditor,
438
+ creditorIban: tables.payment.creditorIban,
439
+ debtor: tables.payment.debtor,
440
+ debtorIban: tables.payment.debtorIban,
441
+ sendAsSinglePayment: sql`NULL`.as("send_as_single_payment"),
442
+ direction: tables.payment.direction
443
+ });
444
+ const getPaymentRequestsWithPaginationQuery = async (db, {
445
+ limit,
446
+ page,
447
+ sort,
448
+ filterAccountId,
449
+ filterStatus,
450
+ filterPaymentType,
451
+ filterCurrency,
452
+ filterMinAmount,
453
+ filterMaxAmount,
454
+ filterBatchId,
455
+ filterCreditorIban,
456
+ filterDebtorIban,
457
+ filterDateFrom,
458
+ filterDateTo,
459
+ filterVariableSymbol,
460
+ filterSpecificSymbol,
461
+ filterConstantSymbol,
462
+ filterMessage,
463
+ filterBankRefId,
464
+ filterPaymentId,
465
+ filterDirection,
466
+ filterSource
467
+ }) => {
468
+ const offset = (page - 1) * limit;
469
+ const buildPrWhereConditions = () => and(
470
+ isNull(tables.paymentRequest.deletedAt),
471
+ buildMultiFilterConditions(
472
+ tables.paymentRequest.accountId,
473
+ filterAccountId
474
+ ),
475
+ buildMultiFilterConditions(tables.paymentRequest.status, filterStatus),
476
+ buildMultiFilterConditions(
477
+ tables.paymentRequest.paymentType,
478
+ filterPaymentType
479
+ ),
480
+ buildMultiFilterConditions(
481
+ tables.paymentRequest.currency,
482
+ filterCurrency
483
+ ),
484
+ buildRangeFilterConditions(
485
+ tables.paymentRequest.amount,
486
+ filterMinAmount,
487
+ filterMaxAmount
488
+ ),
489
+ filterBatchId !== void 0 ? eq(tables.paymentRequest.batchId, filterBatchId) : void 0,
490
+ filterCreditorIban !== void 0 ? eq(tables.paymentRequest.creditorIban, filterCreditorIban) : void 0,
491
+ filterDebtorIban !== void 0 ? eq(tables.paymentRequest.debtorIban, filterDebtorIban) : void 0,
492
+ filterDateFrom !== void 0 ? gte(tables.paymentRequest.createdAt, filterDateFrom) : void 0,
493
+ filterDateTo !== void 0 ? lte(tables.paymentRequest.createdAt, filterDateTo) : void 0,
494
+ filterVariableSymbol !== void 0 ? eq(tables.paymentRequest.vs, filterVariableSymbol) : void 0,
495
+ filterSpecificSymbol !== void 0 ? eq(tables.paymentRequest.ss, filterSpecificSymbol) : void 0,
496
+ filterConstantSymbol !== void 0 ? eq(tables.paymentRequest.ks, filterConstantSymbol) : void 0,
497
+ filterMessage !== void 0 ? like(tables.paymentRequest.message, `%${filterMessage}%`) : void 0,
498
+ filterBankRefId !== void 0 ? eq(tables.paymentRequest.bankRefId, filterBankRefId) : void 0,
499
+ filterPaymentId !== void 0 ? eq(tables.paymentRequest.id, filterPaymentId) : void 0,
500
+ // payment_request is always OUTGOING — exclude branch entirely when filtering INCOMING
501
+ filterDirection === "INCOMING" ? sql`0` : void 0,
502
+ // payment_request is always API (has no bank-synced payments)
503
+ filterSource === "BANK" ? sql`0` : void 0
289
504
  );
505
+ const buildPaymentWhereConditions = () => and(
506
+ isNull(tables.payment.deletedAt),
507
+ buildMultiFilterConditions(tables.payment.accountId, filterAccountId),
508
+ buildMultiFilterConditions(tables.payment.status, filterStatus),
509
+ buildMultiFilterConditions(tables.payment.paymentType, filterPaymentType),
510
+ buildMultiFilterConditions(tables.payment.currency, filterCurrency),
511
+ buildRangeFilterConditions(
512
+ tables.payment.amount,
513
+ filterMinAmount,
514
+ filterMaxAmount
515
+ ),
516
+ filterBatchId !== void 0 ? eq(tables.payment.batchId, filterBatchId) : void 0,
517
+ filterCreditorIban !== void 0 ? eq(tables.payment.creditorIban, filterCreditorIban) : void 0,
518
+ filterDebtorIban !== void 0 ? eq(tables.payment.debtorIban, filterDebtorIban) : void 0,
519
+ filterDateFrom !== void 0 ? gte(tables.payment.createdAt, filterDateFrom) : void 0,
520
+ filterDateTo !== void 0 ? lte(tables.payment.createdAt, filterDateTo) : void 0,
521
+ filterVariableSymbol !== void 0 ? eq(tables.payment.vs, filterVariableSymbol) : void 0,
522
+ filterSpecificSymbol !== void 0 ? eq(tables.payment.ss, filterSpecificSymbol) : void 0,
523
+ filterConstantSymbol !== void 0 ? eq(tables.payment.ks, filterConstantSymbol) : void 0,
524
+ filterMessage !== void 0 ? like(tables.payment.message, `%${filterMessage}%`) : void 0,
525
+ filterBankRefId !== void 0 ? eq(tables.payment.bankRefId, filterBankRefId) : void 0,
526
+ filterPaymentId !== void 0 ? sql`COALESCE(${tables.payment.paymentRequestId}, ${tables.payment.id}) = ${filterPaymentId}` : void 0,
527
+ filterDirection !== void 0 ? eq(tables.payment.direction, filterDirection) : void 0,
528
+ filterSource === "BANK" ? isNull(tables.payment.paymentRequestId) : filterSource === "API" ? isNotNull(tables.payment.paymentRequestId) : void 0
529
+ );
530
+ const queryInFlight = !isCompletedOnly(filterStatus);
531
+ const queryCompleted = true;
532
+ if (!queryInFlight && queryCompleted) {
533
+ const whereConditions = buildPaymentWhereConditions();
534
+ const sortColumn = resolveColumn(tables.payment, sort.column);
535
+ const [{ totalCount }] = await db.select({ totalCount: sql`count(*)` }).from(tables.payment).where(whereConditions);
536
+ const payments = await db.select().from(tables.payment).where(whereConditions).limit(limit).offset(offset).orderBy(sort.direction === "asc" ? asc(sortColumn) : desc(sortColumn));
537
+ return {
538
+ paymentRequests: payments.map(mapPaymentToPaymentRequest),
539
+ totalCount
540
+ };
541
+ }
542
+ const prWhereConditions = buildPrWhereConditions();
543
+ const paymentWhereConditions = buildPaymentWhereConditions();
544
+ const unionColumns = getUnionColumns();
545
+ const paymentUnionColumns = getPaymentUnionColumns();
546
+ const sortColObj = sort.column in unionColumns ? unionColumns[sort.column] : unionColumns.updatedAt;
547
+ const [{ totalCount: countPR }, { totalCount: countP }] = await Promise.all([
548
+ db.select({ totalCount: sql`count(*)` }).from(tables.paymentRequest).where(prWhereConditions).then(([row]) => row),
549
+ db.select({ totalCount: sql`count(*)` }).from(tables.payment).where(paymentWhereConditions).then(([row]) => row)
550
+ ]);
551
+ const paymentRequests = await unionAll(
552
+ db.select(unionColumns).from(tables.paymentRequest).where(prWhereConditions),
553
+ db.select(paymentUnionColumns).from(tables.payment).where(paymentWhereConditions)
554
+ ).orderBy(sort.direction === "asc" ? asc(sortColObj) : desc(sortColObj)).limit(limit).offset(offset);
290
555
  return {
291
- supportedPayments,
292
- unsupportedPayments
556
+ paymentRequests,
557
+ totalCount: countPR + countP
293
558
  };
294
559
  };
295
560
 
@@ -299,7 +564,6 @@ const sendPaymentInputSchema = z.object({
299
564
  amount: z.number().positive(),
300
565
  paymentType: z.enum(PAYMENT_TYPES),
301
566
  chargeBearer: z.enum(CHARGE_BEARERS).optional(),
302
- executionDate: z.string().optional(),
303
567
  instructionPriority: z.enum(INSTRUCTION_PRIORITIES).optional(),
304
568
  currency: z.enum(CURRENCY_CODES),
305
569
  vs: z.string().optional(),
@@ -308,7 +572,6 @@ const sendPaymentInputSchema = z.object({
308
572
  message: z.string().optional(),
309
573
  creditor: bankAccountMetadataSchema,
310
574
  debtor: bankAccountMetadataSchema,
311
- purpose: z.string().optional(),
312
575
  sendAsSinglePayment: z.boolean().optional()
313
576
  });
314
577
 
@@ -388,10 +651,20 @@ const ALLOWED_PAYMENT_FILTERS = {
388
651
  ACCOUNT_ID: "filterPaymentAccountId",
389
652
  AMOUNT: "filterPaymentAmount",
390
653
  CURRENCY: "filterPaymentCurrency",
391
- DIRECTION: "filterPaymentyDirection",
654
+ DIRECTION: "filterPaymentDirection",
392
655
  FROM: "filterPaymentDateFrom",
393
656
  TO: "filterPaymentDateTo",
394
- STATUS: "filterPaymentStatus"
657
+ STATUS: "filterPaymentStatus",
658
+ PAYMENT_TYPE: "filterPaymentType",
659
+ MIN_AMOUNT: "filterPaymentMinAmount",
660
+ MAX_AMOUNT: "filterPaymentMaxAmount",
661
+ VARIABLE_SYMBOL: "filterPaymentVariableSymbol",
662
+ SPECIFIC_SYMBOL: "filterPaymentSpecificSymbol",
663
+ CONSTANT_SYMBOL: "filterPaymentConstantSymbol",
664
+ MESSAGE: "filterPaymentMessage",
665
+ CREDITOR_IBAN: "filterPaymentCreditorIban",
666
+ DEBTOR_IBAN: "filterPaymentDebtorIban",
667
+ BATCH_ID: "filterPaymentBatchId"
395
668
  };
396
669
  const getPaymentsInputSchema = z.object({
397
670
  page: z.number().positive(),
@@ -407,7 +680,17 @@ const getPaymentsInputSchema = z.object({
407
680
  [ALLOWED_PAYMENT_FILTERS.DIRECTION]: z.union([z.enum(PAYMENT_DIRECTIONS), z.enum(PAYMENT_DIRECTIONS).array()]).optional(),
408
681
  [ALLOWED_PAYMENT_FILTERS.FROM]: z.date().optional(),
409
682
  [ALLOWED_PAYMENT_FILTERS.TO]: z.date().optional(),
410
- [ALLOWED_PAYMENT_FILTERS.STATUS]: z.union([z.enum(PAYMENT_STATUSES), z.enum(PAYMENT_STATUSES).array()]).optional()
683
+ [ALLOWED_PAYMENT_FILTERS.STATUS]: z.union([z.enum(PAYMENT_STATUSES), z.enum(PAYMENT_STATUSES).array()]).optional(),
684
+ [ALLOWED_PAYMENT_FILTERS.PAYMENT_TYPE]: z.enum(PAYMENT_TYPES).optional(),
685
+ [ALLOWED_PAYMENT_FILTERS.MIN_AMOUNT]: z.number().positive().optional(),
686
+ [ALLOWED_PAYMENT_FILTERS.MAX_AMOUNT]: z.number().positive().optional(),
687
+ [ALLOWED_PAYMENT_FILTERS.VARIABLE_SYMBOL]: z.string().regex(/^\d{1,10}$/).optional(),
688
+ [ALLOWED_PAYMENT_FILTERS.SPECIFIC_SYMBOL]: z.string().regex(/^\d{1,10}$/).optional(),
689
+ [ALLOWED_PAYMENT_FILTERS.CONSTANT_SYMBOL]: z.string().regex(/^\d{4}$/).optional(),
690
+ [ALLOWED_PAYMENT_FILTERS.MESSAGE]: z.string().optional(),
691
+ [ALLOWED_PAYMENT_FILTERS.CREDITOR_IBAN]: z.string().optional(),
692
+ [ALLOWED_PAYMENT_FILTERS.DEBTOR_IBAN]: z.string().optional(),
693
+ [ALLOWED_PAYMENT_FILTERS.BATCH_ID]: z.uuid().optional()
411
694
  });
412
695
 
413
696
  const syncAccountInputSchema = z.object({
@@ -446,6 +729,8 @@ const updateAccountInputSchema = z.object({
446
729
  });
447
730
 
448
731
  const getBankAccountsInputSchema = z.object({
732
+ page: z.number().positive().optional(),
733
+ limit: z.number().positive().optional(),
449
734
  includeWorkflow: z.boolean().optional(),
450
735
  includeBatchCounts: z.boolean().optional(),
451
736
  filterIbans: z.array(z.string()).optional(),
@@ -466,6 +751,34 @@ const handleAuthorizationCallbackInputSchema = z.object({
466
751
 
467
752
  const sendPaymentSyncInputSchema = sendPaymentInputSchema;
468
753
 
754
+ const getPaymentRequestsInputSchema = z.object({
755
+ page: z.number().positive(),
756
+ limit: z.number().positive(),
757
+ sort: z.object({
758
+ column: z.enum(["createdAt", "updatedAt", "amount"]),
759
+ direction: z.enum(["asc", "desc"])
760
+ }),
761
+ filterAccountId: z.union([z.uuid(), z.uuid().array()]).optional(),
762
+ filterStatus: z.union([z.enum(PAYMENT_STATUSES), z.enum(PAYMENT_STATUSES).array()]).optional(),
763
+ filterPaymentType: z.union([z.enum(PAYMENT_TYPES), z.enum(PAYMENT_TYPES).array()]).optional(),
764
+ filterCurrency: z.union([z.enum(CURRENCY_CODES), z.enum(CURRENCY_CODES).array()]).optional(),
765
+ filterMinAmount: z.number().positive().optional(),
766
+ filterMaxAmount: z.number().positive().optional(),
767
+ filterBatchId: z.uuid().optional(),
768
+ filterCreditorIban: z.string().optional(),
769
+ filterDebtorIban: z.string().optional(),
770
+ filterDateFrom: z.date().optional(),
771
+ filterDateTo: z.date().optional(),
772
+ filterVariableSymbol: z.string().optional(),
773
+ filterSpecificSymbol: z.string().optional(),
774
+ filterConstantSymbol: z.string().optional(),
775
+ filterMessage: z.string().optional(),
776
+ filterBankRefId: z.string().optional(),
777
+ filterPaymentId: z.uuid().optional(),
778
+ filterDirection: z.enum(["INCOMING", "OUTGOING"]).optional(),
779
+ filterSource: z.enum(["API", "BANK"]).optional()
780
+ });
781
+
469
782
  var __defProp = Object.defineProperty;
470
783
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
471
784
  var __decorateClass = (decorators, target, key, kind) => {
@@ -487,7 +800,9 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
487
800
  return await getAllAccountsQuery(this.db, filters);
488
801
  }
489
802
  async _getConnectedAccounts() {
490
- const accounts = await this._getAccounts();
803
+ const { accounts } = await this._getAccounts({
804
+ limit: Number.MAX_SAFE_INTEGER
805
+ });
491
806
  return accounts.filter((acc) => acc.status !== "DISABLED");
492
807
  }
493
808
  async _initiateBankConnector({
@@ -521,6 +836,27 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
521
836
  env: this.env
522
837
  });
523
838
  }
839
+ _validatePaymentTypeAndCurrency(paymentType, currency, creditor) {
840
+ const PAYMENT_TYPE_CURRENCY_MAP = {
841
+ DOMESTIC: ["CZK"],
842
+ SEPA: ["EUR"]
843
+ };
844
+ const allowedCurrencies = PAYMENT_TYPE_CURRENCY_MAP[paymentType];
845
+ if (allowedCurrencies && !allowedCurrencies.includes(currency)) {
846
+ throw createInternalError(null, {
847
+ message: `Payment type ${paymentType} requires currency ${allowedCurrencies.join(" or ")}, got ${currency}`,
848
+ code: "VALID-B-008",
849
+ status: 422
850
+ });
851
+ }
852
+ if (paymentType === "SEPA" && !creditor.iban) {
853
+ throw createInternalError(null, {
854
+ message: "SEPA payments require creditor IBAN",
855
+ code: "VALID-B-009",
856
+ status: 422
857
+ });
858
+ }
859
+ }
524
860
  async getPayments(input) {
525
861
  return this.handleAction(
526
862
  { data: input, schema: getPaymentsInputSchema },
@@ -804,50 +1140,49 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
804
1140
  }
805
1141
  );
806
1142
  }
807
- async addPaymentsToBatch({
808
- paymentsToBatch
809
- }) {
1143
+ async addPaymentsToBatch({ paymentIds }) {
810
1144
  return this.handleAction(null, {}, async () => {
811
- this.logInput({ paymentsToBatch });
812
- const incomingPayments = paymentsToBatch.map(toIncomingPayment);
813
- const accounts = await this._getAccounts();
814
- const { supportedPayments, unsupportedPayments } = seperateSupportedPayments(incomingPayments, accounts);
815
- if (unsupportedPayments.length > 0) {
816
- this.logError({ unsupportedPayments });
817
- await this.pushToQueue(
818
- this.env.QUEUE_BUS_QUEUE,
819
- unsupportedPayments.map((unsupported) => ({
820
- eventType: "BANK_PAYMENT",
821
- eventSignal: "paymentFailed",
822
- bankPayment: {
823
- ...unsupported,
824
- status: "FAILED",
825
- statusReason: "UNSUPPORTED_ACCOUNT"
826
- },
827
- metadata: {
828
- correlationId: unsupported.correlationId,
829
- entityId: unsupported.id,
830
- timestamp: (/* @__PURE__ */ new Date()).toDateString()
831
- }
832
- }))
833
- );
1145
+ this.logInput({ paymentIds });
1146
+ const paymentRequests = (await Promise.all(
1147
+ paymentIds.map(
1148
+ (id) => getPaymentRequestByIdQuery(this.db, { paymentId: id })
1149
+ )
1150
+ )).filter((p) => p !== null);
1151
+ const foundIds = new Set(paymentRequests.map((p) => p.id));
1152
+ const missingIds = paymentIds.filter((id) => !foundIds.has(id));
1153
+ if (missingIds.length > 0) {
1154
+ this.logError({ missingIds });
834
1155
  }
835
- for (const acc of accounts) {
836
- const accountAssignedPayments = supportedPayments.filter(
837
- (payment) => payment.debtorIban === acc.iban && payment.currency === acc.currency
838
- ).map((payment) => assignAccount(payment, acc));
839
- if (accountAssignedPayments.length === 0) {
1156
+ const byAccount = Map.groupBy(
1157
+ paymentRequests,
1158
+ (p) => `${p.accountId}:${p.paymentType}`
1159
+ );
1160
+ const { accounts } = await this._getAccounts();
1161
+ for (const [, paymentsOfType] of byAccount) {
1162
+ const first2 = paymentsOfType[0];
1163
+ const acc = accounts.find((a) => a.id === first2.accountId);
1164
+ if (!acc) {
1165
+ this.logError({ message: `Account not found: ${first2.accountId}` });
1166
+ await Promise.all(
1167
+ paymentsOfType.map(
1168
+ (p) => updatePaymentRequestStatusCommand(this.db, {
1169
+ id: p.id,
1170
+ status: "FAILED",
1171
+ statusReason: "ACCOUNT_NOT_FOUND"
1172
+ }).command.execute()
1173
+ )
1174
+ );
840
1175
  continue;
841
1176
  }
842
- this.log({
843
- message: `\u{1F4B0} Processing ${accountAssignedPayments.length} payments for account (${acc.iban}, ${acc.currency})`
844
- });
845
- const singlePayments = accountAssignedPayments.filter(
1177
+ const singlePayments = paymentsOfType.filter(
846
1178
  (p) => p.sendAsSinglePayment === true
847
1179
  );
848
- const regularPayments = accountAssignedPayments.filter(
1180
+ const regularPayments = paymentsOfType.filter(
849
1181
  (p) => p.sendAsSinglePayment !== true
850
1182
  );
1183
+ this.log({
1184
+ message: `\u{1F4B0} Processing ${paymentsOfType.length} payments for account (${acc.iban}, ${acc.currency})`
1185
+ });
851
1186
  for (const singlePayment of singlePayments) {
852
1187
  const batchId = uuidv4();
853
1188
  const { command: upsertBatch } = upsertBatchCommand(this.db, {
@@ -860,73 +1195,67 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
860
1195
  metadata: { sizeLimit: 1 }
861
1196
  }
862
1197
  });
863
- const { command: insertPaymentRequest } = createPaymentRequestCommand(
1198
+ const { command: updateRequest } = updatePaymentRequestStatusCommand(
864
1199
  this.db,
865
- {
866
- paymentRequest: toPaymentRequestInsert(singlePayment, batchId)
867
- }
1200
+ { id: singlePayment.id, status: "CREATED", batchId }
868
1201
  );
869
- await this.db.batch([upsertBatch, insertPaymentRequest]);
1202
+ await this.db.batch([upsertBatch, updateRequest]);
870
1203
  this.log({
871
1204
  message: `\u2728 Created single payment batch (${singlePayment.paymentType}) for account ${acc.id}`
872
1205
  });
873
1206
  }
874
1207
  if (regularPayments.length > 0) {
875
- const paymentsByType = Map.groupBy(
876
- regularPayments,
877
- (p) => p.paymentType
878
- );
879
- for (const [paymentType, paymentsOfType] of paymentsByType) {
880
- const openBatches = await getAccountOpenBatchesQuery(this.db, {
881
- accountId: acc.id,
882
- paymentType
883
- });
884
- let batchId;
885
- let availableCount = 0;
886
- let availableBatch;
887
- for (const ob of openBatches) {
888
- const existingPayments = await getPaymentRequestsByBatchIdQuery(
889
- this.db,
890
- { batchId: ob.id }
891
- );
892
- const limit = ob.metadata?.sizeLimit ?? acc.batchSizeLimit;
893
- if (existingPayments.length < limit) {
894
- availableBatch = ob;
895
- availableCount = existingPayments.length;
896
- break;
897
- }
898
- }
899
- if (availableBatch) {
900
- batchId = availableBatch.id;
901
- this.log({
902
- message: `\u{1F504} Found existing OPEN batch (${paymentType}) for account ${acc.id}, merging ${availableCount} existing + ${paymentsOfType.length} new payments`
903
- });
904
- } else {
905
- batchId = uuidv4();
906
- this.log({
907
- message: `\u2728 Creating new batch (${paymentType}) for account ${acc.id} with ${paymentsOfType.length} payments`
908
- });
1208
+ const openBatches = await getAccountOpenBatchesQuery(this.db, {
1209
+ accountId: acc.id,
1210
+ paymentType: first2.paymentType
1211
+ });
1212
+ let batchId;
1213
+ let availableCount = 0;
1214
+ let availableBatch;
1215
+ for (const ob of openBatches) {
1216
+ const existingPayments = await getPaymentRequestsByBatchIdQuery(
1217
+ this.db,
1218
+ { batchId: ob.id }
1219
+ );
1220
+ const limit = ob.metadata?.sizeLimit ?? acc.batchSizeLimit;
1221
+ if (existingPayments.length < limit) {
1222
+ availableBatch = ob;
1223
+ availableCount = existingPayments.length;
1224
+ break;
909
1225
  }
910
- const { command: upsertBatch } = upsertBatchCommand(this.db, {
911
- batch: availableBatch ? { ...availableBatch } : {
912
- id: batchId,
913
- authorizationUrls: [],
914
- accountId: acc.id,
915
- paymentType,
916
- status: "OPEN",
917
- metadata: { sizeLimit: acc.batchSizeLimit }
918
- }
1226
+ }
1227
+ if (availableBatch) {
1228
+ batchId = availableBatch.id;
1229
+ this.log({
1230
+ message: `\u{1F504} Found existing OPEN batch (${first2.paymentType}) for account ${acc.id}, merging ${availableCount} existing + ${regularPayments.length} new payments`
919
1231
  });
920
- const paymentRequestCommands = paymentsOfType.map(
921
- (p) => createPaymentRequestCommand(this.db, {
922
- paymentRequest: toPaymentRequestInsert(p, batchId)
923
- }).command
924
- );
925
- await this.db.batch([upsertBatch, ...paymentRequestCommands]);
1232
+ } else {
1233
+ batchId = uuidv4();
926
1234
  this.log({
927
- message: `\u2705 Batch (${paymentType}) upserted successfully for account ${acc.id}`
1235
+ message: `\u2728 Creating new batch (${first2.paymentType}) for account ${acc.id} with ${regularPayments.length} payments`
928
1236
  });
929
1237
  }
1238
+ const { command: upsertBatch } = upsertBatchCommand(this.db, {
1239
+ batch: availableBatch ? { ...availableBatch } : {
1240
+ id: batchId,
1241
+ authorizationUrls: [],
1242
+ accountId: acc.id,
1243
+ paymentType: first2.paymentType,
1244
+ status: "OPEN",
1245
+ metadata: { sizeLimit: acc.batchSizeLimit }
1246
+ }
1247
+ });
1248
+ const updateCommands = regularPayments.map(
1249
+ (p) => updatePaymentRequestStatusCommand(this.db, {
1250
+ id: p.id,
1251
+ status: "CREATED",
1252
+ batchId
1253
+ }).command
1254
+ );
1255
+ await this.db.batch([upsertBatch, ...updateCommands]);
1256
+ this.log({
1257
+ message: `\u2705 Batch (${first2.paymentType}) upserted successfully for account ${acc.id}`
1258
+ });
930
1259
  }
931
1260
  }
932
1261
  });
@@ -983,7 +1312,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
983
1312
  async () => {
984
1313
  this.logQueuePull(b);
985
1314
  const queueHandlerResponse = await this.addPaymentsToBatch({
986
- paymentsToBatch: b.messages.map(({ body }) => body)
1315
+ paymentIds: b.messages.map(({ body }) => body.paymentId)
987
1316
  });
988
1317
  this.logOutput(queueHandlerResponse);
989
1318
  }
@@ -1049,7 +1378,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1049
1378
  const { credentials, accounts } = await connector.authorizeAccount({
1050
1379
  urlParams
1051
1380
  });
1052
- const alreadyExistingAccounts = (await this._getAccounts()).filter(
1381
+ const alreadyExistingAccounts = (await this._getAccounts()).accounts.filter(
1053
1382
  (acc) => acc.connectorKey === ottRow.refId && accounts.map((item) => item.iban).includes(acc.iban)
1054
1383
  );
1055
1384
  const upsertAccounts = accounts.map((acc) => {
@@ -1097,7 +1426,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1097
1426
  ...upsertAccounts,
1098
1427
  ...createAccountCredentials
1099
1428
  ]);
1100
- const fetchedAccounts = await this._getAccounts();
1429
+ const { accounts: fetchedAccounts } = await this._getAccounts();
1101
1430
  if (!fetchedAccounts)
1102
1431
  throw createInternalError(null, {
1103
1432
  message: "Account not found",
@@ -1105,7 +1434,11 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1105
1434
  status: 404
1106
1435
  });
1107
1436
  if (startSync) {
1108
- for (const account of fetchedAccounts) {
1437
+ const newAccountIbans = new Set(accounts.map((a) => a.iban));
1438
+ const accountsToSync = fetchedAccounts.filter(
1439
+ (a) => newAccountIbans.has(a.iban)
1440
+ );
1441
+ for (const account of accountsToSync) {
1109
1442
  const { error } = await this.syncAccount({
1110
1443
  accountId: account.id
1111
1444
  });
@@ -1147,12 +1480,18 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1147
1480
  code: "VALID-B-003",
1148
1481
  status: 422
1149
1482
  });
1483
+ if (account.connectorKey !== connectorKey)
1484
+ throw createInternalError(null, {
1485
+ message: `Connector key mismatch: account uses ${account.connectorKey}, got ${connectorKey}`,
1486
+ code: "VALID-B-010",
1487
+ status: 422
1488
+ });
1150
1489
  const payment = {
1151
1490
  id: uuidv4(),
1152
1491
  bankRefId: uuidv4(),
1153
1492
  correlationId: uuidv4(),
1154
1493
  amount,
1155
- connectorKey,
1494
+ connectorKey: account.connectorKey,
1156
1495
  accountId: account.id,
1157
1496
  direction: "INCOMING",
1158
1497
  paymentType: "DOMESTIC",
@@ -1192,10 +1531,51 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1192
1531
  { data: input, schema: sendPaymentInputSchema },
1193
1532
  { successMessage: "Payment queued successfully" },
1194
1533
  async (data) => {
1534
+ const incomingPayment = toIncomingPayment(data);
1535
+ const { accounts } = await this._getAccounts();
1536
+ const account = accounts.find(
1537
+ (acc) => acc.iban === incomingPayment.debtorIban && acc.currency === incomingPayment.currency
1538
+ );
1539
+ if (!account) {
1540
+ throw createInternalError(null, {
1541
+ message: `No account found for IBAN ${incomingPayment.debtorIban} with currency ${incomingPayment.currency}`,
1542
+ code: "VALID-B-004",
1543
+ status: 422
1544
+ });
1545
+ }
1546
+ if (account.status !== "AUTHORIZED") {
1547
+ throw createInternalError(null, {
1548
+ message: `Account ${account.iban} is not authorized (status: ${account.status})`,
1549
+ code: "VALID-B-007",
1550
+ status: 422
1551
+ });
1552
+ }
1553
+ const connector = await this._initiateBankConnector({
1554
+ connectorKey: account.connectorKey
1555
+ });
1556
+ if (!connector.supportsPaymentType(data.paymentType)) {
1557
+ throw createInternalError(null, {
1558
+ message: `Connector ${account.connectorKey} does not support ${data.paymentType} payments yet`,
1559
+ code: "VALID-B-006",
1560
+ status: 422
1561
+ });
1562
+ }
1563
+ this._validatePaymentTypeAndCurrency(
1564
+ data.paymentType,
1565
+ data.currency,
1566
+ data.creditor
1567
+ );
1568
+ const accountAssigned = assignAccount(incomingPayment, account);
1569
+ const { command: insertPaymentRequest } = createPaymentRequestCommand(
1570
+ this.db,
1571
+ { paymentRequest: toPaymentRequestInsert(accountAssigned, null) }
1572
+ );
1573
+ await insertPaymentRequest.execute();
1195
1574
  await this.pushToQueue(
1196
1575
  this.env.PAYMENTS_READY_TO_BATCH_QUEUE,
1197
- data
1576
+ { paymentId: incomingPayment.id }
1198
1577
  );
1578
+ return { paymentId: incomingPayment.id };
1199
1579
  }
1200
1580
  );
1201
1581
  }
@@ -1205,7 +1585,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1205
1585
  { successMessage: "Payment initiated successfully" },
1206
1586
  async (data) => {
1207
1587
  const incomingPayment = toIncomingPayment(data);
1208
- const accounts = await this._getAccounts();
1588
+ const { accounts } = await this._getAccounts();
1209
1589
  const account = accounts.find(
1210
1590
  (acc) => acc.iban === incomingPayment.debtorIban && acc.currency === incomingPayment.currency
1211
1591
  );
@@ -1216,12 +1596,31 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1216
1596
  status: 422
1217
1597
  });
1218
1598
  }
1599
+ if (account.status !== "AUTHORIZED") {
1600
+ throw createInternalError(null, {
1601
+ message: `Account ${account.iban} is not authorized (status: ${account.status})`,
1602
+ code: "VALID-B-007",
1603
+ status: 422
1604
+ });
1605
+ }
1219
1606
  const batchedPayment = toBatchedPayment(
1220
1607
  assignAccount(incomingPayment, account)
1221
1608
  );
1222
1609
  const connector = await this._initiateBankConnector({
1223
1610
  connectorKey: account.connectorKey
1224
1611
  });
1612
+ if (!connector.supportsPaymentType(data.paymentType)) {
1613
+ throw createInternalError(null, {
1614
+ message: `Connector ${account.connectorKey} does not support ${data.paymentType} payments yet`,
1615
+ code: "VALID-B-006",
1616
+ status: 422
1617
+ });
1618
+ }
1619
+ this._validatePaymentTypeAndCurrency(
1620
+ data.paymentType,
1621
+ data.currency,
1622
+ data.creditor
1623
+ );
1225
1624
  const initiate = () => {
1226
1625
  switch (data.paymentType) {
1227
1626
  case "DOMESTIC":
@@ -1250,16 +1649,20 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1250
1649
  { data: input, schema: getBankAccountsInputSchema },
1251
1650
  { successMessage: "Bank accounts retrieved successfully" },
1252
1651
  async ({
1652
+ page,
1653
+ limit,
1253
1654
  includeWorkflow,
1254
1655
  includeBatchCounts,
1255
1656
  filterIbans,
1256
1657
  filterCurrencies,
1257
1658
  filterBankRefIds
1258
1659
  }) => {
1259
- const accounts = await this._getAccounts({
1660
+ const { accounts, totalCount } = await this._getAccounts({
1260
1661
  filterIbans,
1261
1662
  filterCurrencies,
1262
- filterBankRefIds
1663
+ filterBankRefIds,
1664
+ page,
1665
+ limit
1263
1666
  });
1264
1667
  const accountsWithOptionalFields = await Promise.all(
1265
1668
  accounts.map(async (a) => {
@@ -1293,7 +1696,7 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1293
1696
  );
1294
1697
  return {
1295
1698
  accounts: accountsWithOptionalFields,
1296
- totalCount: accounts.length
1699
+ totalCount
1297
1700
  };
1298
1701
  }
1299
1702
  );
@@ -1411,6 +1814,34 @@ let BankServiceBase = class extends develitWorker(WorkerEntrypoint) {
1411
1814
  }
1412
1815
  );
1413
1816
  }
1817
+ async getPaymentRequests(input) {
1818
+ return this.handleAction(
1819
+ { data: input, schema: getPaymentRequestsInputSchema },
1820
+ { successMessage: "Payment requests fetched successfully" },
1821
+ async (params) => {
1822
+ return await getPaymentRequestsWithPaginationQuery(this.db, params);
1823
+ }
1824
+ );
1825
+ }
1826
+ async getPaymentRequest(input) {
1827
+ return this.handleAction(
1828
+ null,
1829
+ { successMessage: "Payment request fetched successfully" },
1830
+ async () => {
1831
+ const paymentRequest = await getPaymentRequestByIdQuery(this.db, {
1832
+ paymentId: input.paymentId
1833
+ });
1834
+ if (!paymentRequest) {
1835
+ throw createInternalError(null, {
1836
+ message: `Payment request not found: ${input.paymentId}`,
1837
+ code: "NOT-FOUND-B-001",
1838
+ status: 404
1839
+ });
1840
+ }
1841
+ return { paymentRequest };
1842
+ }
1843
+ );
1844
+ }
1414
1845
  async getFinbricksSupportedBanks() {
1415
1846
  const privateKeyPem = (await this.env.SECRETS_STORE.get({
1416
1847
  secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
@@ -1484,6 +1915,12 @@ __decorateClass([
1484
1915
  __decorateClass([
1485
1916
  action("getBatches")
1486
1917
  ], BankServiceBase.prototype, "getBatches", 1);
1918
+ __decorateClass([
1919
+ action("get-payment-requests")
1920
+ ], BankServiceBase.prototype, "getPaymentRequests", 1);
1921
+ __decorateClass([
1922
+ action("get-payment-request")
1923
+ ], BankServiceBase.prototype, "getPaymentRequest", 1);
1487
1924
  BankServiceBase = __decorateClass([
1488
1925
  service("bank")
1489
1926
  ], BankServiceBase);