Skip to main content
Sepa JS XML supports eight PAIN (Payment Initiation) format versions. This guide helps you choose the right version for your needs.

Supported versions

From the source code (index.ts:109-117), these are all supported versions:
export type PAIN_VERSIONS =
  | "pain.001.001.02"  // Credit Transfer v02
  | "pain.001.003.02"  // Credit Transfer v02 (variant)
  | "pain.001.001.03"  // Credit Transfer v03
  | "pain.001.003.03"  // Credit Transfer v03 (variant)
  | "pain.008.001.01"  // Direct Debit v01
  | "pain.008.003.01"  // Direct Debit v01 (variant)
  | "pain.008.001.02"  // Direct Debit v02
  | "pain.008.003.02"; // Direct Debit v02 (variant)

Version structure

PAIN versions follow this pattern: pain.XXX.YYY.ZZ
1

XXX - Message type

  • 001 = Credit Transfer (SCT)
  • 008 = Direct Debit (SDD)
2

YYY - Variant

  • 001 = Standard variant
  • 003 = Alternative variant (usually identical)
3

ZZ - Version number

  • 01 = Version 1 (older)
  • 02 = Version 2 (older)
  • 03 = Version 3 (current SEPA standard)

Credit transfer versions

pain.001.001.02

Older credit transfer format, still widely supported.
painVersion: "pain.001.001.02"

pain.001.003.02

Identical to pain.001.001.02 with a different variant number. From the source code (index.ts:100), both map to the same type.
Current SEPA credit transfer standard.
painVersion: "pain.001.001.03"

pain.001.003.03

Identical to pain.001.001.03 with a different variant number. From the source code (index.ts:102), both map to CstmrCdtTrfInitn.

Direct debit versions

pain.008.001.01

Older direct debit format.
painVersion: "pain.008.001.01"

pain.008.003.01

Identical to pain.008.001.01 with a different variant number.
Current SEPA direct debit standard.
painVersion: "pain.008.001.02"

pain.008.003.02

Identical to pain.008.001.02 with a different variant number. From the source code (index.ts:106), both map to CstmrDrctDbtInitn.

Key differences between versions

Version 02 vs Version 03

Version 02: BIC is required for both partiesVersion 03: BIC is optional (from index.ts:225-230, index.ts:293-295, index.ts:381-383)
// Version 03 - BIC optional
positions: [{
  iban: "DE02701500000000594937",
  // bic field is optional
}]
Version 02: OptionalVersion 03: Required (from index.ts:337-341)
// Version 03 - Required
payments: [{
  end2endReference: "REF123" // Must be provided
}]
Version 02: At document level via SepaData.batchBooking (from index.ts:173-177)Version 03: At position level via CreditorPayments.batchBooking (from index.ts:238-244)
// Version 02
const xml = createSepaXML({
  painVersion: "pain.001.001.02",
  batchBooking: true, // Document level
  positions: [/* ... */]
});

// Version 03
const xml = createSepaXML({
  painVersion: "pain.001.001.03",
  positions: [{
    batchBooking: false, // Position level
    payments: [/* ... */]
  }]
});
Version 02: Only at document levelVersion 03: Both document and position level (from index.ts:238-244)Version 03 includes NbOfTxs and CtrlSum at both levels for better tracking.
Version 02: Uses format-specific root element (pain.001.001.02)Version 03: Uses standard SEPA element names (CstmrCdtTrfInitn, CstmrDrctDbtInitn)

Version detection

From the source code (index.ts:142-146), the library automatically detects the version number:
const painVersion =
  parseInt(
    painFormat.substring(painFormat.length, painFormat.length - 2),
    10,
  ) + (painFormat.indexOf("pain.008") === 0 ? 1 : 0);
This determines whether version-specific features are enabled:
  • Version 2 (02) → Legacy features
  • Version 3 (03) → Modern SEPA features

Default version

From the source code (index.ts:126), the default is:
const PAIN_VERSION = "pain.001.001.03";
If you don’t specify painVersion, credit transfer version 03 is used.

Choosing the right version

1

Check bank requirements

Contact your bank to see which versions they accept. Most modern banks support version 03.
2

Use version 03 for new projects

Unless you have specific requirements, use:
  • pain.001.001.03 for credit transfers
  • pain.008.001.02 for direct debits
3

Consider BIC availability

If you don’t have BIC codes, you must use version 03:
  • Version 02: BIC required
  • Version 03: BIC optional
4

Check for end-to-end references

If you can’t provide end-to-end references, use version 02:
  • Version 02: Not required
  • Version 03: Required

Migration guide

From version 02 to 03

const xml = createSepaXML({
  painVersion: "pain.001.001.02",
  batchBooking: true, // Document level
  id: "MSG001",
  creationDate: new Date(),
  initiatorName: "Company",
  positions: [{
    id: "PMT001",
    name: "Company",
    iban: "DE02701500000000594937",
    bic: "SSKMDEMM", // Required
    requestedExecutionDate: new Date(),
    payments: [{
      id: "TXN001",
      name: "Recipient",
      iban: "DE89370400440532013000",
      bic: "COBADEFFXXX", // Required
      amount: 100.00,
      remittanceInformation: "Payment"
      // No end2endReference needed
    }]
  }]
});

Version comparison table

Featurepain.001.001.02/03.02pain.001.001.03/03.03pain.008.001.01/03.01pain.008.001.02/03.02
TypeCredit TransferCredit TransferDirect DebitDirect Debit
BIC RequiredYesNoNo (creditor)No (creditor)
End-to-end RefOptionalRequiredN/AN/A
Batch BookingDocument levelPosition levelDocument levelPosition level
Root Elementpain.001.001.02CstmrCdtTrfInitnpain.008.001.01CstmrDrctDbtInitn
StatusOlderCurrentOlderCurrent

Next steps

Credit transfers

Learn how to create credit transfers

Direct debits

Learn how to create direct debits

Validation

Understand validation for each version

Examples

See examples using different versions

Build docs developers (and LLMs) love