Skip to content

API surface

ExportDescription
CreditTransferDocumentRoot document type for pain.001
PaymentBatchA single PmtInf block: one debtor, one execution date, many transfers
TransferA single credit transfer transaction (CdtTrfTxInf)
AccountParty{ name: string, iban: string, bic?: string }
Money{ currencyCode: 'EUR', minorUnits: bigint }
ExportDescription
DirectDebitDocumentRoot document type for pain.008
CreditorDocument-level creditor with creditorId (SEPA Creditor Identifier)
DirectDebitBatchA single PmtInf block: collection date, sequence type, many collections
CollectionA single direct debit transaction (DrctDbtTxInf)
Mandate{ id: string, signatureDate: string }
SequenceType'FRST' | 'RCUR' | 'OOFF' | 'FNAL'
LocalInstrument'CORE' | 'B2B'
ExportDescription
CreditTransferDocumentSchemaFull Zod schema for CreditTransferDocument
DirectDebitDocumentSchemaFull Zod schema for DirectDebitDocument
ExportSignatureDescription
euros(amount: string): MoneyBuild a Money value from a decimal string
formatMoney(m: Money): stringFormat to "123.45" (2 decimals, dot, no grouping)
ExportSignatureDescription
writeCreditTransfer(model: CreditTransferDocument, options?: WriteCreditTransferOptions): stringWrite a pain.001 XML string
writeDirectDebit(model: DirectDebitDocument, options?: WriteDirectDebitOptions): stringWrite a pain.008 XML string

Both writers validate the model internally and throw a ValidationError if validation fails.

ExportSignatureDescription
parse(xml: string): ParseResultParse SEPA XML to model, auto-detecting message type

ParseResult is a discriminated union:

type ParseResult =
| { ok: true; type: 'pain.001'; data: CreditTransferDocument }
| { ok: true; type: 'pain.008'; data: DirectDebitDocument }
| { ok: false; error: string }
ExportSignatureDescription
validate(input: unknown): ValidationResult<CreditTransferDocument>Validate a credit-transfer model
validateCreditTransfer(input: unknown, options?: { profile?: BankProfile }): ValidationResult<CreditTransferDocument>Validate with optional bank profile
validateDirectDebit(input: unknown, options?: { profile?: BankProfile }): ValidationResult<DirectDebitDocument>Validate a direct-debit model with optional bank profile

ValidationResult shape:

type ValidationResult<T> =
| { ok: true; data: T }
| { ok: false; errors: ZodIssue[]; profileIssues?: ProfileIssue[] }
ExportDescription
BankProfileInterface for custom bank profiles
ProfileIssue{ path: string, message: string }
requireBicBuilt-in profile: rejects documents where any account is missing a BIC
ExportDescription
WriteCreditTransferOptions{ variant?: CreditTransferVariant, profile?: BankProfile }
WriteDirectDebitOptions{ variant?: DirectDebitVariant, profile?: BankProfile }
CreditTransferVariant'pain.001.001.09' | 'pain.001.003.03'
DirectDebitVariant'pain.008.001.08' | 'pain.008.003.02'

ExportSignatureDescription
validateXsd(xml: string): Promise<XsdResult>Validate XML against the official EPC XSD

XsdResult shape:

type XsdResult =
| { valid: true }
| { valid: false; errors: string[] }

validateXsd auto-detects the message type and namespace. It covers all seven supported schemas. Lazy-loads libxml2-wasm on first call.


The following are intentionally internal and not part of the public API:

  • IBAN mod-97 validation
  • SEPA charset EPC217-08 transliteration
  • XML escaper
  • Raw creditor-id helpers (the public surface is isValidCreditorId and buildCreditorId)

If you need IBAN validation or SEPA charset filtering in your own code, use a dedicated library for those concerns rather than depending on internals that may change.