Skip to main content

bankstatementparser-loader-mt942: SWIFT MT942 loader

PyPI Version Python Versions License Tests Quality

Parse SWIFT MT942 Interim Transaction Report files into bankstatementparser Transaction objects. A single load_mt942(text) call returns a list of bankstatementparser.transaction_models.Transaction, ready for every downstream consumer that already works with the core library's parser output (deduplication, categorisation, exports).

The core bankstatementparser library parses PDF and CSV statements but does not understand the SWIFT MT942 wire format. This loader fills that gap without changing the core data model.

Contents

Overview

bankstatementparser-loader-mt942 is a small, focused companion to the bankstatementparser library. It does one thing well: parse the SWIFT MT942 Interim Transaction Report grammar and hand back the same Transaction objects the core PDF/CSV parsers produce. Every transaction is stamped with source="mt942" so you can tell where it came from.

MT942 is an interim statement. Unlike MT940 it carries no :60F: opening or :62F: closing balance — it reports a floor limit, an optional date/time stamp, the statement lines accumulated so far, and debit/credit summaries. This loader models that structure faithfully and never invents balances that are not present in the source.

Install

bankstatementparser-loader-mt942 runs on macOS, Linux, and Windows and requires Python 3.10+ and pip. It pulls in bankstatementparser (>= 0.0.11) automatically.

pip install bankstatementparser-loader-mt942

Quick Start

from bankstatementparser_loader_mt942 import load_mt942

mt942 = """:20:MT942REF001
:25:COBADEFFXXX/DE89370400440532013000
:28C:42/1
:34F:EURD0,00
:34F:EURC0,00
:13D:2506241200+0100
:61:2506240624C500,00NTRFINV-123//BANKREF1
:86:Incoming payment for invoice 123
:61:2506240624D200,50NTRFRENT//BANKREF2
:86:Monthly rent debit
:90D:1EUR200,50
:90C:1EUR500,00
-
"""

transactions = load_mt942(mt942)

for txn in transactions:
    print(txn.value_date, txn.currency, txn.amount, txn.description)
# 2025-06-24 EUR 500.00 Incoming payment for invoice 123
# 2025-06-24 EUR -200.50 Monthly rent debit

Those are bankstatementparser.transaction_models.Transaction objects — debit lines carry a negative amount, credit lines a positive one, and amounts are exact Decimal values (SWIFT's comma decimal separator 500,00 is converted to Decimal("500.00")).

To read from a file instead of a string:

from bankstatementparser_loader_mt942 import load_mt942_file

transactions = load_mt942_file("statement.mt942")

Supported Fields

Tag Meaning Cardinality
:20: Transaction reference number mandatory
:25: Account identification (the account id) mandatory
:28C: Statement / sequence number optional
:34F: Floor limit indicator <CCY>[D|C]<amount> (provides the currency) one or two
:13D: Date/time stamp YYMMDDHHMM±HHMM optional
:61: Statement line (one per booked entry) repeatable
:86: Information to account owner (attaches to the preceding :61:) optional, per line
:90D: Debit summary <count><CCY><amount> optional
:90C: Credit summary <count><CCY><amount> optional

Unrecognised tags (and the trailing - end-of-message marker) are silently ignored, so future SWIFT additions do not break parsing — this follows Postel's law: be liberal in what you accept. A malformed :61: statement line is skipped rather than fatal, so one bad row never aborts the whole parse.

Real-world wire-format constructs

Genuine bank/SWIFT exports are messier than the tidy sample above. The loader handles the following (pinned by a golden test over a real, third-party fixture in tests/fixtures/real/, whose source, licensing, and provenance are documented in tests/fixtures/real/PROVENANCE.md):

  • SWIFT message envelope. Messages wrapped in the header blocks {1:...}{2:...}{3:...} and the text block {4: … -} are unwrapped before parsing; the envelope is never mistaken for content.
  • Amounts with no fractional digits. A SWIFT amount may end on the decimal comma with nothing after it: 5000, → Decimal("5000"), 0, → Decimal("0").
  • :34F: with an embedded D/C indicator. :34F:NZDC0, yields currency NZD regardless of the C/D letter.
  • Multi-line :86:. Continuation lines that do not start with a :tag: head (e.g. /BAI/…, /BENM/…, /ACNO/…) are appended to the :86: description, newlines preserved.
  • Supplementary details after :61:. A line immediately following a :61: (before any :86:), such as a bare Transfer or wording/NBKT, is the SWIFT supplementary-details subfield. It is folded into the transaction's description (supplementary text first, then the :86: content, joined by newlines) and never glued onto the statement-line tail — so the parsed transaction_id / reference stay clean. A :61: with supplementary details but no following :86: keeps that text as its description.

Field Mapping

Each :61: statement line becomes one Transaction:

Transaction field Source
account_id :25:
currency :34F:
amount :61: amount, negated for debit (D) lines, as Decimal
value_date :61: value date (YYMMDD)
booking_date :61: optional entry date (MMDD, inherits the value-date year)
transaction_id the bank reference in the :61: tail (left of //)
reference the customer reference in the :61: tail (right of //)
description the following :86: free-form text
source always "mt942"
source_index the zero-based line index within the message

The two-digit YY year uses the standard SWIFT sliding window: 00-79 map to 20YY, 80-99 to 19YY.

Summaries

When you want the message metadata and the :90D:/:90C: roll-ups rather than the individual transactions, call summarize_mt942:

from bankstatementparser_loader_mt942 import summarize_mt942

summary = summarize_mt942(mt942)
print(summary.reference)          # MT942REF001
print(summary.currency)           # EUR
print(summary.debit_count)        # 1
print(summary.debit_sum)          # Decimal("200.50")
print(summary.credit_sum)         # Decimal("500.00")
print(summary.transaction_count)  # 2

Mt942Summary is a frozen dataclass with reference, account_id, currency, statement_datetime, debit_count, debit_sum, credit_count, credit_sum, and transaction_count. Optional fields (no :90x: / :13D: present) default to None.

Errors

A payload missing the mandatory :20: reference or :25: account identification raises ValueError with a message naming the missing tag:

load_mt942(":25:ACC\n:61:250624C10,00NTRFX\n")
# ValueError: MT942 payload missing required :20: reference

Examples

Two runnable examples live in examples/:

Both are exercised in CI on every commit.

When not to use this loader

  • You have a PDF or CSV statement. Use the core bankstatementparser parsers directly — this loader is only for the SWIFT MT942 wire format.
  • You have MT940 (final statements with balances). MT940 is a different message; this loader handles the interim MT942 report. The :61: / :86: grammar is shared, but MT942 has no :60F: / :62F: balances.
  • You need bank-specific :86: sub-field parsing (e.g. Deutsche Bank's ?20 / ?30 / ?32 GVC codes). The raw :86: value is preserved verbatim as the transaction description; downstream tooling can parse it if needed.
  • Your MT942 is PGP / GPG encrypted. Decrypt upstream and pass the plaintext to the loader.

Development

git clone https://github.com/sebastienrousseau/bankstatementparser-loader-mt942
cd bankstatementparser-loader-mt942
python -m venv .venv && source .venv/bin/activate
pip install -e .
pip install pytest pytest-cov ruff mypy interrogate
pytest --cov=bankstatementparser_loader_mt942 --cov-branch --cov-fail-under=100
ruff check bankstatementparser_loader_mt942 tests examples
mypy bankstatementparser_loader_mt942
interrogate -c pyproject.toml bankstatementparser_loader_mt942

Security

bankstatementparser-loader-mt942 parses a flat text format with no XML envelope, so the XXE / billion-laughs surface does not apply. Field regexes are anchored and bounded, so catastrophic backtracking is not a concern. Reporting practice and supported versions are documented in SECURITY.md. Vulnerabilities go via GitHub Private Vulnerability Reporting, not public issues.

Documentation

License

Licensed under the Apache License, Version 2.0. Any contribution submitted for inclusion shall be licensed as above, without additional terms.

Contributing

Contributions are welcome. Open an issue or PR on the repository.

Acknowledgements

Built on the bankstatementparser library. The MT942 grammar follows the SWIFT User Handbook MT942 Interim Transaction Report specification and the common-denominator subset shipped by major EU and UK commercial banks.

Metadata

Release files for bankstatementparser-loader-mt942 0.0.16

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bankstatementparser-loader-mt942 0.0.16
File Size Uploaded
bankstatementparser_loader_mt942-0.0.16.tar.gz 21.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bankstatementparser-loader-mt942 0.0.16
File Interpreter ABI Platform
bankstatementparser_loader_mt942-0.0.16-py3-none-any.whl Python 3 none any Details

Total release size: 42.0 kB

Release files / bankstatementparser_loader_mt942-0.0.16.tar.gz

Download URL bankstatementparser_loader_mt942-0.0.16.tar.gz
Size 21.9 kB
Tags Source
SHA-256 checksum
How to use checksums
b93112ee5dbcf1b40ca40674029ae3fe06c78325c0cfac01a20de8bb918cb6db
BLAKE2b-256 checksum
How to use checksums
38287110451165e142e593f978f9f18b6d02c029e090ca06e712a52cc861f392
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Release files / bankstatementparser_loader_mt942-0.0.16-py3-none-any.whl

Download URL bankstatementparser_loader_mt942-0.0.16-py3-none-any.whl
Size 20.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c1343e9bcdc7d26b83e4153e7725eae053232a078cf82320363c47e34c0e4f0
BLAKE2b-256 checksum
How to use checksums
4d89c18874c6dd711044a7c6e747ff0433487bee22b4de253f90036b10a0598d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 29, 2026.

Transparency log

Release history Release notifications | RSS feed

0.0.18

2 release files

This release

0.0.16 This release

2 release files

0.0.15

2 release files

0.0.14

2 release files

0.0.13

2 release files

0.0.12

2 release files

0.0.11

2 release files

0.0.10

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page