SWIFT MT942 Interim Transaction Report loader for the bankstatementparser library — parses MT942 into bankstatementparser Transaction objects.
Project description
bankstatementparser-loader-mt942: SWIFT MT942 loader
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
bankstatementparserlibrary 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
- Install
- Quick Start
- Supported Fields
- Field Mapping
- Summaries
- Errors
- Examples
- When not to use this loader
- Development
- Security
- Documentation
- License
- Contributing
- Acknowledgements
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.9) 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/):
- 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 currencyNZDregardless of theC/Dletter.- 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 bareTransferorwording/NBKT, is the SWIFT supplementary-details subfield. It is folded into the transaction'sdescription(supplementary text first, then the:86:content, joined by newlines) and never glued onto the statement-line tail — so the parsedtransaction_id/referencestay 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/:
01_load_mt942.py— parse a small MT942 string into transactions.02_summarize_mt942.py— read a file and print theMt942Summaryroll-ups.
Both are exercised in CI on every commit.
When not to use this loader
- You have a PDF or CSV statement. Use the core
bankstatementparserparsers 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/?32GVC codes). The raw:86:value is preserved verbatim as the transactiondescription; 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
README.md— this fileARCHITECTURE.md— codebase mapCHANGELOG.md— release notesROADMAP.md— what's nextSECURITY.md— disclosure + supported versionsexamples/— runnable scripts, exercised in CI
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.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bankstatementparser_loader_mt942-0.0.12.tar.gz.
File metadata
- Download URL: bankstatementparser_loader_mt942-0.0.12.tar.gz
- Upload date:
- Size: 20.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a4c0c3656540eaa9e386eb38ee4664b1e12a1c46db570524ac99e0f85e507e0
|
|
| MD5 |
18060d6270f5c06823841b148ff43a5d
|
|
| BLAKE2b-256 |
4b12da0463fa1dbb1ac377c1cba847d43a9b2612815a220e2c486e39bffb402c
|
Provenance
The following attestation bundles were made for bankstatementparser_loader_mt942-0.0.12.tar.gz:
Publisher:
release.yml on sebastienrousseau/bankstatementparser-loader-mt942
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bankstatementparser_loader_mt942-0.0.12.tar.gz -
Subject digest:
4a4c0c3656540eaa9e386eb38ee4664b1e12a1c46db570524ac99e0f85e507e0 - Sigstore transparency entry: 1944178997
- Sigstore integration time:
-
Permalink:
sebastienrousseau/bankstatementparser-loader-mt942@fb57fe20ac43a5954366aa458a233b5c40e753b1 -
Branch / Tag:
refs/tags/v0.0.12 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb57fe20ac43a5954366aa458a233b5c40e753b1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file bankstatementparser_loader_mt942-0.0.12-py3-none-any.whl.
File metadata
- Download URL: bankstatementparser_loader_mt942-0.0.12-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd231ca80ecf5aa9d6e5e74c034c2bf8b87c3e87aa733abeb5d3ab0d13dd2864
|
|
| MD5 |
1be5f6a75680fdea97129fee6df75305
|
|
| BLAKE2b-256 |
5d57bc12049c16c3d6fb217b99b06effaec11b740adb7f07211c7e392f6823ab
|
Provenance
The following attestation bundles were made for bankstatementparser_loader_mt942-0.0.12-py3-none-any.whl:
Publisher:
release.yml on sebastienrousseau/bankstatementparser-loader-mt942
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bankstatementparser_loader_mt942-0.0.12-py3-none-any.whl -
Subject digest:
cd231ca80ecf5aa9d6e5e74c034c2bf8b87c3e87aa733abeb5d3ab0d13dd2864 - Sigstore transparency entry: 1944179086
- Sigstore integration time:
-
Permalink:
sebastienrousseau/bankstatementparser-loader-mt942@fb57fe20ac43a5954366aa458a233b5c40e753b1 -
Branch / Tag:
refs/tags/v0.0.12 - Owner: https://github.com/sebastienrousseau
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@fb57fe20ac43a5954366aa458a233b5c40e753b1 -
Trigger Event:
push
-
Statement type: