Skip to main content

Function signature

function createSepaXML(
  sepaData: SepaData,
  options?: Options
): string
Generate a SEPA XML file compliant with various PAIN formats. The function validates data length constraints and optionally validates IBAN and BIC codes.

Parameters

sepaData
SepaData
required
The SEPA payment data containing all transaction information.
options
Options
Configuration options for XML generation and validation.

Return value

string
string
The generated SEPA XML document as a string.

Examples

Basic credit transfer

import { createSepaXML } from 'sepa-js-xml';

const xml = createSepaXML({
  painVersion: "pain.001.001.02",
  id: "1",
  creationDate: new Date("2022-06-16"),
  initiatorName: "Test Company",
  positions: [
    {
      name: "Test",
      iban: "DE02701500000000594937",
      bic: "SSKMDEMM",
      requestedExecutionDate: new Date("2022-06-16"),
      id: "123",
      payments: [
        {
          id: "Payment 1",
          amount: 123,
          iban: "DE02701500000000594937",
          bic: "SSKMDEMM",
          name: "Recipient Name",
          remittanceInformation: "Invoice 12345",
        },
      ],
    },
  ],
});

Multiple payments with custom currency

const xml = createSepaXML({
  painVersion: "pain.001.001.02",
  id: "1",
  creationDate: new Date("2022-06-16"),
  initiatorName: "Test Company",
  positions: [
    {
      name: "Debtor Account",
      iban: "DE02701500000000594937",
      bic: "SSKMDEMM",
      requestedExecutionDate: new Date("2022-06-16"),
      id: "123",
      payments: [
        {
          id: "Payment 1",
          amount: 123,
          iban: "DE02701500000000594937",
          bic: "SSKMDEMM",
          name: "Recipient 1",
          remittanceInformation: "Invoice 001",
          currency: "USD",
        },
        {
          id: "Payment 2",
          amount: 123.83,
          iban: "DE02701500000000594937",
          bic: "SSKMDEMM",
          name: "Recipient 2",
          remittanceInformation: "Invoice 002",
          currency: "USD",
        },
      ],
    },
  ],
});

Credit transfer with end-to-end reference (pain.001.001.03)

const xml = createSepaXML(
  {
    painVersion: "pain.001.001.03",
    id: "Test1345",
    creationDate: new Date("2022-06-16"),
    initiatorName: "Test Company",
    positions: [
      {
        id: "Test123",
        batchBooking: false,
        iban: "DE02701500000000594937",
        bic: "SSKMDEMM",
        requestedExecutionDate: new Date("2022-06-16"),
        name: "Debtor Name",
        payments: [
          {
            id: "123",
            amount: 230,
            currency: "EUR",
            bic: "SSKMDEMM",
            name: "Creditor Company",
            iban: "DE02701500000000594937",
            remittanceInformation: "Invoice payment",
            end2endReference: "E2E-REF-001",
          },
        ],
      },
    ],
  }
);

Credit transfer without BIC (optional in pain.001.001.03)

const xml = createSepaXML(
  {
    painVersion: "pain.001.001.03",
    id: "Test1345",
    creationDate: new Date("2022-06-16"),
    initiatorName: "Test Company",
    positions: [
      {
        id: "Test123",
        batchBooking: false,
        iban: "DE02701500000000594937",
        requestedExecutionDate: new Date("2022-06-16"),
        name: "Debtor Name",
        payments: [
          {
            id: "123",
            amount: 230,
            currency: "EUR",
            name: "Creditor Company",
            iban: "DE02701500000000594937",
            remittanceInformation: "Invoice payment",
            end2endReference: "E2E-REF-001",
          },
        ],
      },
    ],
  },
  {
    checkIBAN: true,
    checkBIC: true,
  }
);

Pretty printed XML output

const xml = createSepaXML(
  {
    painVersion: "pain.001.001.03",
    id: "MSG-001",
    creationDate: new Date("2022-06-16"),
    initiatorName: "My Company",
    positions: [
      {
        id: "PMT-001",
        iban: "DE02701500000000594937",
        bic: "SSKMDEMM",
        requestedExecutionDate: new Date("2022-06-20"),
        name: "My Company Account",
        payments: [
          {
            id: "TXN-001",
            amount: 100.50,
            name: "Supplier Inc",
            iban: "DE02701500000000594937",
            bic: "SSKMDEMM",
            remittanceInformation: "Payment for services",
            end2endReference: "INV-2022-001",
          },
        ],
      },
    ],
  },
  {
    prettyPrint: true,
    checkIBAN: true,
    checkBIC: true,
  }
);

Disabling validation

const xml = createSepaXML(
  {
    painVersion: "pain.001.001.03",
    id: "Test1345",
    creationDate: new Date("2022-06-16"),
    initiatorName: "Test Company",
    positions: [
      {
        id: "Test123",
        batchBooking: false,
        iban: "DE02701500000000594937",
        bic: "TESTBIC",
        requestedExecutionDate: new Date("2022-06-16"),
        name: "Pos 1",
        payments: [
          {
            id: "123",
            amount: 230,
            currency: "EUR",
            bic: "TESTBIC",
            name: "Money Company",
            iban: "DE02701500000000594937",
            remittanceInformation: "Money please",
            end2endReference: "lol",
          },
        ],
      },
    ],
  },
  {
    checkIBAN: false,
    checkBIC: false,
  }
);

Error handling

The function throws errors in the following cases:

Length validation errors

try {
  createSepaXML({
    id: "123456789123456789123456789123456789", // Too long (max 35)
    creationDate: new Date(),
    initiatorName: "Test",
    positions: [],
  });
} catch (error) {
  // Error: Max length for sepaData.id is 35 (123456789123456789123456789123456789)
}

IBAN validation errors

try {
  createSepaXML({
    id: "Test",
    creationDate: new Date(),
    initiatorName: "Test",
    positions: [
      {
        name: "Test",
        iban: "InvalidIBAN",
        bic: "SSKMDEMM",
        id: "123",
        payments: [],
        requestedExecutionDate: new Date(),
      },
    ],
  });
} catch (error) {
  // Error: sepaData.positions[0].iban is not valid (InvalidIBAN)
}

BIC validation errors

try {
  createSepaXML({
    id: "Test",
    creationDate: new Date(),
    initiatorName: "Test",
    positions: [
      {
        name: "Test",
        iban: "DE02701500000000594937",
        bic: "InvalidBIC",
        id: "123",
        payments: [],
        requestedExecutionDate: new Date(),
      },
    ],
  });
} catch (error) {
  // Error: sepaData.positions[0].bic is not valid (InvalidBIC)
}

Notes

  • The function automatically calculates NbOfTxs (number of transactions) and CtrlSum (control sum) based on the provided payments
  • BIC is optional for SEPA Credit Transfers (pain.001.001.03 and pain.001.003.03) and SEPA Direct Debits on the creditor side
  • The end2endReference field is required when using pain.001.001.03 format
  • All IBAN and BIC validations use the ibantools library
  • Date fields are automatically formatted to ISO 8601 format as required by SEPA standards

Build docs developers (and LLMs) love