@develit-services/bank
v0.8.12
Published
Microsluzba pro spravu bankovnich uctu, zpracovani plateb a synchronizaci transakci. Postavena na Cloudflare Workers s D1 databazi.
Readme
Bank Service
Microsluzba pro spravu bankovnich uctu, zpracovani plateb a synchronizaci transakci. Postavena na Cloudflare Workers s D1 databazi.
Obsah
- Architektura
- Zivotni cyklus payment requestu
- Odeslani platby
- Batch platby
- Polling stavu (CRON)
- Synchronizace uctu
- Bankovni konektory
- RPC akce
- Event system
- Databazove schema
Architektura
Sluzba se sklada z:
- Akce (Actions) - API endpointy pro spravu uctu, plateb a batchu
- Workflows - Cloudflare Durable Objects pro asynchronni zpracovani (sync uctu)
- Konektory - Abstrakce nad API jednotlivych bank (Erste, Fio, Moneta, ...)
- CRON - Pravidelny polling stavu payment requestu
Zivotni cyklus payment requestu
Payment request (iniciovan platba) prochazi nasledujicimi stavy:
OPENED → AUTHORIZED → COMPLETED → BOOKED → SETTLED
↘ ↗
REJECTED / CLOSEDPaymentRequestStatus
| Status | Popis |
|--------|-------|
| OPENED | Platba vytvorena a odeslana do banky, ceka na autorizaci |
| AUTHORIZED | Autorizovana uzivatelem, banka zpracovava |
| COMPLETED | Banka potvrdila zpracovani, platba je na ceste |
| BOOKED | Platba zauctovana ve vypisu platce |
| SETTLED | Platba pripsana na ucet prijemce |
| REJECTED | Odmitnuta bankou nebo uzivatelem |
| CLOSED | Timeout — platba nebyla zpracovana do 14 dni |
Terminalni stavy: SETTLED, REJECTED, CLOSED
PaymentStatus (bankovni vypis)
Stavy pro tabulku payment (polozky z bankovniho vypisu):
| Status | Popis |
|--------|-------|
| PENDING | Ceka na zpracovani |
| PROCESSING | Zpracovava se |
| BOOKED | Zauctovano |
| CANCELLED | Zruseno |
| REJECTED | Odmitnuto |
| SCHEDULED | Naplanovano |
| HOLD | Pozastaveno |
| INFO | Bank-specific informace |
Typy plateb
SEPA- SEPA prevodSWIFT- SWIFT prevodDOMESTIC- Tuzemsky prevodUNKNOWN- Nezname
Odeslani platby
Akce send-payment odesle platbu primo do banky a vrati authorizationUrl + paymentId.
SendPaymentInput (API vstup)
│
▼
Validace (ucet, typ platby, mena)
│
▼
Vytvoreni payment_request v DB (status: OPENED)
│
▼
connector.initiate*Payment() (DOMESTIC/SEPA/SWIFT)
│
├─ Uspech → Update PR (bankRefId, authorizationUrl)
│ → Return { paymentId, authorizationUrl }
│
└─ Selhani → Smazani PR z DB, throw error (klient muze retry)send-payment-sync je deprecated wrapper, ktery vola send-payment.
Batch platby
Akce send-batch prijme pole plateb a odesle je do banky jako batch. Vsechny platby musi mit stejny debtor ucet (IBAN + mena) a stejny typ (DOMESTIC/SEPA/SWIFT). Pocet plateb nesmi prekrocit account.batchSizeLimit (vychozi: 50).
SendBatchInput (API vstup — pole plateb)
│
▼
Validace (stejny debtor, typ, mena, velikost)
│
▼
db.batch() — Vytvoreni batch (PROCESSING) + payment_requests (OPENED)
│
▼
connector.initiate*Batch() — automaticky fallback na single payments
│
├─ Uspech → db.batch() — Update PRs + batch (READY_TO_SIGN)
│ → Return { batchId, authorizationUrls }
│
└─ Selhani → db.batch() — Smazani batch + PRs, throw errorBatch mode
Kazdy batch ma batchMode:
NATIVE— konektor podporuje nativni batch API, vsechny platby jdou v jednom volaniSINGLE— konektor batch nepodporuje, platby se odesilaji jednotlive (automaticky fallback vIBankConnector)
BatchStatus
| Status | Popis |
|--------|-------|
| PROCESSING | Batch se odesila do banky |
| READY_TO_SIGN | Ceka na autorizaci uzivatelem |
| AUTHORIZED | Vsechny platby autorizovany |
| COMPLETED | Vsechny platby dokonceny |
| FAILED | Nektera platba selhala |
Batch status se derivuje z payment requestu — neni pollovan z banky.
Polling stavu (CRON)
Jeden CRON (CRON_PAYMENT_STATUSES) pravidelne spousti updatePaymentRequestStatuses:
- Nacte vsechny non-terminalni payment requesty
- Aplikuje polling logiku:
OPENED/AUTHORIZED— pollovat, po 14 dnech →CLOSEDCOMPLETED/BOOKED— pollovat 7 dni odprocessedAt, pak prestat
- Pro kazdy PR zavola
connector.getPaymentStatus()a updatne stav - Derivuje batch stavy z payment requestu (
_deriveBatchStatus)
Stejna logika (_resolvePaymentRequestStatuses) se vola i z handleAuthorizationCallback pro okamzity re-check po autorizaci.
Synchronizace uctu
Kazdy pripojeny ucet ma workflow SyncAccountPayments, ktery bezi v nekonecne smycce:
┌──→ Nacti konfiguraci uctu
│ │
│ ▼
│ Stahni platby z banky (connector.getAllAccountPayments)
│ │
│ ▼
│ Filtruj dokoncene platby, vloz nove do DB (deduplikace pres bankRefId)
│ │
│ ▼
│ Emituj paymentFetched eventy
│ │
│ ▼
│ Aktualizuj lastSyncAt + metadata
│ │
│ ▼
│ Spi syncIntervalS sekund (vychozi: 600s)
│ │
└────┘Bankovni konektory
Vsechny konektory dedi z abstraktni tridy IBankConnector, ktera poskytuje spolecnou logiku vcetne batch fallbacku.
Prehled konektoru
| Konektor | Klic | Batch podpora | Poznamka |
|----------|------|---------------|----------|
| Erste Bank | ERSTE | DOMESTIC | Vlastni API (neaktivni) |
| Finbricks | FINBRICKS | DOMESTIC | Platforma pro vice bank (bazova trida) |
| Moneta | MONETA | DOMESTIC | Pres Finbricks |
| Creditas | CREDITAS | Zadna | Pres Finbricks |
| Fio | FIO | DOMESTIC | Pres Finbricks |
| DBU | DBU | Zadna | Vlastni API (interni banka) |
| CSAS | CSAS | DOMESTIC | Pres Finbricks |
| AirBank | AIRBANK | DOMESTIC | Pres Finbricks |
| Mock | MOCK | Vsechny typy | Testovaci, automaticky dokoncuje platby |
Metody konektoru
Sprava uctu:
getAuthUri()- Ziskat autorizacni URLauthorizeAccount()- Dokoncit autorizaci uctu
Single platby (per typ):
initiateDomesticPayment()- Tuzemska platbainitiateSEPAPayment()- SEPA platbainitiateForeignPayment()- Zahranicni (SWIFT) platba
Batch platby (per typ):
initiateDomesticBatch()- Batch tuzemskych plateb (s automatickym fallbackem)initiateSEPABatch()- Batch SEPA platebinitiateForeignBatch()- Batch zahranicnich plateb
Synchronizace a stavy:
getAllAccountPayments()- Stahnout transakce uctugetPaymentStatus()- Zjistit stav payment requestu (vraciPaymentRequestStatus)
Abstrakce a batch fallback
Bazova trida IBankConnector implementuje template method pattern pro batch operace. Kazdy konektor deklaruje, ktere typy plateb podporuje v batchi pres metodu supportsBatch(paymentType).
Pokud konektor nepodporuje batch pro dany typ platby, bazova trida automaticky provede fallback na single platby:
initiateDomesticBatch()
│
├─ supportsBatch('DOMESTIC') === true → initiateDomesticBatchImpl() (nativni batch)
│
└─ supportsBatch('DOMESTIC') === false → for each: initiateDomesticPayment() (fallback)Vysledek je vzdy jednotny typ InitiatedBatch, bez ohledu na to, zda byl pouzit nativni batch nebo fallback. Batch zaznam v DB obsahuje batchMode: 'NATIVE' | 'SINGLE' pro rozliseni.
RPC akce
Bank service je RPC worker — nema vlastni verejne HTTP endpointy. Vsechny akce jsou dostupne pouze pres Cloudflare Worker binding.
Sprava uctu
| Akce | Popis |
|------|-------|
| get-auth-uri | Ziska autorizacni URL pro pripojeni uctu |
| authorize-account | Dokonci autorizaci uctu |
| disconnect-account | Odpoji ucet |
| get-bank-accounts | Seznam uctu |
| update-account | Aktualizace nastaveni uctu |
Platby
| Akce | Popis |
|------|-------|
| send-payment | Odesle platbu primo do banky, vrati { paymentId, authorizationUrl } |
| send-payment-sync | Deprecated — wrapper nad send-payment |
| send-batch | Odesle batch plateb primo do banky, vrati { batchId, authorizationUrls } |
| get-payments | Seznam plateb z bankovniho vypisu |
| get-payment-requests | Seznam payment requestu |
| handle-authorization-callback | Zpracuje callback po autorizaci — spusti re-check stavu pres konektor |
| simulate-deposit | Testovaci: vytvori prichozi platbu |
Batch operace
| Akce | Popis |
|------|-------|
| get-batches | Seznam batchu s paginaci a filtry |
| update-payment-request-statuses | Unified CRON — polluje stavy vsech non-terminalnich PR |
Synchronizace
| Akce | Popis |
|------|-------|
| sync-account | Spusti synchronizaci uctu (workflow) |
| sync-account-status | Stav synchronizacniho workflow |
| sync-account-restart | Restart synchronizace |
| sync-account-terminate | Zastaveni synchronizace |
Event system
Sluzba emituje dva typy eventu do QUEUE_BUS_QUEUE:
BankPaymentEvent (bankovni vypis)
type BankPaymentEvent = {
eventType: 'BANK_PAYMENT'
eventSignal: 'paymentFetched' | 'paymentUpdated'
bankPayment: Partial<PaymentSelectType>
metadata: { correlationId, entityId, timestamp }
}| Signal | Kdy se emituje |
|--------|---------------|
| paymentFetched | Nova platba synchronizovana z banky |
| paymentUpdated | Zmena stavu platby |
BankPaymentRequestEvent (lifecycle PR)
type BankPaymentRequestEvent = {
eventType: 'BANK_PAYMENT_REQUEST'
eventSignal: 'paymentRequestStatusChanged'
paymentRequest: PaymentRequestSelectType
metadata: { correlationId, entityId, timestamp }
}Emituje se v _resolvePaymentRequestStatuses pri kazde realne zmene statusu (newStatus !== pr.status).
Databazove schema
payment
Bankovni vypis — platby synchronizovane z banky (prichozi i odchozi).
Klicove sloupce: correlationId, bankRefId, amount, currency, direction, paymentType, status (PaymentStatus), accountId, connectorKey.
Unikatni omezeni: (connectorKey, bankRefId).
payment_request
Iniciovan platby — odchozi platby s lifecycle stavem.
Klicove sloupce: batchId, status (PaymentRequestStatus), bankRefId, amount, currency, paymentType, accountId, connectorKey, authorizationUrl, initiatedAt, processedAt, statusReason.
batch
Batch plateb. Status se derivuje z payment requestu.
Klicove sloupce: status (BatchStatus), batchMode (NATIVE/SINGLE), authorizationUrls, accountId, paymentType, metadata.
account
Bankovni ucet s konfiguraci synchronizace.
Klicove sloupce: iban (unikatni), connectorKey, currency, batchSizeLimit, syncIntervalS, lastSyncAt, status (AUTHORIZED/DISABLED/EXPIRED).
account_credentials
Sifrovane bankovni tokeny (AES). Typy: AUTH_TOKEN, REFRESH_TOKEN, CLIENT_ID, API_KEY.
ott (One-Time Token)
Jednorazove tokeny pro autorizacni flow uctu.
Error Codes
Format: {CATEGORY}-B-{NUMBER}
| Code | Status | Description |
|------|--------|-------------|
| DB-B-001 | 404 | No credentials found for account |
| DB-B-002 | 404 | One-time token not found |
| DB-B-003 | 404 | Account not found (authorize) |
| DB-B-004 | 404 | Account not found (update) |
| DB-B-005 | 404 | Account not found (disconnect) |
| DB-B-006 | 500 | Account not updated (disconnect) |
| DB-B-007 | 404 | Batch not found |
| DB-B-008 | 404 | Payment request not found |
| VALID-B-001 | 400 | Invalid connector key |
| VALID-B-002 | 400 | One-time token expired |
| VALID-B-003 | 422 | Unsupported account |
| VALID-B-004 | 422 | No account found for IBAN + currency |
| VALID-B-005 | 400 | Unsupported payment type |
| VALID-B-006 | 422 | Connector does not support payment type |
| VALID-B-007 | 422 | Account not authorized |
| VALID-B-008 | 422 | Payment type / currency mismatch |
| VALID-B-009 | 422 | SEPA payments require creditor IBAN |
| VALID-B-011 | 422 | Batch: debtor IBAN/currency mismatch |
| VALID-B-012 | 422 | Batch: payment type mismatch |
| VALID-B-013 | 422 | Batch: size limit exceeded |
| SYS-B-001 | 501 | Not implemented |
