SEPA XML-API koppelen: van eerste aanroep tot livegang

2026-04-23

Je financiële team heeft een CSV open in het ene venster, het bankportaal in het andere en een afkeurmelding die vrijwel niets zegt. Eén begunstigde heet “Jansen & Zn”. Een andere naam is uit het ERP gekopieerd met vreemde spaties. Een batch eurobetalingen die er in Excel prima uitzag, faalt zodra de bank hem controleert.

Zo beginnen de meeste teams met een SEPA-API: niet met mooie architectuurplaatjes, maar met operationele pijn. Handmatige exports, breekbare sjablonen en te veel giswerk over wat de bank verwacht. Een SEPA XML-API zet gestructureerde betaalgegevens, meestal JSON, om naar ISO 20022 XML die je bank verwerkt. In dit artikel lees je hoe je die koppeling opzet, van de eerste aanroep tot een veilige livegang.

Waarom een SEPA XML-API

Het bekende patroon: finance exporteert een spreadsheet uit het ERP, iemand past datums aan, iemand anders kort kenmerken in tot wat de bank vermoedelijk verwacht. Het bestand wordt geüpload, afgekeurd, gecorrigeerd en opnieuw geüpload. Dat houdt het even vol bij lage volumes, maar breekt zodra runs routine worden, er meerdere bv’s bij komen of incasso’s strakkere controle vragen.

Bezorgde medewerker die complexe financiële overzichten en spreadsheets op een scherm bekijkt.

Het lastige is meestal niet het maken van XML, maar het elke keer leveren van gegevens die de bank accepteert. Tekens zijn daarbij het minst gedocumenteerde probleem: een &, een trema of een slimme apostrof uit Word kan een technisch correcte XML toch laten afkeuren.

Vuistregel: Komen je brongegevens van mensen, ga er dan van uit dat ze tekens, spaties en kenmerken bevatten die je vóór het maken van de XML moet normaliseren.

Een goede SEPA XML-API doet drie dingen tegelijk:

  • Brongegevens standaardiseren, zodat CSV, Excel, JSON en ERP-exports op dezelfde manier in betaalopdrachten terechtkomen.
  • Controleren vóór het aanleveren, zodat foute batches in je eigen proces stranden en niet in het bankportaal.
  • Handwerk verminderen, voor uitgaande overboekingen én voor incasso’s.

Werk je ook met incasso’s, lees dan hoe je SEPA-incasso automatiseert.

De bouwstenen van een SEPA XML-API

Het lastige deel ontdek je meestal in de testfase. De API accepteert nette JSON, de XML wordt gemaakt, en dan keurt de bank het bestand af omdat een veld op het verkeerde niveau staat of een batch opdrachten mengt die nooit in hetzelfde <PmtInf>-blok horen.

Schema van een SEPA XML-API die interne betaalgegevens omzet naar XML voor de bank.

Twee berichtfamilies

pain.001 is voor overboekingen: betalen aan leveranciers, salarissen, dochterbedrijven of terugbetalingen aan klanten.

pain.008 is voor incasso’s: innen bij klanten met een geldige machtiging (zie de SEPA-machtigingsgenerator).

Omdat de brongegevens vaak uit dezelfde ERP-export komen, lopen die twee in de praktijk door elkaar. In de betaallaag mag dat niet. Overboekingen draaien om je eigen rekening en de begunstigde; incasso’s voegen machtigingskenmerken, volgordetypes en incassodata toe.

De XML-blokken die ertoe doen

  • Group Header <GrpHdr>: het bericht als geheel: berichtkenmerk, aanmaaktijd, aantal transacties en controletotaal.
  • Payment Information <PmtInf>: groepeert transacties met dezelfde rekening, uitvoeringsdatum, betaalmethode en serviceniveau.
  • Transactieblok: begunstigde, bedrag, IBAN, BIC waar nodig en kenmerken per opdracht.
  • Omschrijving: factuurnummers, betalingskenmerken of gestructureerde gegevens voor het afletteren.

Een veelgemaakte ontwerpfout zit in <PmtInf>: alles uit één ERP-run in één blok, ook als uitvoeringsdatum of valuta verschilt. Een SEPA-batch is altijd in euro; betalingen in andere valuta horen op een ander kanaal.

Authenticatie en transport

De meeste SEPA-API’s gebruiken API-sleutels, OAuth-tokens, mutual TLS of een combinatie. Authenticatie bewijst welk systeem de opdracht stuurde, niet wie hem intern goedkeurde. Leg daarom aanmaken, goedkeuren, XML genereren en aanleveren vast als aparte gebeurtenissen: de bronpayload, het controleresultaat, het berichtkenmerk, een hash van het bestand, de indiener en het antwoord van de bank.

Je eerste API-aanroep

Houd de eerste aanroep klein: één rekening, één begunstigde, één bedrag, één omschrijving. Dan zie je koppelfouten meteen en debug je niet tegelijk transport, controle en batchlogica.

Persoon die code schrijft op een computer, met koffiemok en notitieboek.

Een minimale overboeking

Richt je eerst op berichtidentiteit, batchindeling en lengte van kenmerken; de omschrijving mag bijvoorbeeld maximaal 140 tekens zijn. Een minimale JSON-opdracht kan er zo uitzien:

{
  "messageId": "20260420-101530-ACME01",
  "creationDateTime": "2026-04-20T10:15:30+02:00",
  "paymentInformationId": "BATCH-APR-001",
  "requestedExecutionDate": "2026-04-21",
  "debtor": {
    "name": "Acme BV",
    "iban": "NL00BANK0123456789"
  },
  "transactions": [
    {
      "endToEndId": "FAC-10045",
      "creditorName": "Leverancier Europa GmbH",
      "creditorIban": "DE00BANK0123456789012",
      "amount": "1250.00",
      "currency": "EUR",
      "remittanceInformation": "Factuur 10045"
    }
  ]
}

De waarden zijn alleen voorbeelden van de structuur. Het gaat om de vorm: bestandsidentiteit, batchidentiteit en transactiegegevens zijn gescheiden. Let op: in JSON en XML staat het bedrag met een punt (1250.00), niet als 1.250,00.

Eerst authenticatie, dan complexiteit

curl -X POST "https://api.example.com/convert" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d @betaling.json

Een verzoek kan geautoriseerd zijn en toch onbruikbare betaalinhoud opleveren. Authenticatie en geldige betaalberichten zijn twee verschillende dingen.

Wat de API hoort terug te geven

{
  "status": "ok",
  "messageId": "20260420-101530-ACME01",
  "schema": "pain.001",
  "xml": "<Document>...</Document>",
  "warnings": []
}

De warnings zijn belangrijk: ingekorte kenmerken, omgezette tekens of weggelaten optionele velden zijn niet fataal maar wel riskant.

Kernpunt: Beoordeel de eerste aanroep niet op de vraag of er XML terugkwam, maar of de XML de zakelijke betekenis van de opdracht behoudt.

De velden die bij eerste pogingen breken

  • Hergebruikte berichtkenmerken, omdat ontwikkelaars testpayloads kopiëren.
  • Wisselende datumformaten, de ene bron stuurt datums, de andere tijdstempels.
  • Rommelige omschrijvingen met factuurlijsten, leestekens en notities uit het ERP.
  • Valutalogica, als een payload ook niet-eurobetalingen probeert te dragen.

Test daarna bewust drie fouten: een ontbrekend verplicht veld, een te lange omschrijving en een naam met verkeerde tekens. Dan weet je of de API alleen omzet of je proces ook beschermt.

Excel en CSV koppelen aan API-velden

De meeste mislukte koppelingen komen niet door XML-syntax maar door slechte keuzes stroomopwaarts: inconsistente Excel-koppen, CSV’s met onzichtbare spaties. De eerste taak is daarom niet “XML maken”, maar één standaard betaalobject definiëren waar elk bronformaat netjes in past.

Bronveld (Excel-kolom) JSON-veld SEPA XML-tag
Naam begunstigde creditorName <Cdtr><Nm>
IBAN begunstigde creditorIban <CdtrAcct><Id><IBAN>
Factuurnummer remittanceInformation <RmtInf>
Bedrag amount <InstdAmt>
Valuta currency <InstdAmt Ccy>
Betaaldatum requestedExecutionDate <ReqdExctnDt>
Batchkenmerk paymentInformationId <PmtInfId>
Berichtkenmerk messageId <MsgId>
Naam opdrachtgever debtor.name <Dbtr><Nm>
IBAN opdrachtgever debtor.iban <DbtrAcct><Id><IBAN>
Machtigingskenmerk mandateId <MndtId>
Datum machtiging mandateDate <DtOfSgntr>

Leg die tabel vast in je implementatienotities en testgevallen.

Waar incassokoppelingen misgaan

  • Incassant-ID vroeg controleren. Wacht niet tot het maken van de XML om te ontdekken dat hij ontbreekt of fout is. Check hem met de incassant-ID-tool.
  • Een vaste regel voor lange namen. Namen zijn beperkt tot 70 tekens. Bepaal of je inkort, normaliseert of handmatig laat beoordelen.

Brongegevens opschonen

  • Tekst normaliseren: spaties weghalen, XML-gevoelige tekens omzetten.
  • Eén datumformaat: alles wordt omgezet voordat het de API bereikt.
  • Weergavenaam en betaalnaam scheiden: een klantlabel uit je CRM is niet altijd de juiste naam voor de bank.
  • Kenmerken gestructureerd houden: factuurnummers, machtigingskenmerken en interne notities niet in één vrij veld.

Werk je nog vooral met spreadsheets, begin dan met een gefaseerde conversie, zoals beschreven in CSV omzetten naar SEPA XML.

Controle, beveiliging en foutafhandeling

Een bestand kan je unittests halen, een 200 OK van de API krijgen en toch falen waar het telt.

Controleer in lagen

  • In je applicatie: ontbrekende velden, ongeldige IBAN’s (controleer ze vroeg met de IBAN-validator), niet-ondersteunde valuta en ongeldige uitvoeringsdata.
  • Op bedrijfsregels: soort betaling, rollen van betaler en ontvanger, aanwezigheid van een machtiging bij incasso’s.
  • Op de uiteindelijke XML: klopt het document na omzetting, inkorten en tekennormalisatie nog met het pain.001- of pain.008-schema?

Bewaar de oorspronkelijke bronwaarde voor je audit en maak een bankveilige waarde voor de XML.

Foutmeldingen die zeggen wat je moet doen

{
  "status": "error",
  "code": "INVALID_REMITTANCE",
  "field": "transactions[0].remittanceInformation",
  "message": "Remittance information exceeds allowed bank format"
}

Maak daar iets operationeels van: “Transactie 1 is mislukt. Het factuurkenmerk is te lang. Kort het in en verstuur de batch opnieuw met een nieuw berichtkenmerk.” Zonder die aanwijzing maken teams bij herstel per ongeluk dubbele betalingen.

Beveiliging hoort in de eerste versie

  • Geheimen beheren: sleutels en certificaten buiten de broncode, met vaste rotatie en per omgeving.
  • TLS overal: ook bij callbacks en interne verbindingen met betaalgegevens.
  • Rolscheiding: finance bereidt voor, fiatteurs keuren goed, ontwikkelaars kunnen met testsleutels geen live betalingen versturen.
  • Gestructureerde logs: batch-ID, berichtkenmerk, gebruiker en controleresultaat, zonder volledige IBAN’s of omschrijvingen.
  • Bewaartermijnen: voor payloads, antwoorden en auditgebeurtenissen, in lijn met de AVG.

Bankverschillen configureerbaar maken

Schema-conform betekent niet automatisch dat elke bank het accepteert. Leg bankregels vast in configuratie, versieer validators samen met de schemaversie, bewaar afkeurredenen en voeg ze toe aan je controles vooraf, en houd regressietests bij voor bekende fouten.

Livegang en de keuze tussen bouwen of uitbesteden

Behandel de livegang als een gecontroleerde migratie. Test met gegevens die zo dicht mogelijk bij je echte exports liggen; kunstmatige testwaarden laten de problemen met spaties, namen en tekens niet zien.

Fase Wat je doet Waar je op let
Pilot Kleine batches, één bv of een beperkte groep leveranciers Afkeur en waarschuwingen
Testen Geldige én ongeldige gevallen Tekens, dubbele kenmerken, ontbrekende ID’s
Terugvaloptie Handmatige route tijdelijk aanhouden Niet als permanente kruk
Monitoring Dagelijks afkeur, herzendingen en afletterproblemen Zie je een fout twee keer per week, automatiseer dan een controle

Zelf bouwen of een beheerde dienst?

Zelf bouwen loont als je sterke ISO 20022-kennis hebt, meerdere bankkoppelingen beheert en betalingen kerninfrastructuur van je product zijn. Een beheerde conversiedienst past beter als je grootste probleem de variatie in brongegevens is.

GenerateSEPA biedt een JSON-API die Excel-, CSV- en JSON-gegevens omzet naar geldige SEPA XML voor overboekingen (pain.001) en incasso’s (pain.008), met IBAN-controle vooraf. Jouw applicatie houdt de bedrijfsregels en goedkeuringen, de dienst zorgt voor opmaak en controle van de XML. Probeer het 7 dagen gratis.


Veelgestelde vragen

Welke XML-berichten ondersteunt een SEPA XML-API?
Meestal twee ISO 20022-berichten: pain.001 voor SEPA-overboekingen (betalen aan leveranciers of medewerkers) en pain.008 voor SEPA-incasso's (innen bij klanten met een machtiging). Ze volgen dezelfde XML-standaard maar hebben een ander doel. Meng ze nooit in één batch.
Hoe werkt authenticatie bij een SEPA XML-API?
De meeste SEPA-API's gebruiken API-sleutels, OAuth-tokens, mutual TLS of een combinatie. Authenticatie bewijst welk systeem de opdracht stuurde, maar vervangt je interne goedkeuring niet. Leg aanmaken, goedkeuren en aanleveren vast als aparte gebeurtenissen met rolgebaseerde toegang.
Hoe ga je om met fouten bij een SEPA XML-API?
Controleer in drie lagen: in je applicatie op ontbrekende velden en ongeldige IBAN's, op bedrijfsregels zoals het soort betaling, en tot slot de XML tegen het schema. Een goede foutmelding noemt het veld, de reden en hoe je opnieuw aanlevert zonder dubbele batch.
Moet je een eigen SEPA XML-laag bouwen of een dienst gebruiken?
Zelf bouwen loont als je veel ISO 20022-kennis hebt, meerdere bankkoppelingen beheert en betalingen kerninfrastructuur van je product zijn. Is je grootste probleem de variatie in brongegevens, dan is een beheerde conversiedienst met API meestal sneller en goedkoper in onderhoud.

Gerelateerde artikelen