Перейти до змісту

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 rangebusiness_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+ банків


Пов'язане