Skip to content

feat: implement missing FinTS 3 features (HKPAE, HKCSE, full mock server & integration tests)#42

Open
Copilot wants to merge 4 commits intomasterfrom
copilot/implement-fints-3-features
Open

feat: implement missing FinTS 3 features (HKPAE, HKCSE, full mock server & integration tests)#42
Copilot wants to merge 4 commits intomasterfrom
copilot/implement-fints-3-features

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 16, 2026

Summary

Implements the previously missing FinTS 3.0 business transactions, extends the mock bank server to cover all operations, and adds comprehensive integration tests.

Changes

New FinTS 3 Segments

  • HKPAE (hkpae.ts) – PIN change request (Persönliche Kennung ändern, FinTS 3.0 §C.4.1). Sends new PIN twice for confirmation; old PIN is authenticated via the standard HNSHA mechanism.
  • HKCSE (hkcse.ts) – Scheduled SEPA credit transfer (Terminüberweisung). Same pain.001 structure as HKCCS but with ReqdExctnDt set to a future date inside the XML.
  • HICSE (hicse.ts) – Bank acknowledgement for HKCSE, carrying the assigned task ID.
  • HICSES (hicses.ts) – Parameter segment advertised by the bank during sync to indicate scheduled credit transfer support.

Client Methods

  • changePin(newPin) – Sends HKPAE and handles the dialog lifecycle.
  • scheduledCreditTransfer(account, request) – Sends HKCSE with a future execution date embedded in the pain.001 XML.
  • completeScheduledCreditTransfer(...) – Completes a TAN-challenged scheduled transfer.

Capability Detection

  • supportsScheduledCreditTransfer added to BankCapabilities, Dialog, and FinTS4Client.

Mock Bank Server (mock-bank-server.ts)

Now handles all major FinTS 3 business transactions:

  • HKSPA, HKSAL, HKKAZ (existing) ✓
  • HKCCS → HICCS (SEPA credit transfer) ✓
  • HKDSE → HIDSE (SEPA direct debit) ✓
  • HKCSE → HICSE (scheduled credit transfer) ✓ (new)
  • HKCDB → HICDB (standing orders) ✓
  • HKWPD → HIWPD (securities portfolio / MT535) ✓
  • HKPAE (PIN change) ✓ (new)

Sync response now advertises: HICCSS, HIDSES, HICSES, HICDBS, HIWPDS.

Also fixed the HISAL response format: correct account DEG order and added the 7th available-balance field required by the spec.

Tests

  • 39 integration tests (test-mock-bank-v3-integration.ts) covering the full dialog lifecycle, all business transactions, and the high-level PinTanClient API.
  • 5 unit tests for HKPAE serialization.
  • 14 unit tests for HKCSE / HICSE / HICSES parsing and serialization.

Total: 584 tests passing (541 originally + 43 new).

Copilot AI and others added 3 commits April 16, 2026 22:44
Agent-Logs-Url: https://github.com/larsdecker/fints/sessions/8f5a1b48-c3fb-432e-b19f-0737c87474e4

Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
… server and integration tests)

Agent-Logs-Url: https://github.com/larsdecker/fints/sessions/8f5a1b48-c3fb-432e-b19f-0737c87474e4

Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
…tion finding

Agent-Logs-Url: https://github.com/larsdecker/fints/sessions/8f5a1b48-c3fb-432e-b19f-0737c87474e4

Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
Copilot AI requested a review from larsdecker April 16, 2026 23:03
@larsdecker larsdecker marked this pull request as ready for review April 17, 2026 15:06
Copilot AI review requested due to automatic review settings April 17, 2026 15:06
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 27d9cb84c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +587 to +590
await dialog.send(this.createRequest(dialog, segments));
if (shouldInitializeDialog) {
await dialog.end();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Persist new PIN before closing change-PIN flow

After HKPAE succeeds, the method immediately closes the dialog without updating the client/dialog PIN to newPin, so HKEND (and all later requests) are still signed with the old PIN. On banks that apply the PIN change immediately, this causes the close request or the very next API call to fail authentication even though the PIN change itself succeeded.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements missing FinTS 3.0 business transactions (PIN change + scheduled SEPA credit transfer), expands the mock FinTS 3 test server to cover additional operations, and adds extensive integration/unit test coverage.

Changes:

  • Add new FinTS 3.0 segments for PIN change (HKPAE) and scheduled SEPA credit transfer (HKCSE/HICSE/HICSES), plus capability flag wiring.
  • Extend mock bank server sync + business transaction handling (credit transfer, direct debit, scheduled transfer, standing orders, holdings).
  • Add/expand integration and unit tests to exercise the full dialog lifecycle and new features.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
yarn.lock Lockfile updated; now includes workspace file: entries (currently with absolute paths).
packages/fints/src/v4/dialog.ts Add supportsScheduledCreditTransfer (v4 still reports false).
packages/fints/src/types.ts Add scheduled credit transfer request/submission types + capability flag.
packages/fints/src/test-server/test-data.ts Add task ID constant and test MT535 / PAIN.001 builders for mock responses.
packages/fints/src/test-server/mock-bank-server.ts Expand mock server to handle additional FinTS 3 transactions + new sync advertisement.
packages/fints/src/test-server/tests/test-mock-bank-v3-integration.ts Add many integration tests covering the new mock server behaviors and client APIs.
packages/fints/src/segments/index.ts Export newly added segments.
packages/fints/src/segments/hkpae.ts New HKPAE segment (PIN change request) serialization.
packages/fints/src/segments/hkcse.ts New HKCSE segment (scheduled credit transfer request) serialization.
packages/fints/src/segments/hicse.ts New HICSE acknowledgement segment parsing.
packages/fints/src/segments/hicses.ts New HICSES parameter segment parsing.
packages/fints/src/segments/tests/test-hkpae.ts Unit tests for HKPAE serialization.
packages/fints/src/segments/tests/test-hkcse.ts Unit tests for HKCSE serialization and HICSE/HICSES parsing.
packages/fints/src/dialog.ts Add scheduled credit transfer capability detection and expose via capabilities.
packages/fints/src/client.ts Add changePin, scheduledCreditTransfer, and completeScheduledCreditTransfer APIs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +245 to +247
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.003.03`,
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.003.03`,
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.008.003.02`,
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HISPAS sync response encodes each PAIN format as a separate + data group. However, HISPAS.deserialize() only reads the 4th data group for formats, so formats after the first one are silently dropped (e.g. pain.008 won’t be advertised to the client). Pack the supported formats into the expected single DEG (e.g. join formats with : in the 4th field) so response.painFormats contains all advertised PAIN versions.

Suggested change
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.003.03`,
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.003.03`,
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.008.003.02`,
[
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.001.003.03`,
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.002.003.03`,
`urn?:iso?:std?:iso?:20022?:tech?:xsd?:pain.008.003.02`,
].join(":"),

Copilot uses AI. Check for mistakes.
`5000,00:EUR`, // Credit limit
`C:13095,67:EUR:${dateStr}`, // Pre-booked balance
`5000,00:EUR`, // Credit limit (Dispositionskredit)
`C:13095,67:EUR`, // Available balance (Verfügbarer Betrag)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HISAL.deserialize() expects the available-balance data group to contain the numeric amount as its first element. The mock response currently sends C:13095,67:EUR, which parses to ['C','13095,67','EUR'] and results in availableBalance becoming NaN. Send the available balance as an amount element (e.g. 13095,67 or 13095,67:EUR) so parsing yields a valid number.

Suggested change
`C:13095,67:EUR`, // Available balance (Verfügbarer Betrag)
`13095,67:EUR`, // Available balance (Verfügbarer Betrag)

Copilot uses AI. Check for mistakes.
Comment on lines +594 to +599
* Submit a scheduled (future-dated) SEPA credit transfer (Terminüberweisung).
*
* The execution date is encoded inside the pain.001 XML message as
* ReqdExctnDt. The bank must advertise HICSES support during synchronisation;
* otherwise an error is thrown.
*
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSDoc says an error is thrown if the bank does not advertise HICSES support, but scheduledCreditTransfer() does not check dialog.supportsScheduledCreditTransfer (or hicseVersion) before submitting the request. Either add an explicit capability check and throw a clear error, or update the documentation to match the current behavior (letting the server response drive failures).

Copilot uses AI. Check for mistakes.
Comment thread packages/fints/src/dialog.ts Outdated
/**
* Negotiated version for HKCSE (scheduled credit transfer).
*/
public hicseVersion = 1;
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dialog uses hkccsVersion / hkdseVersion naming for the negotiated request-segment versions, but the new scheduled-transfer version is named hicseVersion even though it’s used as the HKCSE request version (derived from HICSES). For consistency and to avoid confusion with the response segment HICSE, consider renaming this to hkcseVersion (and updating call sites) or otherwise aligning the name with the existing pattern.

Suggested change
public hicseVersion = 1;
public hkcseVersion = 1;

Copilot uses AI. Check for mistakes.
@larsdecker
Copy link
Copy Markdown
Owner

@copilot apply changes based on the comments in this thread

Please let also a eslint and prettier run before you commit your changes.

…e, hkcseVersion rename, capability check, eslint/prettier

Agent-Logs-Url: https://github.com/larsdecker/fints/sessions/3836d525-d5c2-475f-9fd5-afc9ab8ffdfb

Co-authored-by: larsdecker <1968186+larsdecker@users.noreply.github.com>
Copy link
Copy Markdown
Author

Copilot AI commented Apr 21, 2026

@copilot apply changes based on the comments in this thread

Please let also a eslint and prettier run before you commit y...

All four review points have been addressed in commit d347c65:

  1. HISPAS formats — all three PAIN formats are now packed into the 4th DEG joined with : so response.painFormats correctly returns all of them.
  2. HISAL available balance — changed from C:13095,67:EUR to 13095,67:EUR so Parse.num produces a valid number instead of NaN.
  3. hkcseVersion renamehicseVersionhkcseVersion across dialog.ts, client.ts, and the integration test for consistency with hkccsVersion/hkdseVersion.
  4. Capability checkscheduledCreditTransfer() now throws early with a clear message if dialog.supportsScheduledCreditTransfer is false, and a new test covers that error path.

ESLint (0 errors) and Prettier were run on all changed files before committing.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants