Skip to main content
Bank Statement Import (MT940/CSV/OFX) — Import bank statements in MT940, CAMT — 1/1Illustrative preview

Import bank statements in MT940, CAMT.053, OFX, QIF or CSV and auto-map them to journals

— built, installed & supported by ECOSIRE.

What is Bank Statement Import (MT940/CSV/OFX)?

Import bank statements in MT940, CAMT.053, OFX, QIF or CSV and auto-map them to journals — built, installed & supported by ECOSIRE. Built to order by ECOSIRE for Odoo 17, 18, 19 — indicative price from $999.00 USD; request a quote for a scoped proposal.

Key Features

MT940 parser (SWIFT / German bank format) handling :61: / :86: transaction and detail lines, opening and closing balances
CAMT.053 (ISO 20022 camt.053.001.xx) XML parser reading Ntry, NtryDtls and end-to-end references
OFX and QIF parsers for personal-banking and legacy exports
Fully configurable CSV/TSV parser: delimiter, quote char, header row, date format, decimal and thousand separators
Saved bank-specific column-mapping templates stored as an Odoo model — pick the bank, upload, done
Support for single signed-amount columns OR separate debit/credit columns, plus sign-inversion per bank
Automatic journal assignment: map an IBAN/BIC/account number in the file header to the correct Odoo bank journal
Duplicate-line detection via a computed hash (@api.depends on date + amount + reference) and bank end-to-end IDs
Multi-currency statement support — statement currency preserved, converted at the transaction-date rate against the journal currency
Guided import wizard (TransientModel) with a parsed-line preview and validation before posting the account.bank.statement
Creates native account.bank.statement.line records so Odoo reconciliation, bank-matching rules and Enterprise auto-reconcile work unchanged
Row-level error reporting: unparseable lines are surfaced with the reason instead of silently dropped
ir.model.access.csv access rules plus optional company_id record rules for multi-company isolation
QWeb import-summary report (lines imported, skipped, duplicates, totals) per import run
Optional automated action to alert finance by email when a scheduled or API-driven import fails
XML-RPC / JSON-RPC entry point so upstream systems or a bank SFTP drop can push files into the importer

Built to order, done for you

No DIY setup — a working app, built, installed and supported by ECOSIRE.

  1. 1

    You order

    Start with a one-time build price. We scope it with you at kickoff.

  2. 2

    We build & install

    ECOSIRE builds, configures and installs it on your Odoo.

  3. 3

    Go live + support

    You go live in about one working week, with two weeks of go-live support. Defects in the code we deliver are fixed free of charge.

Technical Specifications

Odoo Compatibility
Odoo 17, Odoo 18, Odoo 19
Editions
Enterprise & Community
License
Licence confirmation required
Python Requirement
Python 3.10+
Database
PostgreSQL 12+

About this Product

If your bank does not offer a live feed to Odoo — or the feed is unreliable, region-specific, or Enterprise-only — your finance team is stuck keying transactions by hand or wrestling with brittle spreadsheet imports. Odoo's core account.statement.import handles OFX, QIF, CAMT and CSV to a point, but real bank exports are messy: German banks ship MT940, some SWIFT statements arrive as CAMT.053, and every bank's CSV puts the date, value date, amount, sign, and reference columns in a different order. That mismatch is exactly where reconciliation breaks down.

This is a BUILD-TO-ORDER module: ECOSIRE designs, builds, installs and supports a bank-statement import engine tailored to the exact file formats your banks actually produce. It is not an instant apps.odoo.com download — we scope it to your banks, build it against your Odoo edition, and hand it over configured and tested. Typical delivery is one working week depending on how many banks and formats you need.

Under the hood it ships as a proper Odoo addon: a versioned __manifest__.py declaring dependencies on account and account_bank_statement_import, ORM models (models.Model) for reusable bank-mapping templates and import runs, parsers for MT940, CAMT.053 (ISO 20022), OFX, QIF and arbitrary CSV, and a guided wizard (TransientModel) that lets your team upload a file, pick the target journal, preview parsed lines, and post the resulting account.bank.statement. Each import creates standard statement lines so Odoo's existing reconciliation, bank-matching rules and reporting work unchanged — nothing is bolted on the side.

Column mapping is stored, not re-guessed every time. We build a saved template per bank (which column is the transaction date, which is the value date, whether amount is a single signed column or separate debit/credit columns, the decimal/thousand separators, the date format, and the currency) so a treasury clerk just chooses "HSBC AED — Current" and uploads. Duplicate-line detection compares the bank's unique end-to-end reference (or a computed hash of date + amount + reference via an @api.depends compute field) against already-imported lines, so re-importing an overlapping date range never double-books a transaction. Multi-currency statements are parsed with the statement currency preserved and converted against the journal currency using Odoo's rate on the transaction date.

Security follows Odoo conventions: access to the import wizard and mapping templates is governed by ir.model.access.csv and, where you need it, record rules scoped to company_id so a multi-company group only sees its own bank templates. Everything is delivered with a QWeb import-summary report, an optional automated action to email finance when a file fails to parse, and — if you integrate upstream systems — the standard XML-RPC / JSON-RPC endpoints to push files programmatically. We build on Community or Enterprise and support Odoo 17, 18 and 19.

What you get

  • Complete, installable Odoo addon (source code) with a versioned __manifest__.py targeting your Odoo 17, 18 or 19 edition (Community or Enterprise)
  • Parser modules for every format your banks actually produce (MT940, CAMT.053, OFX, QIF, CSV) — only what you need, built and tested against your real sample files
  • Pre-built column-mapping templates for each of your banks, configured and validated against sample statements you provide
  • Security configuration: ir.model.access.csv entries and any required company_id record rules, wired to your accounting roles
  • QWeb import-summary report plus optional automated-action email alerts on failed imports
  • Installation on your server (or Odoo.sh / ECOSIRE-managed hosting) and a smoke test posting a real statement to a test journal
  • Admin + end-user documentation and a live training session for your finance team on running imports and adding new bank templates
  • A defined post-delivery support and bug-fix window, with paid maintenance available for new banks, formats or Odoo version upgrades

Who this is for

Finance / treasury clerk without a bank feed

Downloads statements from the bank portal every morning and currently types or copy-pastes each line into Odoo. Wants to upload the same file and have transactions land in the right journal, deduplicated, ready to reconcile — in seconds, not hours.

Accounting manager / controller

Owns reconciliation accuracy and month-end close across several bank accounts and currencies. Needs guaranteed no-double-booking, a clear audit trail of what was imported, and consistent handling when a bank changes its export layout.

ERP administrator / IT lead

Runs the Odoo instance and cares about a clean, upgrade-safe addon rather than one-off scripts. Wants proper access rights, multi-company isolation, and optionally an XML-RPC/JSON-RPC or SFTP hook so imports can be automated instead of manual.

How Bank Statement Import (MT940/CSV/OFX) Compares

CriterionECOSIRECustom BuildCompetitorOdoo Native
MT940 / CAMT.053 format supportBuilt-in parsers for MT940 and CAMT.053 plus OFX/QIF/CSV, tested on your real filesOnly if the DIY build implements each parser correctly — SWIFT/ISO 20022 edge cases are easy to missVaries by add-on; many cover CSV/OFX only and skip MT940OFX, QIF, CAMT and generic CSV in core; no MT940 parser
Per-bank saved column mappingSaved mapping template per bank (columns, signs, separators, date format) — pick and uploadPossible but usually hard-coded per bank; brittle when layouts changeSome offer mapping UIs, quality and flexibility vary widelyGeneric CSV import with manual field matching each time; no reusable per-bank template
Duplicate-line detectionEnd-to-end reference match plus computed date+amount+reference hash; re-imports skip duplicatesOnly if explicitly coded; commonly overlooked, leading to double-bookingSometimes included, sometimes basic date-range onlyLimited safeguards; overlapping re-imports can create duplicate lines
Automatic journal assignmentIBAN/BIC/account in the file header mapped to the correct Odoo bank journalMust be built and maintained manuallyOften requires selecting the journal manually each importJournal selected manually per import
Multi-currency handlingStatement currency preserved and converted at transaction-date rate against the journal currencyDepends entirely on the DIY implementationInconsistent; some ignore statement currencyPartial — depends on format and journal setup
Fit to your Odoo edition & workflowBuilt for Odoo 17/18/19, Community or Enterprise, wired to your journals, roles and multi-company setupFully custom but you carry all the build and maintenance riskOff-the-shelf — you adapt to it, not the other way aroundWhatever core provides; no tailoring
Support, source ownership & upgradesDelivered with docs, training, a support window and paid maintenance; you own the source and we port it across versionsYou own it but also own every bug fix and version upgradeVendor-dependent; support quality and version updates varyCovered by your Odoo support/subscription only for core behavior

Frequently Asked Questions about Bank Statement Import

How long until the module is delivered and live?

This is a build-to-order module, not an instant download. Typical delivery is one working week from the point we receive your sample statement files and confirm which banks, formats and Odoo edition you're on. A single bank in one format lands toward the 2-week end; several banks with mixed MT940/CAMT/CSV layouts and multi-currency handling sit toward 4 weeks. We share a scoped timeline before we start and install it on your server or Odoo.sh when it's tested.

What support and updates do I get after delivery?

Every build includes a defined post-delivery support window to fix any bugs in the delivered scope at no extra cost. Beyond that, we offer a paid maintenance option that covers adding new banks or file formats, adapting when a bank changes its export layout, and porting the module forward when you upgrade Odoo (e.g. 17 to 18 to 19). You own the source code, so you're never locked in.

My bank's CSV columns are in an unusual order and use commas as decimals — can you handle that?

Yes — that's exactly the case this module is built for. We create a saved mapping template per bank that records which column is the transaction date, which is the value date, whether the amount is one signed column or split debit/credit, the sign convention, the date format, and the decimal and thousand separators. Once built, your team just selects the bank and uploads the file; no re-mapping each time.

Will re-importing an overlapping date range double-book transactions?

No. Duplicate-line detection compares each incoming line against already-imported lines using the bank's unique end-to-end reference where available, and otherwise a computed hash of date, amount and reference (an Odoo compute field with @api.depends). Overlapping or accidentally re-uploaded files skip the lines already present and only import genuinely new ones — the import summary tells you exactly how many were skipped as duplicates.

How is this different from Odoo's built-in statement import or a live bank feed?

Odoo core imports OFX, QIF, CAMT and generic CSV but has no MT940 parser and no per-bank saved column mapping, so real-world bank CSVs and German MT940 exports fail or need manual clean-up. A live bank feed (Enterprise) is great when your bank is supported — but many regional banks aren't, feeds cost per connection, and they don't cover historical back-loading. This module fills that gap: it imports whatever file your bank gives you, mapped to the right journal, deduplicated, in your Odoo edition.

Does it work with multi-company and multi-currency setups?

Yes. Statements are parsed with their own currency preserved and converted at the transaction-date rate against the journal currency using Odoo's currency rates. For multi-company groups we add company_id record rules so each company only sees and imports against its own bank journals and templates, and access to the import wizard is governed through ir.model.access.csv tied to your existing accounting roles.

Can imports be automated instead of done by hand?

They can. On top of the manual upload wizard, we can wire an automated action and expose the importer over Odoo's XML-RPC / JSON-RPC API so an upstream system, script, or a scheduled pull from a bank SFTP drop can push files in automatically — with an email alert to finance if a file fails to parse. We scope this as an add-on since it depends on how your bank delivers files.

Request a quote

Bank Statement Import

Import bank statements in MT940, CAMT.053, OFX, QIF or CSV and auto-map them to journals — built, installed & supported by ECOSIRE.

  • MT940 parser (SWIFT / German bank format) handling :61: / :86: transaction and detail lines, opening and closing balances
  • CAMT.053 (ISO 20022 camt.053.001.xx) XML parser reading Ntry, NtryDtls and end-to-end references
  • OFX and QIF parsers for personal-banking and legacy exports
  • Fully configurable CSV/TSV parser: delimiter, quote char, header row, date format, decimal and thousand separators

Request a Quotation

Tell us about your Bank Statement Import requirements and we'll send pricing, licensing options and a tailored proposal — usually within one business day.

No payment now. This sends a quote request to our team — we'll follow up by email with pricing and next steps.