Add opt-in SEPA Instant (SCT Inst / Echtzeitüberweisung) support to credit transfers#81
Open
wolframarnold wants to merge 1 commit into
Open
Add opt-in SEPA Instant (SCT Inst / Echtzeitüberweisung) support to credit transfers#81wolframarnold wants to merge 1 commit into
wolframarnold wants to merge 1 commit into
Conversation
…ransfers Under the EU Instant Payments Regulation (2024/886) euro-area PSPs must offer instant credit transfers at price parity with standard ones, so users increasingly need to flag a SEPA batch as instant. The EPC/DK mechanism is PmtTpInf/LclInstrm/Cd=INST, which sepaxml could emit for direct debits but not for credit transfers. - transfer.py: when config['instant'] is set, emit <LclInstrm><Cd>INST</Cd></LclInstrm> directly after SvcLvl inside PmtTpInf, preserving the ISO 20022 PaymentTypeInformation sequence (InstrPrty?, SvcLvl?, LclInstrm?, CtgyPurp?). Mirrors the existing SepaDD precedent, which already sets LclInstrm/Cd from config['instrument']. Gated inside the existing non-domestic (SEPA) guard, since INST is a SEPA local instrument. - The flag is config-level, not per-payment: PmtTpInf is a payment-information-block element shared by all grouped transfers, so a per-payment flag is ambiguous for mixed batches. - tests/transfer/test_instant.py: INST present directly after SvcLvl (batch and non-batch), XSD-valid, and absent without the flag. - README: document the config['instant'] flag next to 'domestic'.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds opt-in SEPA Instant Credit Transfer (SCT Inst / Echtzeitüberweisung) support to
SepaTransfer. When the config carries"instant": True, the generatedpain.001emitsPmtTpInf/LclInstrm/Cd = INST— the EPC/DK mechanism for requesting an instant transfer — positioned directly afterSvcLvl, per the ISO 20022PaymentTypeInformationsequence (InstrPrty?, SvcLvl?, LclInstrm?, CtgyPurp?).Why
Under the EU Instant Payments Regulation (2024/886), euro-area PSPs must offer instant credit transfers at price parity with standard ones, so requesting INST is becoming a routine need.
sepaxmlalready emitsLclInstrm/Cdfor direct debits but had no way to do so for credit transfers. (Downstream, e.g.python-fintspinssepaxml==2.7.*for its SEPA payloads.)Design
PmtTpInfis a payment-information-block element shared by all grouped transfers; a per-payment flag on a block-level node is ambiguous for mixed batches. (This is the flaw visible in prior-art Add structured reference and instant payment support #71's per-payment approach.)debit.pyalready setsLclInstrm/Cdfromself._config['instrument'](CORE/B2B); this is the symmetric credit-transfer counterpart.domesticguard, since INST is a SEPA local instrument — adomestictransfer has noSvcLvl=SEPA/PmtTpInfblock to attach it to.Tests
tests/transfer/test_instant.pyasserts INST is present directly afterSvcLvl(batch and non-batch paths), XSD-valid, and absent without the flag. Verified XSD-valid across all four supported pain.001 schemas (03/09/10/11). No existing tests change.Real-world verification
The exact XML this change produces (
<PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl><LclInstrm><Cd>INST</Cd></LclInstrm></PmtTpInf>on apain.001.001.03batch,batch=True) was verified end-to-end against a live German bank on 2026-07-16, using two €0.01 transfers between real accounts at two different institutions:LclInstrmwas sent the same day. The receiving bank (Taunus Sparkasse) booked the flagged transfer as ECHTZEIT-GUTSCHRIFT (SEPA Instant credit) and the unflagged one as ONLINE-UEBERWEISUNG (standard SCT) — confirming the element alone switches the scheme, cross-bank, and is not silently downgraded.(The verification was done by injecting this element into sepaxml 2.7.0 output and re-validating against the bundled
pain.001.001.03.xsd— i.e., precisely the XML shape this PR generates natively.)Prior art
#71 established the same element and position (good corroboration), but bundled it with a per-payment API, structured references, six new XSDs, and a whole-file reformat (~9.4k additions across 24 files) and was self-closed unreviewed. This PR is the minimal form: one feature, ~13 lines in
transfer.py, one new test file, one README line — no reformatting, no new schemas.