Bank Exchange — інтеграція з банком¶
Статус: ✅ Backend MVP shipped 2026-05-10 (Sprint 5 з cash-bank-audit) — імпорт, авто-зіставлення, Kanban UI, lifecycle. Direct bank API + AI matching by purpose — лишаються deferred.
Призначення¶
Аддон для двостороннього обміну з банком:
- Імпорт виписок (бак → DOP) — автоматичне створення IncomingPayment / OutgoingPayment
- Експорт платіжних доручень (DOP → банк) — генерація payment batches
Реалізовано (Sprint 5 з cash-bank-audit-2026-05-10)¶
Import виписки — 4 формати¶
- SWIFT MT940 (
.sta/.mt940) — теговий формат,:60F:/:61:/:86:/:62F:блоки - ISO 20022 camt.053 (
.xml) — Bank-to-Customer Statement з namespace stripping - PrivatBank Business CSV — гнучка авто-детекція заголовків (UA/RU)
- Monobank Business CSV —
Дата i час,Деталі операції, signed amount
Idempotency: SHA-256 хеш файла + unique(tenant, settlement_account, raw_file_hash) — повторний завантаж того ж файлу повертає 409 з посиланням на existing statement.
Auto-match¶
propose_matches()— confidence scoring 1.00 / 0.85 / 0.70 / 0.55 / 0.40 за: amount, IBAN→Client (черезSettlementAccount.client), EDRPOU→Client, value_date ±3d- Авто-link тільки коли top-кандидат єдиний з confidence=1.0; ambiguous залишаються
pendingзі списком кандидатів BankMatchingRule— per-tenant правила (partner_iban/partner_edrpou/description_pattern/amount range→business_operation+expense_item+client)
UI Kanban¶
- 3 колонки: Pending / Matched / Created
- Per-line action menu: Accept candidate / Create payment / Mark ignored / Unmatch
- Statement toolbar: Refresh matches / Post / Unpost
- Counters strip +
Reconciled progressбейдж
Lifecycle¶
BankStatement(state='posted')означає «всі рядки опрацьовано» — НЕ пише уPostingGroup. Проводки робить пов'язанийIncomingPayment/OutgoingPayment.create_payment_from_line()— спавнитьIncomingPayment.clientабоOutgoingPayment.supplierз line + applied_rule defaults; залишаєstate='draft'.
Endpoints¶
POST /api/v1/essentials/bank-statements/import_file/(multipart)POST /api/v1/essentials/bank-statements/{id}/{propose_matches,post_document,unpost_document}/POST /api/v1/essentials/bank-statement-lines/{id}/{accept_match,unmatch,mark_ignored,create_payment}/- CRUD
/api/v1/essentials/bank-matching-rules/
20 lifecycle тестів — backend/essentials/tests/test_bank_statement_lifecycle.py. Деталі для портування — docs/ai/domains/essentials/bank-statements/.
🔮 Deferred¶
Export платіжних доручень¶
- Генерація пакета платежів (від
OutgoingPaymentзі статусом approved) - Вивантаження у форматі для банк-клієнта
- Підпис електронним ключем (КЕП)
- Trigger: клієнт з обсягом >50 outgoing/день, де ручне введення у банк-клієнт стає bottleneck'ом
🔮 Deferred / Ideas¶
Direct API integration (без файлів)¶
Мотивація: виписки в реальному часі без щоденного імпорту .xml Чому відкладено: у кожного банку свій REST API + OAuth Trigger: клієнт з потребою intraday balance
AI matching by purpose field¶
Мотивація: з призначення платежу AI може вгадати Invoice Чому відкладено: потрібна навчена модель на історії Trigger: після накопичення базової історії узгоджень
Multi-bank dashboard¶
Мотивація: клієнти з кількома р/р у різних банках хочуть консолідований view Чому відкладено: залежить від наявних інтеграцій Trigger: після підключення 2+ банків