Ukrainian compliance β€” Banking

Client-Bank: MT940 + PrivatBank CSV

SWIFT MT940 + PrivatBank CSV import. IBAN validation MOD-97. Smart matching: amount (40%) + Π„Π”Π ΠŸΠžΠ£ (30%) + invoice# (20%) + name (10%). Exchange differences per P(S)BO 21.

SWIFT MT940 PrivatBank CSV IBAN MOD-97 validation Auto-match β‰₯ 90% score

Two import formats: SWIFT MT940 + PrivatBank CSV

Axiom supports the two most common bank statement formats used by Ukrainian businesses. The MT940 parser handles any SWIFT-compatible bank. The PrivatBank CSV parser handles the native export from PrivatBank.

SWIFT MT940 β€” all Ukrainian SWIFT-compatible banks

Raiffeisen Β· OTP Β· FUIB Β· Ukrsibbank Β· Oschadbank Β· any SWIFT bank

  • :25: β€” account IBAN extracted and validated per ISO 13616
  • :28C: β€” statement number and sequence
  • :60F: β€” opening balance with date and currency
  • :61: β€” each transaction: value date, amount, reference
  • :86: narrative β€” counterparty IBAN and Π„Π”Π ΠŸΠžΠ£ extracted automatically

PrivatBank CSV β€” native PrivatBank online banking export

  • Transaction date, amount, currency
  • Counterparty name from CSV column
  • Π„Π”Π ΠŸΠžΠ£ extracted from reference text via keyword search
Axiom DB SWIFT MT940 :25: Β· :28C: Β· :60F: :61: Β· :86: narrative Raiffeisen OTP FUIB IBAN UA PrivatBank CSV date Β· amount Β· currency counterparty Β· Π„Π”Π ΠŸΠžΠ£ native export Β· no plugins MT940 parser Β· any SWIFT-compatible bank
IBAN Structure Β· ISO 13616 UA21 3223 1300 β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆβ–ˆβ–ˆ β–ˆβ–ˆ UA 21 32231 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ UA 2 chars country check 2 digits MOD-97 МЀО 6 digits bank code account number 19 digits 29 chars total MOD-97 algorithm Move first 4 chars to end Β· substitute letters β†’ digits Β· mod 98 = 1 βœ“ βœ“ Valid IBAN βœ— Invalid β†’ flagged

IBAN validation β€” MOD-97 per ISO 13616

Every IBAN in an imported statement is validated before it touches the database. Ukrainian IBAN: 29 characters, UA prefix, 2-digit MOD-97 check sum, 25-digit bank + account number. Invalid IBANs are flagged at import time.

UA21 3223 1300 0002 6007 2335 66001
UA prefix 2 chars β€” country code 21 check 2 digits β€” MOD-97 check sum 32231 МЀО 6 digits β€” bank code (МЀО) …001 account 19 digits β€” account number
  • ValidateUkrainianIBAN() β€” MOD-97 algorithm per ISO 13616
  • NormalizeIBAN() β€” strips spaces, uppercases, rejects non-UA prefix
  • FormatIBAN() β€” "UA21 3223 1300 0002 6007 2335 66001" (grouped by 4)
  • ExtractBankCode() β€” extracts MFO (bank code) from positions 5–9

Weighted scoring β€” smart matching algorithm

Each bank statement line is scored against all open invoices. The five scoring signals reflect how Ukrainian bank payments work in practice.

Signal Weight How it works
Amount exact match 40% abs(bank βˆ’ invoice) < 1 kopeck
Π„Π”Π ΠŸΠžΠ£ match 30% Extracted Π„Π”Π ΠŸΠžΠ£ = customer tax code
Invoice number in reference 20% Invoice number appears in :86: narrative
Name similarity 10% Jaccard index on counterparty name tokens
Date proximity 5% Statement date within 14 days of invoice due date
β‰₯ 0.9 Auto-matched, journal entry created automatically
0.6–0.9 Manual confirmation required, suggested candidate shown
< 0.6 No match β€” manual assignment or new GL posting required
Weighted Scoring Algorithm Amount abs(bank βˆ’ invoice) < 1 ΠΊΠΎΠΏ. 40% Π„Π”Π ΠŸΠžΠ£ extracted Π„Π”Π ΠŸΠžΠ£ = customer code 30% Invoice β„– invoice number in :86: narrative 20% Name Jaccard similarity on name tokens 10% Date within 14 days of invoice due date 5% β‰₯ 0.9 β†’ auto 0.6–0.9 β†’ review < 0.6 β†’ manual
Journal Entries П(Π‘)Π‘Πž 21 Date Description Dt Ct Amount Customer receipt 311 361 Supplier payment 631 311 FX gain (rate ↑) 362 714 FX loss (rate ↓) 945 362 П(Π‘)Π‘Πž 21 βœ“ GL 311 closing balance check βœ“

GL postings + exchange differences (П(Π‘)Π‘Πž 21)

Confirmed matches generate double-entry journal entries automatically. For foreign currency transactions, the exchange difference against the NBU rate on the value date is calculated and posted per P(S)BO 21.

Automatic journal entries on confirmed match

  • Customer receipt β†’ Dt 311 (Bank) / Ct 361 (Receivables)
  • Supplier payment β†’ Dt 631 (AP) / Ct 311 (Bank)
  • Tax payment β†’ Dt 641/642/651 (tax liability) / Ct 311 (Bank)
  • FX gain (rate rose) β†’ Dt 362 / Ct 714 (FX income)
  • FX loss (rate fell) β†’ Dt 945 (FX expense) / Ct 362

Reconciliation workflow

  • Import statement β†’ auto-match runs immediately for all lines
  • Review queue: manual-confirm lines (score 0.6–0.9) with candidate and score
  • Unmatched lines: assign to invoice manually or post to GL miscellaneous account
  • Closing balance check: bank closing balance vs GL account 311 β€” discrepancy flagged

MonoBank API parser is planned β€” MT940 and PrivatBank CSV are production-ready today.

Related modules