This guide walks you through creating a SEPA credit transfer XML file from scratch.
Prerequisites
Before you begin, make sure you have:
Node.js installed (v14 or higher recommended)
A JavaScript or TypeScript project set up
Sepa JS XML installed (see Installation )
Generate a credit transfer XML
Follow these steps to create your first SEPA credit transfer XML file:
Import the library
Start by importing the createSepaXML function from the package: import { createSepaXML , type SepaData } from 'sepa-js-xml' ;
Prepare your payment data
Create a data object with your payment information. Here’s a complete example: const paymentData : SepaData = {
id: "MSG-001" ,
creationDate: new Date (),
initiatorName: "Your Company Name" ,
positions: [
{
id: "BATCH-001" ,
name: "Your Company Name" ,
iban: "DE89370400440532013000" ,
bic: "COBADEFFXXX" ,
requestedExecutionDate: new Date (),
payments: [
{
id: "PAYMENT-001" ,
name: "John Doe" ,
iban: "DE89370400440532013001" ,
bic: "COBADEFFXXX" ,
amount: 150.50 ,
remittanceInformation: "Invoice #12345" ,
end2endReference: "INV-12345"
},
{
id: "PAYMENT-002" ,
name: "Jane Smith" ,
iban: "DE89370400440532013002" ,
bic: "COBADEFFXXX" ,
amount: 250.00 ,
remittanceInformation: "Invoice #12346" ,
end2endReference: "INV-12346"
}
]
}
]
};
The IBANs and BICs in this example are for demonstration only. Replace them with valid account details before generating production files.
Generate the XML
Call the createSepaXML function with your payment data: const xml = createSepaXML ( paymentData );
console . log ( xml );
For better readability during development, you can enable pretty printing: const xml = createSepaXML ( paymentData , {
prettyPrint: true ,
checkIBAN: true ,
checkBIC: true
});
Save the XML file
Write the generated XML to a file: import { writeFileSync } from 'fs' ;
writeFileSync ( 'sepa-payment.xml' , xml , 'utf-8' );
console . log ( 'SEPA XML file generated successfully!' );
Complete example
Here’s a complete working example that generates a SEPA credit transfer XML file:
import { createSepaXML , type SepaData } from 'sepa-js-xml' ;
import { writeFileSync } from 'fs' ;
const paymentData : SepaData = {
id: "MSG-001" ,
creationDate: new Date (),
initiatorName: "Your Company Name" ,
positions: [
{
id: "BATCH-001" ,
name: "Your Company Name" ,
iban: "DE89370400440532013000" ,
bic: "COBADEFFXXX" ,
requestedExecutionDate: new Date (),
payments: [
{
id: "PAYMENT-001" ,
name: "John Doe" ,
iban: "DE89370400440532013001" ,
bic: "COBADEFFXXX" ,
amount: 150.50 ,
remittanceInformation: "Invoice #12345" ,
end2endReference: "INV-12345"
},
{
id: "PAYMENT-002" ,
name: "Jane Smith" ,
iban: "DE89370400440532013002" ,
bic: "COBADEFFXXX" ,
amount: 250.00 ,
remittanceInformation: "Invoice #12346" ,
end2endReference: "INV-12346"
}
]
}
]
};
try {
const xml = createSepaXML ( paymentData , {
prettyPrint: true ,
checkIBAN: true ,
checkBIC: true
});
writeFileSync ( 'sepa-payment.xml' , xml , 'utf-8' );
console . log ( 'SEPA XML file generated successfully!' );
} catch ( error ) {
console . error ( 'Error generating SEPA XML:' , error . message );
}
Configuration options
You can customize the XML generation with these options:
Option Type Default Description prettyPrintbooleanfalseFormat the XML with indentation for readability checkIBANbooleantrueValidate IBAN codes using ibantools checkBICbooleantrueValidate BIC codes using ibantools
const xml = createSepaXML ( paymentData , {
prettyPrint: true , // Enable formatted output
checkIBAN: true , // Validate IBANs (recommended)
checkBIC: true // Validate BICs (recommended)
});
It’s recommended to keep IBAN and BIC validation enabled in production to catch invalid account details before submitting payments to your bank.
Understanding the data structure
The SepaData interface has three main levels:
1. Message level (SepaData)
{
id : "MSG-001" , // Message ID (max 35 chars)
creationDate : new Date (), // When the message was created
initiatorName : "Your Company" , // Your company name (max 70 chars)
painVersion : "pain.001.001.03" , // Optional: PAIN format version
positions : [ ... ] // Array of creditor positions
}
2. Position level (CreditorPayments)
{
id : "BATCH-001" , // Position ID (max 35 chars)
name : "Your Company Name" , // Debtor name (max 70 chars)
iban : "DE89370400440532013000" , // Debtor IBAN
bic : "COBADEFFXXX" , // Debtor BIC (optional in some versions)
requestedExecutionDate : new Date (), // When to execute the payment
batchBooking : true , // Optional: batch booking flag
payments : [ ... ] // Array of individual payments
}
3. Payment level (Payment)
{
id : "PAYMENT-001" , // Payment ID (max 35 chars)
name : "John Doe" , // Creditor name (max 70 chars)
iban : "DE89370400440532013001" , // Creditor IBAN
bic : "COBADEFFXXX" , // Creditor BIC (optional in some versions)
amount : 150.50 , // Amount in EUR
currency : "EUR" , // Optional: defaults to EUR
remittanceInformation : "Invoice #12345" , // Payment reference
end2endReference : "INV-12345" // End-to-end reference (required in pain.001.001.03)
}
Validation and error handling
The library performs automatic validation and throws errors if:
The id or initiatorName exceeds the maximum length
IBAN or BIC codes are invalid (when validation is enabled)
Required fields are missing for specific PAIN versions
Always wrap createSepaXML calls in a try-catch block:
try {
const xml = createSepaXML ( paymentData );
} catch ( error ) {
if ( error . message . includes ( 'Max length' )) {
console . error ( 'Field length validation failed:' , error . message );
} else if ( error . message . includes ( 'not valid' )) {
console . error ( 'IBAN/BIC validation failed:' , error . message );
} else {
console . error ( 'Unexpected error:' , error . message );
}
}
Next steps
Now that you’ve generated your first SEPA XML file, explore more advanced features:
API Reference View detailed API documentation and type signatures
Direct Debits Learn how to create SEPA direct debit XML files