Skip to main content

Pure-Python client for the EBICS 3.0 (H005) banking protocol

Project description

ebicsclient — a pure-Python EBICS 3.0 (H005) client

A from-scratch, pure-Python client for the EBICS banking protocol (EBICS 3.0 / H005), validated live against Zürcher Kantonalbank (ZKB).

What it provides today:

  • Key ceremony — INI/HIA/HPB with X.509 key transmission (self-signed mit Schlüsseln or CA-issued mit Zertifikaten), the printable initialisation letter (HTML/PDF), and bank-key pinning across sessions
  • Read — statement/report downloads with parsers into typed models: camt.053 end-of-day statements, camt.052 intraday reports, camt.054 booking advices (incl. QRR/SCOR/LSV), and pain.002 payment status reports
  • Writepain.001 payment submission (BTU) with the A006 electronic signature
  • Security throughout — the bank's AuthSignature is verified on every response, unknown return codes are never masked, and everything fails closed
  • Self-inspectionavailable_order_types() (HAA) and subscriber_info() (HTD)

What is missing: distributed signatures (EDS/VEU — multi-person payment approval; see milestone 7 below), and validation against banks beyond ZKB. Legacy EBICS versions (H004 and earlier) are deliberately unsupported.

  • Stack: Python 3.11+, just two runtime deps — cryptography (RSA/AES) and lxml (XML / inclusive Canonical XML 1.0); everything else stdlib. No PHP/Java sidecar. (Rationale: docs/04-implementation-plan.md.)
  • License model: source-available — free for personal use, paid license for commercial/business use (see docs/02-licensing-strategy.md).
  • Reusable & app-agnostic: designed to be embedded as a dependency in a downstream application, not tied to any one consumer — a stable, reusable standard.

Why this exists

EBICS access now requires EBICS 3.0 / H005 (the pre-3.0 protocol was retired ~Nov 2025), and the ISO 20022 "2009" message vintage retires 21 Nov 2026 — so a client must speak H005 and consume camt.053.001.08 (the 2019 vintage) and submit pain.001.001.09 payments. There is no other pure-Python client for this. We build one, kept tightly scoped. EBICS is a stable, formally versioned standard, so a scoped client is low ongoing maintenance — the cost is upfront correctness. See docs/03-library-landscape.md for the landscape.

Quickstart

from ebicsclient import Bank, User, Client, generate_keyring, save_keyring, PAIN_001

bank = Bank(host_id="ZKBKCHZZ", url="https://ebicsweb.example.com/ebicsweb")
user = User(partner_id="PARTNER1", user_id="USER1")

# 1. Generate the three RSA key pairs (once) and store them encrypted.
keyring = generate_keyring()
save_keyring(keyring, "keyring.json", passphrase="…")

client = Client(bank, user, keyring)

# 2. Key initialisation: submit your keys, then print/sign/send the letter and wait for activation.
client.ini()
client.hia()
letter = client.make_ini_letter()          # HTML, or PDF with the optional [pdf] extra
# … send letter.content to the bank; once activated:

# 3. Fetch the bank's public keys (verify their published hashes out of band).
client.hpb()

# 4. Read: download and parse the end-of-day statements.
for statement in client.download_statements():
    print(statement.iban, statement.closing_balance)

# 5. Write: initiate a payment (a pain.001.001.09 document, as bytes).
transaction_id = client.upload(PAIN_001, pain001_bytes)

The certificate-based ("mit Zertifikaten") profile is a constructor option — see docs/11-certificate-profiles.md.

⚠️ Loading EBICS identifiers from a config file? Quote them.

EBICS IDs can carry leading zeros (a real Partner ID may look like 00123456), and ISO message versions look like "08". Unquoted in YAML/JSON/TOML these parse as numbers — the wrong type and silently stripped of their zeros (PyYAML even reads all-octal-digit values as octal). Since 1.3.1 the library rejects non-string values immediately with an explanatory error, but the correct fix is always quoting the value in your config (partner_id: "00123456", message_version: "08") — never wrapping the parsed number in str(), which would keep the wrong, zero-stripped identifier and talk to the bank as the wrong subscriber. The same applies to digits-only keyring passphrases.

Documentation index

Doc Contents
docs/01-protocol-and-formats.md EBICS/H005 background, the two regulatory deadlines, message formats
docs/02-licensing-strategy.md Dual-licensing plan, legal reasoning, reimplementation
docs/03-library-landscape.md Existing EBICS libraries and the gap this library fills
docs/04-implementation-plan.md Scope, modules, the two hard parts, build order, test strategy
docs/05-zkb-onboarding.md The INI/HIA + signed-letter ceremony, ZKB BTF/order params
docs/06-engineering-conventions.md Baseline practices: layout, logging, errors, security, typing, testing, CI
docs/07-handshake-testing.md Validating INI/HIA/HPB + download/upload against the ZKB test platform
docs/08-parity-and-xsd-findings.md The inclusive-vs-exclusive c14n correction and verification discipline
docs/09-zkb-test-platform-settings.md What the ZKB test platform exposes, and its upload/simulation model
docs/10-btf-order-types.md ZKB's EBICS order-type → H005 BTF catalogue
docs/11-certificate-profiles.md "mit Schlüsseln" vs "mit Zertifikaten", and the certificate seam
../local/ (outside the repo) Real ZKB connection credentials, kept in the workspace outside the repo — can't be committed

Development

Contributors: see CONTRIBUTING.md. One-command setup with uv: git clone https://github.com/schulluk/ebicsclient && cd ebicsclient && uv sync --all-groups (or pip install -e . --group dev on pip ≥ 25.1). This is a money-moving library — the engineering bar is docs/06-engineering-conventions.md.

Status

Read and write validated live against the ZKB test platform. The key ceremony, the statement download path, and the payment upload (envelope, authentication signature, A006 electronic signature, and order-data encryption) are all accepted by the bank, and the camt.053 parser is validated against a real bank statement.

Milestone 1 — Key ceremony (validated live on ZKB)

  • Key generation + encrypted keyring, and EBICS public-key hashes
  • Authentication signature (inclusive Canonical XML 1.0 + RSA-SHA256)
  • HTTPS transport (TLS 1.2 floor, certifi fallback via the optional tls extra)
  • INI/HIA/HPB handshake
  • X.509 key transmission: mit Schlüsseln (self-signed) and mit Zertifikaten (CA certs)
  • Initialisation letter (HTML, or PDF via the optional pdf extra)
  • Bank-key pinning across sessions (hpb(pinned=...))

Milestone 2 — Read (validated live on ZKB)

  • Order-data decryption (RSA-unwrap + AES-128-CBC)
  • Statement download — EOP/camt.053 BTD transaction (initialise → transfer → receipt)
  • camt.053 parsing (balances + entries) — validated on a real ZKB statement

Milestone 3 — Write (validated live on ZKB)

  • Order-data encryption and the A006 electronic signature (RSASSA-PSS)
  • Payment upload — MCT/pain.001 BTU transaction — accepted live

Milestone 4 — Verification & release

  • Exception model with retryability classification
  • Offline verification: H005 XSD validation, C14N golden vectors, ebics-client-php parity
  • Golden regression fixture from a real ZKB statement
  • CI (ruff / mypy --strict / pytest) and tag-triggered PyPI releases (Trusted Publishing)

Milestone 5 — Message formats (parsers built against genuine ZKB messages)

  • pain.002 status-report parser (group / payment / transaction statuses, reason codes)
  • camt.052 intraday reports
  • camt.054 booking advices (incl. the QRR / SCOR / LSV variants via service_option)

Milestone 6 — Protocol hardening & conveniences

  • Verify the bank's AuthSignature on every response — validated live on ZKB
  • Subscriber self-inspection — available_order_types() (HAA) and subscriber_info() (HTD)

Milestone 7 — Distributed signatures (EDS/VEU) (next; parked until validatable)

EDS (Elektronische Verteilte Unterschrift) is EBICS's workflow for orders that need multiple people to sign before the bank executes them — dual control on payments. An order is uploaded with requestEDS and parks in the bank's VEU queue; further signatories list the queue, inspect the order, and deliver their A006 signatures until the configured quorum (e.g. first + second signature) is reached. The building blocks (A006 signing, the SignatureFlag, the admin-download transaction pattern) are in place; what is missing is a validatable multi-user setup — the ZKB test subscriber is single-user with NumSigRequired=0, so the workflow cannot be exercised there. This milestone starts when a downstream setup with a real multi-signature profile exists.

  • Upload into the VEU queue (SignatureFlag with requestEDS)
  • List pending orders (HVU/HVZ) and fetch order details (HVD) and transactions (HVT)
  • Deliver an additional signature (HVE) and cancel a pending order (HVS)
  • Validate the full quorum workflow against a multi-signature bank profile

This client is EBICS 3.0 (H005) only — legacy versions (H004 and earlier) will not be supported (see docs/04); the protocol/ seam exists for a future EBICS version, not for the past.

License

Source-available under the PolyForm Noncommercial License 1.0.0free for noncommercial use; commercial/business use requires a paid license. See LICENSE.md and the rationale in docs/02-licensing-strategy.md.

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

ebicsclient-1.3.2.tar.gz (187.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ebicsclient-1.3.2-py3-none-any.whl (65.0 kB view details)

Uploaded Python 3

File details

Details for the file ebicsclient-1.3.2.tar.gz.

File metadata

  • Download URL: ebicsclient-1.3.2.tar.gz
  • Upload date:
  • Size: 187.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ebicsclient-1.3.2.tar.gz
Algorithm Hash digest
SHA256 305e7810300f40ffb7d2dce4c7940e32d39c4bf5d1d308c37518a373eec14b8f
MD5 cfee145ee4341e60080709ee0665330a
BLAKE2b-256 9083b53c31f8695a91ff412dc3bb3dd44d6daaebe4dc5aef31b401188080262c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ebicsclient-1.3.2.tar.gz:

Publisher: release.yml on schulluk/ebicsclient

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ebicsclient-1.3.2-py3-none-any.whl.

File metadata

  • Download URL: ebicsclient-1.3.2-py3-none-any.whl
  • Upload date:
  • Size: 65.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ebicsclient-1.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4e84b7a00538b89df4528309a8196caddc4495d096c7af02be1330e6f8d11205
MD5 e43cb806dad9ca9d42b47049edd9c5d8
BLAKE2b-256 5bee5ebb797970caac989f1bc84251a4c7ae0606494492355199a88203b7aa31

See more details on using hashes here.

Provenance

The following attestation bundles were made for ebicsclient-1.3.2-py3-none-any.whl:

Publisher: release.yml on schulluk/ebicsclient

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page