@develit-services/bank 0.8.1 → 0.8.3
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/README.md +82 -6
- package/dist/database/schema.cjs +9 -7
- 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 +1 -1
- package/dist/export/worker.cjs +211 -43
- package/dist/export/worker.d.cts +23 -8
- package/dist/export/worker.d.mts +23 -8
- package/dist/export/worker.d.ts +23 -8
- package/dist/export/worker.mjs +202 -34
- package/dist/export/workflows.cjs +71 -52
- package/dist/export/workflows.mjs +71 -52
- package/dist/export/wrangler.d.cts +1 -2
- package/dist/export/wrangler.d.mts +1 -2
- package/dist/export/wrangler.d.ts +1 -2
- package/dist/shared/{bank.C0p-hLzn.d.mts → bank.BE9bK1n7.d.mts} +213 -3
- package/dist/shared/{bank.Bs7mkXbR.cjs → bank.BOnP9p9Y.cjs} +15 -2
- package/dist/shared/bank.C-T1FQxg.cjs +17 -0
- package/dist/shared/{bank.993UA65l.mjs → bank.C4VOdIx1.mjs} +57 -5
- package/dist/shared/{bank.BC06Rbrx.d.cts → bank.CQBfbG8u.d.cts} +0 -1
- package/dist/shared/{bank.BC06Rbrx.d.mts → bank.CQBfbG8u.d.mts} +0 -1
- package/dist/shared/{bank.BC06Rbrx.d.ts → bank.CQBfbG8u.d.ts} +0 -1
- package/dist/shared/{bank.Ce-NBBw1.cjs → bank.CQURey1E.cjs} +64 -7
- package/dist/shared/{bank.CGIeLo8U.mjs → bank.Cpy9PULF.mjs} +14 -3
- package/dist/shared/bank.DDHrdFgy.mjs +15 -0
- package/dist/shared/{bank.BJ7LqYtJ.d.cts → bank.DDveEfub.d.cts} +707 -126
- package/dist/shared/{bank.BJ7LqYtJ.d.mts → bank.DDveEfub.d.mts} +707 -126
- package/dist/shared/{bank.BJ7LqYtJ.d.ts → bank.DDveEfub.d.ts} +707 -126
- package/dist/shared/{bank.CeRbuycV.mjs → bank.DRrBrAdI.mjs} +62 -8
- package/dist/shared/{bank.IVhZ_RlH.cjs → bank.SQ4Mmr8u.cjs} +57 -3
- package/dist/shared/{bank.C0p-hLzn.d.ts → bank.gl4dlxWy.d.cts} +213 -3
- package/dist/shared/{bank.C0p-hLzn.d.cts → bank.pngKIcOl.d.ts} +213 -3
- package/dist/types.cjs +25 -23
- package/dist/types.d.cts +29 -180
- package/dist/types.d.mts +29 -180
- package/dist/types.d.ts +29 -180
- package/dist/types.mjs +2 -2
- package/package.json +1 -1
- package/dist/shared/bank.Cp0yvOdq.cjs +0 -15
- package/dist/shared/bank.fIGTiPnp.mjs +0 -13
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ Sluzba se sklada z:
|
|
|
24
24
|
|
|
25
25
|
## Zivotni cyklus platby
|
|
26
26
|
|
|
27
|
-
Platba prochazi
|
|
27
|
+
Platba prochazi 6 fazemi s explicitnimi typy:
|
|
28
28
|
|
|
29
29
|
```
|
|
30
30
|
SendPaymentInput (API vstup)
|
|
@@ -55,10 +55,17 @@ SendPaymentInput (API vstup)
|
|
|
55
55
|
│ Odeslana do banky, ceka na autorizaci │
|
|
56
56
|
│ (muze jiz mit bankRefId) │
|
|
57
57
|
└──────────────────┬──────────────────────────┘
|
|
58
|
-
│
|
|
58
|
+
│ uzivatel autorizuje (callback)
|
|
59
59
|
▼
|
|
60
60
|
┌─────────────────────────────────────────────┐
|
|
61
|
-
│ 5.
|
|
61
|
+
│ 5. SignedPayment status: SIGNED │
|
|
62
|
+
│ Autorizovana uzivatelem, banka │
|
|
63
|
+
│ zpracovava │
|
|
64
|
+
└──────────────────┬──────────────────────────┘
|
|
65
|
+
│ banka dokonci zpracovani
|
|
66
|
+
▼
|
|
67
|
+
┌─────────────────────────────────────────────┐
|
|
68
|
+
│ 6. CompletedPayment status: COMPLETED│
|
|
62
69
|
│ Zpracovana bankou, ma bankRefId │
|
|
63
70
|
│ a processedAt timestamp │
|
|
64
71
|
│ (pripadne FAILED / PENDING) │
|
|
@@ -71,6 +78,7 @@ SendPaymentInput (API vstup)
|
|
|
71
78
|
|--------|-------|
|
|
72
79
|
| `CREATED` | Platba vytvorena, ceka na zpracovani |
|
|
73
80
|
| `PREPARED` | Odeslana do banky, ceka na autorizaci |
|
|
81
|
+
| `SIGNED` | Autorizovana uzivatelem, banka zpracovava |
|
|
74
82
|
| `PENDING` | Banka zpracovava |
|
|
75
83
|
| `COMPLETED` | Uspesne dokoncena |
|
|
76
84
|
| `FAILED` | Selhala |
|
|
@@ -146,11 +154,14 @@ Kazdy batch obsahuje pouze platby **jednoho typu** (SEPA, DOMESTIC nebo SWIFT).
|
|
|
146
154
|
Workflow (Cloudflare Durable Object) ridi zpracovani batche:
|
|
147
155
|
|
|
148
156
|
1. Nacte a validuje batch (nesmi byt SIGNED/PROCESSING)
|
|
157
|
+
1b. Nacte payment requesty pro batch z `payment_request` tabulky
|
|
149
158
|
2. Zamkne batch (nastavi PROCESSING, overi checksum)
|
|
150
159
|
3. Iniciuje batch u banky pres konektor podle typu platby (`connector.initiateDomesticBatch()` / `initiateSEPABatch()` / `initiateForeignBatch()`)
|
|
160
|
+
3b. Aktualizuje singlePayments na PREPARED (bankRefId, initiatedAt, authorizationUrl)
|
|
151
161
|
4. Aktualizuje batch na READY_TO_SIGN s autorizacnimi URL
|
|
162
|
+
4a. MOCK konektor: preskoci autorizaci, rovnou oznaci singlePayments jako COMPLETED a batch jako SIGNED
|
|
152
163
|
5. Odesle email s odkazem na autorizaci
|
|
153
|
-
6. Ceka na autorizaci uzivatelem
|
|
164
|
+
6. (TBD) Ceka na autorizaci uzivatelem (waitForEvent)
|
|
154
165
|
|
|
155
166
|
### CRON kontrola stavu
|
|
156
167
|
|
|
@@ -241,6 +252,64 @@ Vsechny konektory dedi z abstraktni tridy `IBankConnector`, ktera poskytuje spol
|
|
|
241
252
|
| Mock | `MOCK` | Vsechny typy | Testovaci, automaticky dokoncuje platby |
|
|
242
253
|
| Mock COBS | `MOCK_COBS` | Vsechny typy | Testovaci COBS konektor |
|
|
243
254
|
|
|
255
|
+
### Podporovane sluzby dle bank (Finbricks, CZ)
|
|
256
|
+
|
|
257
|
+
> Data ze sandbox prostredi Finbricks (`/status/bankInfo`). Aktualizovano: 2026-02-23.
|
|
258
|
+
|
|
259
|
+
#### Platby
|
|
260
|
+
|
|
261
|
+
| Banka | Provider | Domestic | SEPA | Foreign | Batch | Recurring | Pairing | Settled |
|
|
262
|
+
|-------|----------|:--------:|:----:|:-------:|:-----:|:---------:|:-------:|:-------:|
|
|
263
|
+
| MONETA Money Bank | `MONETA` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
|
264
|
+
| Mock Cobs banka | `MOCK_COBS` | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
|
265
|
+
| Air Bank | `AIRBANK` | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
|
266
|
+
| J&T Banka | `JTB` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
267
|
+
| mBank | `MBANK` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
268
|
+
| Raiffeisen | `RAIFFEISEN` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
269
|
+
| Fio banka | `FIO` | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ |
|
|
270
|
+
| CSOB | `CSOB` | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ | ❌ |
|
|
271
|
+
| Komercni banka | `KB` | ✅ | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ |
|
|
272
|
+
| UniCredit | `UNICREDIT` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
273
|
+
| Ceska sporitelna | `CSAS` | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ❌ |
|
|
274
|
+
| Partners Banka | `PARTNERS` | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
|
|
275
|
+
| Banka CREDITAS | `CREDITAS` | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
|
276
|
+
|
|
277
|
+
#### Ucty (informace)
|
|
278
|
+
|
|
279
|
+
| Banka | Provider | Info | Zustatek | Transakce |
|
|
280
|
+
|-------|----------|:----:|:--------:|:---------:|
|
|
281
|
+
| MONETA Money Bank | `MONETA` | ✅ | ✅ | ✅ |
|
|
282
|
+
| Mock Cobs banka | `MOCK_COBS` | ✅ | ✅ | ✅ |
|
|
283
|
+
| Air Bank | `AIRBANK` | ✅ | ✅ | ✅ |
|
|
284
|
+
| J&T Banka | `JTB` | ✅ | ✅ | ✅ |
|
|
285
|
+
| mBank | `MBANK` | ✅ | ✅ | ✅ |
|
|
286
|
+
| Raiffeisen | `RAIFFEISEN` | ✅ | ✅ | ✅ |
|
|
287
|
+
| Fio banka | `FIO` | ✅ | ✅ | ✅ |
|
|
288
|
+
| CSOB | `CSOB` | ✅ | ✅ | ✅ |
|
|
289
|
+
| Komercni banka | `KB` | ✅ | ✅ | ✅ |
|
|
290
|
+
| UniCredit | `UNICREDIT` | ✅ | ✅ | ✅ |
|
|
291
|
+
| Ceska sporitelna | `CSAS` | ✅ | ✅ | ✅ |
|
|
292
|
+
| Partners Banka | `PARTNERS` | ✅ | ✅ | ✅ |
|
|
293
|
+
| Banka CREDITAS | `CREDITAS` | ✅ | ✅ | ✅ |
|
|
294
|
+
|
|
295
|
+
#### Instant platby
|
|
296
|
+
|
|
297
|
+
| Banka | Provider | Domestic Creditor | Domestic Debtor | SEPA Creditor | SEPA Debtor |
|
|
298
|
+
|-------|----------|:-----------------:|:---------------:|:-------------:|:-----------:|
|
|
299
|
+
| MONETA Money Bank | `MONETA` | ✅ | ✅ | ❌ | ❌ |
|
|
300
|
+
| Mock Cobs banka | `MOCK_COBS` | ✅ | ✅ | ✅ | ❌ |
|
|
301
|
+
| Air Bank | `AIRBANK` | ✅ | ✅ | ✅ | ✅ |
|
|
302
|
+
| J&T Banka | `JTB` | ✅ | ✅ | ✅ | ✅ |
|
|
303
|
+
| mBank | `MBANK` | ✅ | ✅ | ❌ | ❌ |
|
|
304
|
+
| Raiffeisen | `RAIFFEISEN` | ✅ | ✅ | ❌ | ❌ |
|
|
305
|
+
| Fio banka | `FIO` | ✅ | ✅ | ❌ | ✅ |
|
|
306
|
+
| CSOB | `CSOB` | ✅ | ✅ | ❌ | ❌ |
|
|
307
|
+
| Komercni banka | `KB` | ✅ | ✅ | ❌ | ❌ |
|
|
308
|
+
| UniCredit | `UNICREDIT` | ✅ | ✅ | ❌ | ❌ |
|
|
309
|
+
| Ceska sporitelna | `CSAS` | ✅ | ✅ | ❌ | ❌ |
|
|
310
|
+
| Partners Banka | `PARTNERS` | ✅ | ✅ | ❌ | ❌ |
|
|
311
|
+
| Banka CREDITAS | `CREDITAS` | ✅ | ✅ | ❌ | ❌ |
|
|
312
|
+
|
|
244
313
|
### Metody konektoru
|
|
245
314
|
|
|
246
315
|
Kazdy konektor implementuje nasledujici metody (nebo vraci `Not implemented`):
|
|
@@ -319,6 +388,7 @@ Bank service je **RPC worker** - nema vlastni verejne HTTP endpointy. Vsechny ak
|
|
|
319
388
|
| `send-payment` | Odesle platbu (vlozi do fronty pro batchovani) |
|
|
320
389
|
| `send-payment-sync` | Odesle platbu synchronne primo do banky, vrati `authorizationUrl` (bez queue/batch/DB) |
|
|
321
390
|
| `get-payments` | Seznam plateb s paginaci a filtry (ucet, castka, mena, smer, datum, stav) |
|
|
391
|
+
| `handle-authorization-callback` | Zpracuje callback po autorizaci platby/batche (aktualizuje singlePayment + batch status) |
|
|
322
392
|
| `simulate-deposit` | Testovaci: vytvori prichozi platbu ve stavu COMPLETED |
|
|
323
393
|
|
|
324
394
|
### Batch operace
|
|
@@ -374,11 +444,17 @@ Klicove sloupce: `correlationId`, `refId`, `bankRefId`, `amount`, `currency`, `d
|
|
|
374
444
|
|
|
375
445
|
Unikatni omezeni: `(connectorKey, bankRefId)`.
|
|
376
446
|
|
|
447
|
+
### payment_request
|
|
448
|
+
|
|
449
|
+
Odchozi platby v prubehu zpracovani (in-flight). Kazda platba v batchi ma vlastni radek se stavem.
|
|
450
|
+
|
|
451
|
+
Klicove sloupce: `batchId`, `status`, `bankRefId`, `amount`, `currency`, `paymentType`, `creditorIban`, `debtorIban`, `accountId`, `connectorKey`, `authorizationUrl`, `initiatedAt`, `processedAt`, `statusReason`.
|
|
452
|
+
|
|
377
453
|
### batch
|
|
378
454
|
|
|
379
|
-
Batch plateb
|
|
455
|
+
Batch plateb se stavovymi informacemi. Platby jsou v tabulce `payment_request` (vazba pres `batchId`).
|
|
380
456
|
|
|
381
|
-
Klicove sloupce: `status`, `
|
|
457
|
+
Klicove sloupce: `status`, `authorizationUrls`, `paymentsChecksum`, `metadata`, `sizeLimit`, `accountId`, `paymentType`.
|
|
382
458
|
|
|
383
459
|
### account
|
|
384
460
|
|
package/dist/database/schema.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const paymentRequest_schema = require('../shared/bank.SQ4Mmr8u.cjs');
|
|
4
4
|
require('@develit-io/backend-sdk');
|
|
5
5
|
require('drizzle-orm/relations');
|
|
6
6
|
require('drizzle-orm/sqlite-core');
|
|
@@ -13,9 +13,11 @@ require('drizzle-zod');
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
exports.account =
|
|
17
|
-
exports.accountCredentials =
|
|
18
|
-
exports.batch =
|
|
19
|
-
exports.ott =
|
|
20
|
-
exports.payment =
|
|
21
|
-
exports.paymentRelations =
|
|
16
|
+
exports.account = paymentRequest_schema.account;
|
|
17
|
+
exports.accountCredentials = paymentRequest_schema.accountCredentials;
|
|
18
|
+
exports.batch = paymentRequest_schema.batch;
|
|
19
|
+
exports.ott = paymentRequest_schema.ott;
|
|
20
|
+
exports.payment = paymentRequest_schema.payment;
|
|
21
|
+
exports.paymentRelations = paymentRequest_schema.paymentRelations;
|
|
22
|
+
exports.paymentRequest = paymentRequest_schema.paymentRequest;
|
|
23
|
+
exports.paymentRequestRelations = paymentRequest_schema.paymentRequestRelations;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { as as account, at as accountCredentials, au as batch, av as ott, aw as payment, ax as paymentRelations, ay as paymentRequest, az as paymentRequestRelations } from '../shared/bank.DDveEfub.cjs';
|
|
2
2
|
import 'drizzle-orm/sqlite-core';
|
|
3
3
|
import 'drizzle-orm';
|
|
4
4
|
import '@develit-io/backend-sdk';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { as as account, at as accountCredentials, au as batch, av as ott, aw as payment, ax as paymentRelations, ay as paymentRequest, az as paymentRequestRelations } from '../shared/bank.DDveEfub.mjs';
|
|
2
2
|
import 'drizzle-orm/sqlite-core';
|
|
3
3
|
import 'drizzle-orm';
|
|
4
4
|
import '@develit-io/backend-sdk';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { as as account, at as accountCredentials, au as batch, av as ott, aw as payment, ax as paymentRelations, ay as paymentRequest, az as paymentRequestRelations } from '../shared/bank.DDveEfub.js';
|
|
2
2
|
import 'drizzle-orm/sqlite-core';
|
|
3
3
|
import 'drizzle-orm';
|
|
4
4
|
import '@develit-io/backend-sdk';
|
package/dist/database/schema.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { n as account, p as accountCredentials, q as batch, r as ott, s as payment, t as paymentRelations } from '../shared/bank.
|
|
1
|
+
export { n as account, p as accountCredentials, q as batch, r as ott, s as payment, t as paymentRelations, u as paymentRequest, v as paymentRequestRelations } from '../shared/bank.C4VOdIx1.mjs';
|
|
2
2
|
import '@develit-io/backend-sdk';
|
|
3
3
|
import 'drizzle-orm/relations';
|
|
4
4
|
import 'drizzle-orm/sqlite-core';
|
package/dist/export/worker.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const backendSdk = require('@develit-io/backend-sdk');
|
|
4
|
-
const drizzle = require('../shared/bank.
|
|
4
|
+
const drizzle = require('../shared/bank.BOnP9p9Y.cjs');
|
|
5
5
|
const cloudflare_workers = require('cloudflare:workers');
|
|
6
6
|
const d1 = require('drizzle-orm/d1');
|
|
7
|
+
const mock_connector = require('../shared/bank.CQURey1E.cjs');
|
|
8
|
+
require('jose');
|
|
7
9
|
const zod = require('zod');
|
|
8
|
-
const
|
|
10
|
+
const paymentRequest_schema = require('../shared/bank.SQ4Mmr8u.cjs');
|
|
9
11
|
const generalCodes = require('@develit-io/general-codes');
|
|
10
12
|
require('date-fns');
|
|
11
|
-
require('jose');
|
|
12
13
|
const drizzleOrm = require('drizzle-orm');
|
|
13
14
|
require('node:crypto');
|
|
14
|
-
|
|
15
|
-
require('../shared/bank.Cp0yvOdq.cjs');
|
|
15
|
+
require('../shared/bank.C-T1FQxg.cjs');
|
|
16
16
|
require('drizzle-orm/relations');
|
|
17
17
|
require('drizzle-orm/sqlite-core');
|
|
18
18
|
require('drizzle-zod');
|
|
@@ -94,6 +94,16 @@ const deletePaymentsByAccountCommand = (db, { accountId }) => {
|
|
|
94
94
|
};
|
|
95
95
|
};
|
|
96
96
|
|
|
97
|
+
const createPaymentRequestCommand = (db, { paymentRequest }) => {
|
|
98
|
+
return {
|
|
99
|
+
command: db.insert(drizzle.tables.paymentRequest).values({
|
|
100
|
+
...paymentRequest,
|
|
101
|
+
creditorIban: paymentRequest.creditor.iban,
|
|
102
|
+
debtorIban: paymentRequest.debtor.iban
|
|
103
|
+
}).returning()
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
97
107
|
const getAccountBatchCountsQuery = async (db, { accountId }) => {
|
|
98
108
|
const result = await db.select({
|
|
99
109
|
totalCount: drizzleOrm.sql`COUNT(*)`.as("totalCount"),
|
|
@@ -144,7 +154,7 @@ const getAllAccountsQuery = async (db, filters) => {
|
|
|
144
154
|
};
|
|
145
155
|
|
|
146
156
|
const getAllPendingBatchesQuery = (db) => {
|
|
147
|
-
return db.select().from(drizzle.tables.batch).where(drizzleOrm.inArray(drizzle.tables.batch.status, ["READY_TO_SIGN"]));
|
|
157
|
+
return db.select().from(drizzle.tables.batch).where(drizzleOrm.inArray(drizzle.tables.batch.status, ["READY_TO_SIGN", "SIGNED"]));
|
|
148
158
|
};
|
|
149
159
|
|
|
150
160
|
const buildMultiFilterConditions = (column, value) => {
|
|
@@ -249,6 +259,11 @@ const getOttQuery = async (db, { ott }) => {
|
|
|
249
259
|
return await db.select().from(drizzle.tables.ott).where(drizzleOrm.eq(drizzle.tables.ott.oneTimeToken, ott)).get();
|
|
250
260
|
};
|
|
251
261
|
|
|
262
|
+
const getPaymentRequestByIdQuery = async (db, { paymentId }) => {
|
|
263
|
+
const results = await db.select().from(drizzle.tables.paymentRequest).where(drizzleOrm.eq(drizzle.tables.paymentRequest.id, paymentId)).limit(1);
|
|
264
|
+
return results[0] ?? null;
|
|
265
|
+
};
|
|
266
|
+
|
|
252
267
|
const seperateSupportedPayments = (incomingPayments, accounts) => {
|
|
253
268
|
const [supportedPayments, unsupportedPayments] = incomingPayments.reduce(
|
|
254
269
|
([valid, invalid], payment) => {
|
|
@@ -272,12 +287,12 @@ const seperateSupportedPayments = (incomingPayments, accounts) => {
|
|
|
272
287
|
|
|
273
288
|
const sendPaymentInputSchema = zod.z.object({
|
|
274
289
|
correlationId: zod.z.string().min(1),
|
|
275
|
-
refId: zod.z.string(),
|
|
290
|
+
refId: zod.z.string().optional(),
|
|
276
291
|
amount: zod.z.number().positive(),
|
|
277
|
-
paymentType: zod.z.enum(
|
|
278
|
-
chargeBearer: zod.z.enum(
|
|
292
|
+
paymentType: zod.z.enum(paymentRequest_schema.PAYMENT_TYPES),
|
|
293
|
+
chargeBearer: zod.z.enum(paymentRequest_schema.CHARGE_BEARERS).optional(),
|
|
279
294
|
executionDate: zod.z.string().optional(),
|
|
280
|
-
instructionPriority: zod.z.enum(
|
|
295
|
+
instructionPriority: zod.z.enum(paymentRequest_schema.INSTRUCTION_PRIORITIES).optional(),
|
|
281
296
|
currency: zod.z.enum(generalCodes.CURRENCY_CODES),
|
|
282
297
|
vs: zod.z.string().optional(),
|
|
283
298
|
ss: zod.z.string().optional(),
|
|
@@ -290,7 +305,7 @@ const sendPaymentInputSchema = zod.z.object({
|
|
|
290
305
|
});
|
|
291
306
|
|
|
292
307
|
const getAuthUriInputSchema = zod.z.object({
|
|
293
|
-
connectorKey: zod.z.enum(
|
|
308
|
+
connectorKey: zod.z.enum(paymentRequest_schema.CONNECTOR_KEYS)
|
|
294
309
|
});
|
|
295
310
|
|
|
296
311
|
const authorizeAccountInputSchema = zod.z.object({
|
|
@@ -311,7 +326,7 @@ const simulateDepositInputSchema = zod.z.object({
|
|
|
311
326
|
message: zod.z.string(),
|
|
312
327
|
creditor: backendSdk.bankAccountMetadataSchema,
|
|
313
328
|
debtor: backendSdk.bankAccountMetadataSchema,
|
|
314
|
-
connectorKey: zod.z.enum(
|
|
329
|
+
connectorKey: zod.z.enum(paymentRequest_schema.CONNECTOR_KEYS)
|
|
315
330
|
});
|
|
316
331
|
|
|
317
332
|
const ALLOWED_BATCH_FILTERS = {
|
|
@@ -326,7 +341,7 @@ const getBatchesInputSchema = zod.z.object({
|
|
|
326
341
|
direction: zod.z.enum(["asc", "desc"])
|
|
327
342
|
}),
|
|
328
343
|
[ALLOWED_BATCH_FILTERS.ACCOUNT_ID]: zod.z.union([zod.z.uuid(), zod.z.uuid().array()]).optional(),
|
|
329
|
-
[ALLOWED_BATCH_FILTERS.STATUS]: zod.z.union([zod.z.enum(
|
|
344
|
+
[ALLOWED_BATCH_FILTERS.STATUS]: zod.z.union([zod.z.enum(paymentRequest_schema.BATCH_STATUSES), zod.z.enum(paymentRequest_schema.BATCH_STATUSES).array()]).optional()
|
|
330
345
|
});
|
|
331
346
|
|
|
332
347
|
const processBatchInputSchema = zod.z.object({
|
|
@@ -381,10 +396,10 @@ const getPaymentsInputSchema = zod.z.object({
|
|
|
381
396
|
[ALLOWED_PAYMENT_FILTERS.ACCOUNT_ID]: zod.z.union([zod.z.uuid(), zod.z.uuid().array()]).optional(),
|
|
382
397
|
[ALLOWED_PAYMENT_FILTERS.AMOUNT]: zod.z.union([zod.z.number(), zod.z.number().array()]).optional(),
|
|
383
398
|
[ALLOWED_PAYMENT_FILTERS.CURRENCY]: zod.z.union([zod.z.enum(generalCodes.CURRENCY_CODES), zod.z.enum(generalCodes.CURRENCY_CODES).array()]).optional(),
|
|
384
|
-
[ALLOWED_PAYMENT_FILTERS.DIRECTION]: zod.z.union([zod.z.enum(
|
|
399
|
+
[ALLOWED_PAYMENT_FILTERS.DIRECTION]: zod.z.union([zod.z.enum(paymentRequest_schema.PAYMENT_DIRECTIONS), zod.z.enum(paymentRequest_schema.PAYMENT_DIRECTIONS).array()]).optional(),
|
|
385
400
|
[ALLOWED_PAYMENT_FILTERS.FROM]: zod.z.date().optional(),
|
|
386
401
|
[ALLOWED_PAYMENT_FILTERS.TO]: zod.z.date().optional(),
|
|
387
|
-
[ALLOWED_PAYMENT_FILTERS.STATUS]: zod.z.union([zod.z.enum(
|
|
402
|
+
[ALLOWED_PAYMENT_FILTERS.STATUS]: zod.z.union([zod.z.enum(paymentRequest_schema.PAYMENT_STATUSES), zod.z.enum(paymentRequest_schema.PAYMENT_STATUSES).array()]).optional()
|
|
388
403
|
});
|
|
389
404
|
|
|
390
405
|
const syncAccountInputSchema = zod.z.object({
|
|
@@ -419,7 +434,7 @@ zod.z.object({
|
|
|
419
434
|
});
|
|
420
435
|
|
|
421
436
|
const updateAccountInputSchema = zod.z.object({
|
|
422
|
-
account:
|
|
437
|
+
account: paymentRequest_schema.accountInsertSchema
|
|
423
438
|
});
|
|
424
439
|
|
|
425
440
|
const getBankAccountsInputSchema = zod.z.object({
|
|
@@ -434,6 +449,13 @@ const disconnectAccountInputSchema = zod.z.object({
|
|
|
434
449
|
accountId: zod.z.uuid()
|
|
435
450
|
});
|
|
436
451
|
|
|
452
|
+
const handleAuthorizationCallbackInputSchema = zod.z.object({
|
|
453
|
+
paymentId: zod.z.string().uuid().optional(),
|
|
454
|
+
batchId: zod.z.string().uuid().optional()
|
|
455
|
+
}).refine((data) => data.paymentId || data.batchId, {
|
|
456
|
+
message: "Either paymentId or batchId is required"
|
|
457
|
+
});
|
|
458
|
+
|
|
437
459
|
const sendPaymentSyncInputSchema = sendPaymentInputSchema;
|
|
438
460
|
|
|
439
461
|
var __defProp = Object.defineProperty;
|
|
@@ -593,12 +615,45 @@ let BankServiceBase = class extends backendSdk.develitWorker(cloudflare_workers.
|
|
|
593
615
|
}).command.execute();
|
|
594
616
|
statusChanged = true;
|
|
595
617
|
}
|
|
618
|
+
if (statusChanged) {
|
|
619
|
+
const paymentRequests = await drizzle.getPaymentRequestsByBatchIdQuery(this.db, {
|
|
620
|
+
batchId: batch.id
|
|
621
|
+
});
|
|
622
|
+
const perPaymentStatuses = "payments" in apiResponse ? apiResponse.payments : null;
|
|
623
|
+
const batchStatusToPaymentStatus = {
|
|
624
|
+
SIGNED: "SIGNED",
|
|
625
|
+
COMPLETED: "COMPLETED",
|
|
626
|
+
FAILED: "FAILED",
|
|
627
|
+
SIGNATURE_FAILED: "FAILED"
|
|
628
|
+
};
|
|
629
|
+
for (const pr of paymentRequests) {
|
|
630
|
+
let newStatus = pr.status;
|
|
631
|
+
if (perPaymentStatuses) {
|
|
632
|
+
const match = perPaymentStatuses.find(
|
|
633
|
+
(p) => p.merchantTransactionId === pr.id
|
|
634
|
+
);
|
|
635
|
+
if (match) {
|
|
636
|
+
newStatus = mock_connector.mapFinbricksTransactionStatus(
|
|
637
|
+
match.resultCode
|
|
638
|
+
);
|
|
639
|
+
}
|
|
640
|
+
} else {
|
|
641
|
+
newStatus = batchStatusToPaymentStatus[currentStatus] ?? pr.status;
|
|
642
|
+
}
|
|
643
|
+
if (newStatus !== pr.status) {
|
|
644
|
+
await drizzle.updatePaymentRequestStatusCommand(this.db, {
|
|
645
|
+
id: pr.id,
|
|
646
|
+
status: newStatus,
|
|
647
|
+
processedAt: newStatus === "COMPLETED" || newStatus === "FAILED" ? /* @__PURE__ */ new Date() : void 0
|
|
648
|
+
}).command.execute();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
596
652
|
return {
|
|
597
653
|
batchId: batch.id,
|
|
598
654
|
previousStatus,
|
|
599
655
|
currentStatus,
|
|
600
656
|
statusChanged
|
|
601
|
-
// eventSent,
|
|
602
657
|
};
|
|
603
658
|
}
|
|
604
659
|
async updateBatchStatuses(input) {
|
|
@@ -670,6 +725,77 @@ let BankServiceBase = class extends backendSdk.develitWorker(cloudflare_workers.
|
|
|
670
725
|
}
|
|
671
726
|
);
|
|
672
727
|
}
|
|
728
|
+
async handleAuthorizationCallback(input) {
|
|
729
|
+
return this.handleAction(
|
|
730
|
+
{ data: input, schema: handleAuthorizationCallbackInputSchema },
|
|
731
|
+
{ successMessage: "Authorization callback processed" },
|
|
732
|
+
async ({ paymentId, batchId }) => {
|
|
733
|
+
let targetBatchId = null;
|
|
734
|
+
let paymentsUpdated = 0;
|
|
735
|
+
if (paymentId) {
|
|
736
|
+
const pr = await getPaymentRequestByIdQuery(this.db, { paymentId });
|
|
737
|
+
if (!pr) {
|
|
738
|
+
throw backendSdk.createInternalError(null, {
|
|
739
|
+
message: `Payment request not found: ${paymentId}`,
|
|
740
|
+
code: "DB-B-008",
|
|
741
|
+
status: 404
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
if (pr.status !== "SIGNED" && pr.status !== "COMPLETED") {
|
|
745
|
+
await drizzle.updatePaymentRequestStatusCommand(this.db, {
|
|
746
|
+
id: paymentId,
|
|
747
|
+
status: "SIGNED"
|
|
748
|
+
}).command.execute();
|
|
749
|
+
paymentsUpdated = 1;
|
|
750
|
+
}
|
|
751
|
+
targetBatchId = pr.batchId;
|
|
752
|
+
}
|
|
753
|
+
if (batchId) {
|
|
754
|
+
targetBatchId = batchId;
|
|
755
|
+
const batchPayments = await drizzle.getPaymentRequestsByBatchIdQuery(
|
|
756
|
+
this.db,
|
|
757
|
+
{
|
|
758
|
+
batchId
|
|
759
|
+
}
|
|
760
|
+
);
|
|
761
|
+
for (const pr of batchPayments) {
|
|
762
|
+
if (pr.status !== "SIGNED" && pr.status !== "COMPLETED") {
|
|
763
|
+
await drizzle.updatePaymentRequestStatusCommand(this.db, {
|
|
764
|
+
id: pr.id,
|
|
765
|
+
status: "SIGNED"
|
|
766
|
+
}).command.execute();
|
|
767
|
+
paymentsUpdated++;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
let batchSigned = false;
|
|
772
|
+
if (targetBatchId) {
|
|
773
|
+
const allPayments = await drizzle.getPaymentRequestsByBatchIdQuery(this.db, {
|
|
774
|
+
batchId: targetBatchId
|
|
775
|
+
});
|
|
776
|
+
const allDone = allPayments.every(
|
|
777
|
+
(p) => p.status === "SIGNED" || p.status === "COMPLETED"
|
|
778
|
+
);
|
|
779
|
+
if (allDone) {
|
|
780
|
+
const batch = await drizzle.getBatchByIdQuery(this.db, {
|
|
781
|
+
batchId: targetBatchId
|
|
782
|
+
});
|
|
783
|
+
if (batch && batch.status !== "SIGNED") {
|
|
784
|
+
await drizzle.upsertBatchCommand(this.db, {
|
|
785
|
+
batch: { ...batch, status: "SIGNED" }
|
|
786
|
+
}).command.execute();
|
|
787
|
+
batchSigned = true;
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
return {
|
|
792
|
+
paymentsUpdated,
|
|
793
|
+
batchId: targetBatchId,
|
|
794
|
+
batchSigned
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
);
|
|
798
|
+
}
|
|
673
799
|
async addPaymentsToBatch({
|
|
674
800
|
paymentsToBatch
|
|
675
801
|
}) {
|
|
@@ -715,21 +841,24 @@ let BankServiceBase = class extends backendSdk.develitWorker(cloudflare_workers.
|
|
|
715
841
|
(p) => p.sendAsSinglePayment !== true
|
|
716
842
|
);
|
|
717
843
|
for (const singlePayment of singlePayments) {
|
|
718
|
-
const
|
|
719
|
-
const { command } = drizzle.upsertBatchCommand(this.db, {
|
|
844
|
+
const batchId = backendSdk.uuidv4();
|
|
845
|
+
const { command: upsertBatch } = drizzle.upsertBatchCommand(this.db, {
|
|
720
846
|
batch: {
|
|
721
|
-
id:
|
|
847
|
+
id: batchId,
|
|
722
848
|
authorizationUrls: [],
|
|
723
849
|
accountId: acc.id,
|
|
724
850
|
paymentType: singlePayment.paymentType,
|
|
725
|
-
payments: [batchedPayment],
|
|
726
851
|
status: "OPEN",
|
|
727
|
-
metadata: {
|
|
728
|
-
sizeLimit: 1
|
|
729
|
-
}
|
|
852
|
+
metadata: { sizeLimit: 1 }
|
|
730
853
|
}
|
|
731
854
|
});
|
|
732
|
-
|
|
855
|
+
const { command: insertPaymentRequest } = createPaymentRequestCommand(
|
|
856
|
+
this.db,
|
|
857
|
+
{
|
|
858
|
+
paymentRequest: mock_connector.toPaymentRequestInsert(singlePayment, batchId)
|
|
859
|
+
}
|
|
860
|
+
);
|
|
861
|
+
await this.db.batch([upsertBatch, insertPaymentRequest]);
|
|
733
862
|
this.log({
|
|
734
863
|
message: `\u2728 Created single payment batch (${singlePayment.paymentType}) for account ${acc.id}`
|
|
735
864
|
});
|
|
@@ -744,30 +873,48 @@ let BankServiceBase = class extends backendSdk.develitWorker(cloudflare_workers.
|
|
|
744
873
|
accountId: acc.id,
|
|
745
874
|
paymentType
|
|
746
875
|
});
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
876
|
+
let batchId;
|
|
877
|
+
let availableCount = 0;
|
|
878
|
+
let availableBatch;
|
|
879
|
+
for (const ob of openBatches) {
|
|
880
|
+
const existingPayments = await drizzle.getPaymentRequestsByBatchIdQuery(
|
|
881
|
+
this.db,
|
|
882
|
+
{ batchId: ob.id }
|
|
883
|
+
);
|
|
884
|
+
const limit = ob.metadata?.sizeLimit ?? acc.batchSizeLimit;
|
|
885
|
+
if (existingPayments.length < limit) {
|
|
886
|
+
availableBatch = ob;
|
|
887
|
+
availableCount = existingPayments.length;
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
if (availableBatch) {
|
|
892
|
+
batchId = availableBatch.id;
|
|
893
|
+
this.log({
|
|
894
|
+
message: `\u{1F504} Found existing OPEN batch (${paymentType}) for account ${acc.id}, merging ${availableCount} existing + ${paymentsOfType.length} new payments`
|
|
895
|
+
});
|
|
896
|
+
} else {
|
|
897
|
+
batchId = backendSdk.uuidv4();
|
|
898
|
+
this.log({
|
|
899
|
+
message: `\u2728 Creating new batch (${paymentType}) for account ${acc.id} with ${paymentsOfType.length} payments`
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
const { command: upsertBatch } = drizzle.upsertBatchCommand(this.db, {
|
|
903
|
+
batch: availableBatch ? { ...availableBatch } : {
|
|
904
|
+
id: batchId,
|
|
760
905
|
authorizationUrls: [],
|
|
761
906
|
accountId: acc.id,
|
|
762
907
|
paymentType,
|
|
763
|
-
payments: batchedPayments,
|
|
764
908
|
status: "OPEN",
|
|
765
|
-
metadata: {
|
|
766
|
-
sizeLimit: acc.batchSizeLimit
|
|
767
|
-
}
|
|
909
|
+
metadata: { sizeLimit: acc.batchSizeLimit }
|
|
768
910
|
}
|
|
769
911
|
});
|
|
770
|
-
|
|
912
|
+
const paymentRequestCommands = paymentsOfType.map(
|
|
913
|
+
(p) => createPaymentRequestCommand(this.db, {
|
|
914
|
+
paymentRequest: mock_connector.toPaymentRequestInsert(p, batchId)
|
|
915
|
+
}).command
|
|
916
|
+
);
|
|
917
|
+
await this.db.batch([upsertBatch, ...paymentRequestCommands]);
|
|
771
918
|
this.log({
|
|
772
919
|
message: `\u2705 Batch (${paymentType}) upserted successfully for account ${acc.id}`
|
|
773
920
|
});
|
|
@@ -1256,6 +1403,24 @@ let BankServiceBase = class extends backendSdk.develitWorker(cloudflare_workers.
|
|
|
1256
1403
|
}
|
|
1257
1404
|
);
|
|
1258
1405
|
}
|
|
1406
|
+
async getFinbricksSupportedBanks() {
|
|
1407
|
+
const privateKeyPem = (await this.env.SECRETS_STORE.get({
|
|
1408
|
+
secretName: "BANK_SERVICE_FINBRICKS_PRIVATE_KEY_PEM"
|
|
1409
|
+
})).data?.secretValue || "";
|
|
1410
|
+
const client = new mock_connector.FinbricksClient(
|
|
1411
|
+
this.env.FINBRICKS_BASE_URI,
|
|
1412
|
+
this.env.FINBRICKS_MERCHANT_ID,
|
|
1413
|
+
privateKeyPem,
|
|
1414
|
+
this.env.REDIRECT_URI
|
|
1415
|
+
);
|
|
1416
|
+
return client.request({
|
|
1417
|
+
endpoint: mock_connector.FINBRICKS_ENDPOINTS.BANK_INFO,
|
|
1418
|
+
method: "GET",
|
|
1419
|
+
query: {
|
|
1420
|
+
merchantId: this.env.FINBRICKS_MERCHANT_ID
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
}
|
|
1259
1424
|
};
|
|
1260
1425
|
__decorateClass([
|
|
1261
1426
|
backendSdk.action("get-payments")
|
|
@@ -1272,6 +1437,9 @@ __decorateClass([
|
|
|
1272
1437
|
__decorateClass([
|
|
1273
1438
|
backendSdk.action("update-batch-statuses")
|
|
1274
1439
|
], BankServiceBase.prototype, "updateBatchStatuses", 1);
|
|
1440
|
+
__decorateClass([
|
|
1441
|
+
backendSdk.action("handle-authorization-callback")
|
|
1442
|
+
], BankServiceBase.prototype, "handleAuthorizationCallback", 1);
|
|
1275
1443
|
__decorateClass([
|
|
1276
1444
|
backendSdk.action("add-payments-to-batch")
|
|
1277
1445
|
], BankServiceBase.prototype, "addPaymentsToBatch", 1);
|