Skip to content

Support EBICS 3.0 BTD download orders (service params + date range) - #53

Open
Trofeomedia wants to merge 4 commits into
ebics-java:masterfrom
Trofeomedia:feat/btd-download
Open

Support EBICS 3.0 BTD download orders (service params + date range)#53
Trofeomedia wants to merge 4 commits into
ebics-java:masterfrom
Trofeomedia:feat/btd-download

Conversation

@Trofeomedia

Copy link
Copy Markdown
Contributor

Downloads currently send the 3-letter code as AdminOrderType with empty StandardOrderParams, which EBICS 3.0 banks reject for customer data orders. This PR mirrors the existing BTU upload path on the download side: optional EbicsDownloadParams produce AdminOrderType=BTD with a BTDOrderParams/Service block (service name, scope, optional service option, message name/version, container type) and an optional DateRange. Behaviour without params is unchanged.

Related fixes that surfaced while testing this against a real EBICS 3.0 bank server:

  • Caller properties now override the bundled config.properties (DefaultConfiguration read only the bundled file before). Practical impact: EBICS_VERSION was silently ignored and every H005 request carried Version="H003" in the H005 namespace — schema-valid (the pattern is H\d{3}), accepted by some servers, rejected by stricter ones.
  • Download arguments are validated before any bank contact, and the date range uses LocalDate (the day the caller typed is the day that reaches the bank, timezone-free).
  • The MsgName Version attribute is omitted when no version is given instead of being written as an empty string, which fails the H005 NumStringType minLength facet. Bank-published BTF lists contain versionless entries (e.g. ZKB's result archive OTH BIL CH004TPE msc).
  • The parameterized launcher gained an XTC convenience mapping (ZKB ISO 20022 test platform's camt simulation input, OTH BIL CH004TPS csv, no ES) mirroring the existing XE2 special case.

Tested end-to-end against testplattform.zkb.ch (ZKB's public EBICS 3.0 test platform): INI/HIA/HPB key exchange with out-of-band fingerprint verification, BTU upload (OTH BIL CH004TPS csv), and BTD downloads (EOP CH camt.053 08 ZIP and OTH BIL CH004TPE msc ZIP) returning real generated camt files. Full unit test suite green (40/40).

🤖 Generated with Claude Code

Trofeomedia and others added 4 commits August 10, 2026 15:39
…range

Downloads sent the 3-letter order code as AdminOrderType with empty
StandardOrderParams, which EBICS 3.0 banks reject for customer data. This
mirrors the existing BTU upload path: optional EbicsDownloadParams produce
AdminOrderType=BTD with a BTDOrderParams/Service block, container type and an
optional DateRange.

Also fixes the date range that fetchFile(file, orderType, start, end) accepted
and dropped: without a service name the legacy order type is kept and the range
goes into StandardOrderParams. Behaviour without params is unchanged.

Dates are written as plain xs:date; passing a Calendar made XMLBeans append the
local offset (2026-08-10+02:00), which shifts the reported day for a bank in
another timezone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ocalDate

Review round 1 on the BTD download support.

- Reject a partial or reversed date range in the EbicsDownloadParams constructor,
  the one place every caller passes through. A half range used to be dropped when
  the request was built, on the launcher's legacy path without even a warning; a
  reversed range is schema-valid and comes back as EBICS_NO_DOWNLOAD_DATA_AVAILABLE,
  indistinguishable from a genuinely empty period.
- Check every launcher argument before the first environment read, keystore access
  or bank call. It ran after loadUser/createUser and after --ini/--hia/--hpb, so an
  incomplete --btd order could still fire an INI request first, and INI is one-shot
  at most banks.
- Carry the report period as LocalDate instead of Date. A calendar day read out of
  an instant depends on the machine's timezone: a UTC-midnight Date becomes the
  previous day west of UTC. The Date-taking overloads are kept and now document
  that. Adds createDateRange(LocalDate, LocalDate).
- Upper-case the EBICS code list values (--service, --scope, --option, --container)
  so --container zip no longer aborts. Message names such as camt.053 stay as given.

Tests 31 -> 36. New guards were each seen failing first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DefaultConfiguration takes a Properties object, stores it, and then never reads
it: getString() only ever consulted the ResourceBundle, so every setting an
embedder passed in was silently discarded.

Three of the four affected values happened to match the bundled defaults, so
nobody noticed. The fourth did not: ebics.version stayed pinned to H003
(EBICS 2.4) even when the caller asked for H005 (EBICS 3.0), so every request --
INI, HIA, HPB and BTD alike -- went out carrying Version="H003" inside an
urn:org:ebics:H005 document.

Neither the unit tests nor schema validation could catch this. The tests assert
on the order block, not the envelope attributes, and ProtocolVersionType is
defined as the pattern H\d{3} rather than an enumeration, so H003 validates
happily. It only surfaces when you run the client and read what it emits.

Verified against a local EBICS host: before the fix all three key-management
requests carried Version="H003"; afterwards all three carry H005 and remain
schema-valid.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- OrderType XTC + launcher branch: uploads the ZKB test platform's
  camt simulation CSV via EBICS 3.0 BTU (OTH BIL CH004TPS csv, no ES).
- --msg-version is now optional for --btd: bank lists like ZKB's
  result archive (OTH BIL CH004TPE msc) carry no version, and an
  empty Version attribute fails the H005 NumStringType facet.
- EbicsXmlFactory omits the MsgName Version attribute when null
  (BTU and BTD) instead of writing an empty string.

Verified against testplattform.zkb.ch: XTC upload accepted (N003),
XTD download returned the generated camt.052/053/054 for our own
SCOR payments. Full test suite green (40/40).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@uwemaurer

Copy link
Copy Markdown
Collaborator

Thank you for your changes! I already cherry picked two of your commits earlier because my claude was going to implement the same thing. we need to resolve the conflicts in this PR now before merging

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants