National variants
Some countries use national extensions of the SEPA ISO 20022 schemas under different XML namespaces. These are distinct from bank profiles: a profile is additive on top of a given schema, while a national variant is a different XML schema with its own namespace, element ordering, and element names.
sepa-xml-ts supports the German DK (DFU agreement Anlage 3) variants:
| Variant | Schema | Namespace |
|---|---|---|
pain.001.003.03 | German DK Credit Transfer | urn:iso:std:iso:20022:tech:xsd:pain.001.003.03 |
pain.008.003.02 | German DK Direct Debit | urn:iso:std:iso:20022:tech:xsd:pain.008.003.02 |
Both ship with their official XSD (vendored in the package) and are verified against it in CI.
German DK credit transfer: pain.001.003.03
Section titled “German DK credit transfer: pain.001.003.03”The model input is the same CreditTransferDocument as for pain.001.001.09. Pass
{ variant: 'pain.001.003.03' } to emit and validate against the DK schema.
import { writeCreditTransfer, type CreditTransferDocument } from 'sepa-xml-ts'import { validateXsd } from 'sepa-xml-ts/xsd'
const xml = writeCreditTransfer(doc, { variant: 'pain.001.003.03' })// <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.003.03">...
const xsdResult = await validateXsd(xml)console.log(xsdResult.valid) // true -- validates against the DK XSDStructural differences from pain.001.001.09
Section titled “Structural differences from pain.001.001.09”| Element | pain.001.001.09 | pain.001.003.03 |
|---|---|---|
ReqdExctnDt | <ReqdExctnDt><Dt>YYYY-MM-DD</Dt></ReqdExctnDt> | <ReqdExctnDt>YYYY-MM-DD</ReqdExctnDt> |
| Financial institution ID | <BICFI> element | <BIC> element |
DbtrAgt when no BIC | Omitted | Required: <Othr><Id>NOTPROVIDED</Id></Othr> |
CdtrAgt when no BIC | Empty placeholder | Omitted |
The NOTPROVIDED fallback in DbtrAgt is the only allowed placeholder in the DK XSD when the
debtor’s BIC is unknown. The writer handles this automatically.
Parsing pain.001.003.03
Section titled “Parsing pain.001.003.03”parse() auto-detects the namespace and reads a DK credit transfer file into a
CreditTransferDocument. The returned parsed.type is 'pain.001' in both cases.
import { parse } from 'sepa-xml-ts'
const parsed = parse(dkXml)// parsed.type === 'pain.001'// parsed.data is a CreditTransferDocumentGerman DK direct debit: pain.008.003.02
Section titled “German DK direct debit: pain.008.003.02”The model input is the same DirectDebitDocument as for pain.008.001.08. Pass
{ variant: 'pain.008.003.02' } to emit and validate against the DK SDD schema.
import { writeDirectDebit } from 'sepa-xml-ts'import { validateXsd } from 'sepa-xml-ts/xsd'
const xml = writeDirectDebit(doc, { variant: 'pain.008.003.02' })// <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.003.02">...
const xsdResult = await validateXsd(xml)console.log(xsdResult.valid) // trueStructural differences from pain.008.001.08
Section titled “Structural differences from pain.008.001.08”| Element | pain.008.001.08 | pain.008.003.02 |
|---|---|---|
| Financial institution ID | <BICFI> element | <BIC> element |
CdtrAgt when no BIC | Empty placeholder | <Othr><Id>NOTPROVIDED</Id></Othr> |
DbtrAgt when no BIC | Empty placeholder | <Othr><Id>NOTPROVIDED</Id></Othr> |
GrpHdr/CtrlSum | Required | Omitted (optional in DK XSD) |
Parsing pain.008.003.02
Section titled “Parsing pain.008.003.02”parse() reads a DK direct debit file into a DirectDebitDocument. The returned parsed.type
is 'pain.008' in both cases.
Legacy ISO format: pain.001.001.03
Section titled “Legacy ISO format: pain.001.001.03”pain.001.001.03 is not a national variant, it is the older ISO 20022 credit transfer format
(pre-2014 EPC). It is exposed through the same variant option for systems that still require
.03 on the wire (for example an existing bank integration that has not moved to .09).
import { writeCreditTransfer } from 'sepa-xml-ts'
const xml = writeCreditTransfer(doc, { variant: 'pain.001.001.03' })// <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03">...The model input is the same CreditTransferDocument as for .09. Structural differences from
pain.001.001.09: a plain ReqdExctnDt element (no Dt wrapper), the BIC element instead of
BICFI, and a debtor FinInstnId that is emitted (empty when no BIC is set). The output is
verified against the official schemas/iso20022/pain.001.001.03.xsd and round-trips through
parse(). By default writeCreditTransfer still emits the modern pain.001.001.09.
Combining variant and profile
Section titled “Combining variant and profile”The variant and profile options are independent and work together:
import { writeCreditTransfer, requireBic } from 'sepa-xml-ts'
const xml = writeCreditTransfer(doc, { variant: 'pain.001.003.03', profile: requireBic,})The profile check runs against the validated model. The variant controls the serialization.
What is NOT supported
Section titled “What is NOT supported”- National variants for countries other than Germany are not currently shipped. Adding a new variant requires the official XSD and golden test samples as verification oracles.
- German DK variants for pain.002 (status reports) and camt.* messages are out of scope.