Skip to content

ISO 20022 message

pain.008 format: customer direct debit initiation

pain.008 is the ISO 20022 file a creditor sends its bank to collect direct debits: one or more payment blocks (one per collection date, sequence type and scheme) with the debits inside, each with the mandate that authorises it. In the euro area it carries SEPA Core and SEPA B2B collections.

pain.008 at a glance
Messagepain.008, root element <CstmrDrctDbtInitn>
NameCustomer direct debit initiation
SentCreditor → bank
SWIFT MT counterpartMT104
Read byPayment File Viewer

Who sends it, and when

The creditor uploads it to its bank ahead of the collection date, within the bank’s and the scheme’s deadlines. The bank answers with pain.002 reports; the collected amounts arrive on the camt.053 (often as one credit per block, detailed in a camt.054), and debits that fail come back later as returns with a reason code.

The structure of a pain.008

pain.008 · structure
Document
└─ CstmrDrctDbtInitn
   ├─ GrpHdr               MsgId, CreDtTm, NbOfTxs, CtrlSum, InitgPty
   └─ PmtInf               a block: one date, sequence type and scheme
      ├─ PmtInfId, PmtMtd (DD), BtchBookg, NbOfTxs, CtrlSum
      ├─ PmtTpInf          SvcLvl SEPA, LclInstrm CORE or B2B, SeqTp FRST/RCUR/OOFF/FNAL
      ├─ ReqdColltnDt, Cdtr, CdtrAcct, CdtrAgt, ChrgBr
      ├─ CdtrSchmeId       the SEPA creditor identifier
      └─ DrctDbtTxInf      one per debit
         ├─ PmtId/EndToEndId, InstdAmt
         ├─ DrctDbtTx/MndtRltdInf   MndtId, DtOfSgntr
         └─ DbtrAgt, Dbtr, DbtrAcct, RmtInf

Versions in use

Version .001.02 (2009) is still widely used; .001.08 (2019) is the version the EPC’s SEPA guidelines have been based on since March 2024, when creditors could keep their existing files. The viewer reads .001.02 to .001.13.

An annotated pain.008

An excerpt of the sample the viewer opens (fictitious companies, published test account numbers):

pain008-sepa-core.xml
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02">
  <CstmrDrctDbtInitn>
    …
    <PmtInf>
      <PmtInfId>DD-RCUR-20261029</PmtInfId>
      <PmtMtd>DD</PmtMtd>
      …
      <PmtTpInf>
        <SvcLvl>
          <Cd>SEPA</Cd>
        </SvcLvl>
        <LclInstrm>
          <Cd>CORE</Cd>
        </LclInstrm>
        <SeqTp>RCUR</SeqTp>
      </PmtTpInf>
      …
      <CdtrSchmeId>
        <Id>
          <PrvtId>
            <Othr>
              <Id>DE98ZZZ09999999999</Id>
              …
      <DrctDbtTxInf>
        <PmtId>
          <EndToEndId>NW-SUB-1001-2610</EndToEndId>
        </PmtId>
        <InstdAmt Ccy="EUR">119.90</InstdAmt>
        <DrctDbtTx>
          <MndtRltdInf>
            <MndtId>NW-M-1001</MndtId>
            <DtOfSgntr>2025-03-14</DtOfSgntr>
          </MndtRltdInf>
        </DrctDbtTx>
        …

“…” marks lines left out.

pain.008 sample, explained
In the fileWhat it says
<LclInstrm><Cd>COREThe SEPA Core scheme (B2B for business-to-business).
<SeqTp>RCURA recurring collection under an existing mandate (FRST first, OOFF one-off, FNAL final).
DE98ZZZ09999999999The creditor identifier (a published test id): it tells debtors’ banks who is collecting.
<MndtId> / <DtOfSgntr>The mandate reference and the date it was signed.

Open this sample in the Payment File Viewer

Common validation errors

What most often goes wrong in a pain.008, and the rule that reports it in the viewer and the API:

  • sepa.creditor-id (SEPA creditor identifier missing): No SEPA creditor identifier on the block or the transaction.
  • sepa.mandate (SEPA mandate data missing): A debit without a mandate reference or signature date.
  • sepa.sequence-type (SEPA sequence type missing): No sequence type (FRST, RCUR, OOFF, FNAL).
  • pain.sum.payment (Payment information control sum differs): A block’s CtrlSum differs from its amounts.
  • iban.invalid (Invalid IBAN): A debtor IBAN that fails its check digits.

Check a pain.008 from a script or an AI agent

Scripts and AI agents can do the same without a browser: POST /api/v1/validate or the MCP tool validate_payment_file returns every issue with its rule id, severity, line and path, and whether the file is valid. No key is needed, and the file is processed in memory and never stored (API and MCP docs).

REST · curl
curl -s --data-binary @pain008-sepa-core.xml https://iso20022-navigator.com/api/v1/validate
MCP · tools/call
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "validate_payment_file",
    "arguments": {
      "content": "<the file text>"
    }
  }
}