pain.008 XML genereren: structuur, mapping en validatie
2026-05-05
De maandelijkse incassorun staat klaar. Het boekhoudpakket heeft een export gemaakt, iemand heeft er “iets XML-achtigs” van gemaakt en de bank meldt: Schema validation failed. Niemand weet welke regel het probleem is.
pain.008 XML genereren lijkt simpel: gegevens van betalers nemen, XML maken, uploaden. In de praktijk loopt het mis in het gat tussen financiële administratie, schemaregels, machtigingsgegevens en wat je bank verwacht. In dit artikel lees je hoe het bericht is opgebouwd, hoe je je gegevens koppelt, hoe je valideert en hoe je het automatiseert.
Waarom pain.008 belangrijk is
pain.008 is het berichtformaat voor SEPA-incasso binnen ISO 20022. Elke Nederlandse bank die zakelijke incasso’s aanbiedt, verwacht dit formaat. Het bepaalt of je geld op tijd binnenkomt, of machtigingen kloppen en of je administratie aansluit.

Vuistregel: een incassobestand dat met de hand is gemaakt, valideer je altijd vóór verzending. “Het is geëxporteerd” betekent niet “de bank accepteert het”. Gebruik de gratis SEPA-incasso XML-validator.
Waar teams vastlopen
- Oude exports uit ERP-systemen die niet netjes passen op pain.008.
- Machtigingsgegevens in vrije tekstvelden in plaats van vaste kolommen.
- Verkeerde schemaversie of namespace.
- Handmatige correcties in de XML die niet terug in de bron komen.
Wat “beheersen” echt betekent
Je hoeft de ISO 20022-documentatie niet uit je hoofd te kennen. Je moet drie dingen begrijpen:
- Welke velden het schema vraagt.
- Hoe je brongegevens op die velden worden gekoppeld.
- Hoe je valideert voordat de bank het bestand ziet.
De opbouw van een pain.008 XML-bestand

Lees een pain.008-bestand niet als code, maar als een hiërarchie. De standaardversie pain.008.001.02 heeft drie lagen onder het documentroot:
-
Group Header (
GrpHdr): één per bestand. Berichtkenmerk, aanmaakdatum, aantal posten, totaalbedrag. -
Payment Information (
PmtInf): één of meer per bestand. Groepeert incasso’s met dezelfde incassodatum, hetzelfde schema en hetzelfde sequentietype. -
Direct Debit Transaction (
DrctDbtTxInf): één per incasso. Bedrag, betaler, IBAN, machtiging, omschrijving.
Een minimaal voorbeeld
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.008.001.02">
<CstmrDrctDbtInitn>
<GrpHdr>
<MsgId>DD20260115-001</MsgId>
<CreDtTm>2026-01-15T10:00:00</CreDtTm>
<NbOfTxs>2</NbOfTxs>
<CtrlSum>250.00</CtrlSum>
</GrpHdr>
<PmtInf>
<PmtInfId>COLL-20260115</PmtInfId>
<NbOfTxs>2</NbOfTxs>
<CtrlSum>250.00</CtrlSum>
<ReqdColltnDt>2026-01-20</ReqdColltnDt>
<DrctDbtTxInf>
<PmtId><EndToEndId>INV-1001</EndToEndId></PmtId>
<InstdAmt Ccy="EUR">100.00</InstdAmt>
<DbtrAcct><Id><IBAN>DE89370400440532013000</IBAN></Id></DbtrAcct>
</DrctDbtTxInf>
</PmtInf>
</CstmrDrctDbtInitn>
</Document>
(Ingekort: een echt bestand bevat ook de incassant, het incassant-ID, de machtigingsgegevens en de tweede post.)
Kernpunt: de bank leest dit bestand niet zoals jij een spreadsheet leest. Ze controleert of elk element op de juiste plek staat, met de juiste inhoud, onder het juiste bovenliggende element.
Group Header
MsgId moet uniek zijn per bestand. CreDtTm is het tijdstip van aanmaken, niet de incassodatum. NbOfTxs en CtrlSum moeten precies overeenkomen met de posten in het bestand.
Payment Information
Hier staan de incassodatum (ReqdColltnDt), het schema (Core of B2B), het sequentietype en jouw gegevens als incassant. Drie regels:
-
Datums betekenen wat het schema zegt.
ReqdColltnDtis de gewenste incassodatum. -
Totalen blijven kloppen. Verandert de lijst met posten, dan veranderen
NbOfTxsenCtrlSummee. - Groepeer alleen wat bij elkaar hoort. Eerste en terugkerende incasso’s horen in aparte blokken.
Direct Debit Transaction
Per incasso: EndToEndId (je eigen kenmerk, terug te zien bij afletteren), het bedrag, de naam en het IBAN van de betaler, het machtigingskenmerk (MndtId) en de datum van ondertekening (DtOfSgntr), en een omschrijving. Alle verplichte velden staan in verplichte velden van pain.008.001.02.
Werkwijze: bouw vanuit schone brongegevens, genereer één keer, valideer tegen het schema en lever dan aan. Bewerken in een teksteditor is de uitzondering, niet de werkwijze.
Je brongegevens koppelen
De kwaliteit van je pain.008-bestand wordt bepaald vóórdat de XML wordt gemaakt.
| Bronkolom (Excel) | pain.008-tag | Regels |
|---|---|---|
| Berichtkenmerk | GrpHdr/MsgId |
Uniek per bestand |
| Aanmaakmoment | GrpHdr/CreDtTm |
Tijdstip van aanmaken, niet de incassodatum |
| Aantal posten | GrpHdr/NbOfTxs |
Gelijk aan het aantal regels |
| Controletotaal | GrpHdr/CtrlSum |
Som van alle bedragen |
| Naam incassant | PmtInf/Cdtr/Nm |
De naam zoals bij je bank bekend |
| Incassodatum | PmtInf/ReqdColltnDt |
Werkdag, binnen de deadline van je bank |
| Naam betaler | DrctDbtTxInf/Dbtr/Nm |
Zonder speciale tekens |
| IBAN betaler | DrctDbtTxInf/DbtrAcct/Id/IBAN |
Geldig IBAN, zonder spaties |
| Bedrag | DrctDbtTxInf/InstdAmt |
Punt als decimaalteken in de XML |
| Eigen kenmerk | DrctDbtTxInf/PmtId/EndToEndId |
Voor afletteren en opvolgen |
| Machtigingskenmerk | DrctDbtTxInf/DrctDbtTx/MndtRltdInf/MndtId |
Gelijk aan het kenmerk op de machtiging |
Werk je vanuit platte bestanden, lees dan ook CSV naar SEPA XML.
Gegevens opschonen vóór het koppelen
- Datumformaten gelijktrekken.
- Bedragen standaardiseren.
- IBAN’s controleren met de IBAN-validator.
-
Gereserveerde tekens zoals
&,<en>opschonen of laten escapen.
Kernpunt: slechte brongegevens leveren XML op die er goed uitziet en toch faalt. Besteed meer tijd aan schone velden dan aan mooie uitvoer.
Valideren en fouten oplossen

Validatie heeft twee lagen: technisch (klopt het tegen het XSD-schema?) en inhoudelijk (kloppen totalen, machtigingen, datums en de eisen van je bank?).
| Fout | Wat het meestal betekent | Wat je controleert |
|---|---|---|
| XML-structuur ongeldig | Tags op de verkeerde plek, ontbrekend of niet gesloten | Valideren tegen het XSD, nesting nakijken |
| Ongeldig IBAN-controlegetal | Rekeningnummer fout of onvolledig | Bron-IBAN, spaties, rekeninggegevens |
| Controletotaal klopt niet |
CtrlSum is niet gelijk aan de som |
Opnieuw berekenen uit de opgenomen regels |
| Ongeldig teken | Gereserveerde XML-tekens niet ge-escaped | Namen, kenmerken en omschrijvingen |
| Machtigingskenmerk onbekend | Kenmerk ontbreekt of wijkt af | Machtigingsregister naast de mapping |
Volgorde bij het oplossen
- Bevestig de schemaversie.
- Controleer de totalen.
- Kijk naar speciale tekens.
- Bekijk de machtigingsgegevens.
- Genereer opnieuw nadat je de bron hebt gecorrigeerd.
pain.008 automatiseren met een API

Zelfgeschreven scripts breken vaak bij randgevallen: wisselende sequentietypes, nieuwe velden, andere schemaversies. Een API maakt van het genereren een herhaalbare aanroep:
- Je stuurt de incassogegevens als JSON.
- Je gebruikt een vaste veldkoppeling.
- Je krijgt een gevalideerd pain.008-bestand terug.
- Je slaat het op en levert het aan bij de bank.
{
"message_id": "DD20260115-001",
"collection_date": "2026-01-20",
"iban": "NL00EXAMPLE0123456789",
"amount": "100.00",
"mandate_reference": "MACHT-001",
"end_to_end_id": "INV-1001"
}
Met GenerateSEPA kan dat zowel via de API als door een Excel-, CSV- of JSON-bestand te uploaden. Elk IBAN wordt gecontroleerd voordat het bestand wordt gemaakt. Meer technische achtergrond vind je in SEPA XML-API.
Vuistregel: als je incassorun elke maand belangrijk is, moet het genereren geautomatiseerd zijn en de validatie in de workflow zitten.
Checklist voor elk pain.008-bestand
| Stap | Wat je doet | Wanneer |
|---|---|---|
| 1 | Schemaversie afstemmen met je bank | Eenmalig, bij elke bankwissel |
| 2 | Brongegevens opschonen | Elke run |
| 3 | Veldkoppeling vastleggen | Eenmalig, daarna hergebruiken |
| 4 | Genereren en valideren | Elke run |
| 5 | Fouten in de bron oplossen, niet in de XML | Bij elke afwijzing |
| 6 | Bestand en bankantwoord bewaren | Elke run |
Wil je je incassogegevens zonder handwerk omzetten naar een geldig pain.008-bestand? Probeer GenerateSEPA 7 dagen gratis.
Veelgestelde vragen
- Waarvoor wordt pain.008 XML gebruikt?
- pain.008 is het ISO 20022-bericht waarmee je een SEPA-incasso bij je bank aanlevert. Het bestand vertelt de bank welke bedragen ze van welke rekeningen moet afschrijven, op welke datum en op basis van welke machtigingen.
- Kan ik pain.008 rechtstreeks uit een Excel-bestand genereren?
- Ja, maar niet met een gewone export. De gegevens moeten in de juiste XML-hiërarchie worden gezet en vóór verzending worden gevalideerd. Een converter waarin je kolommen aan SEPA-velden koppelt, doet dat voor je.
- Waarom wordt mijn pain.008-bestand geweigerd terwijl het er goed uitziet?
- Omdat er goed uitzien geen validatie is. Het bestand kan correcte XML zijn en toch niet voldoen aan het schema, een verkeerd controletotaal hebben, een ontbrekend machtigingskenmerk bevatten of een schemaversie gebruiken die je bank niet verwacht.
- Wat is de beste manier om pain.008 te automatiseren?
- Laat je eigen systeem de incassogegevens als JSON naar een API sturen die een gevalideerd pain.008-bestand teruggeeft. Leg de veldkoppeling één keer vast en valideer elk bestand voordat het naar de bank gaat.