Wil je e-facturen via Peppol versturen vanuit Excel/Access (VBA) of VB6? In dit artikel lees je wat Peppol is, welke libraries je nodig hebt (o.a. VBA-Web van Tim Hall), hoe je een Peppol Certified Access Point (zoals Scrada) koppelt en krijg je voorbeeldcode om direct te starten.
Waarom VBA of Visual Basic?
Veel bedrijfsoplossingen zijn historisch gebouwd in VBA (Visual Basic for Applications) of Visual Basic 6 (VB6). Hoewel de IDE van VB6 niet meer wordt ondersteund, draaien de meeste VB6-applicaties nog steeds op moderne Windows-versies. VBA is nog altijd beschikbaar in Microsoft Excel en Access (ook op macOS), waardoor je bestaande oplossingen kunt uitbreiden.
Kort samengevat: VBA en VB6 delen dezelfde basis. Wat je in VBA bouwt, werkt vaak met minimale aanpassingen ook in VB6, en omgekeerd.
Wat is Peppol?
Peppol (Pan-European Public Procurement On-Line) is een Europees netwerk om gestandaardiseerd en veilig elektronische documenten (zoals e-facturen) uit te wisselen tussen bedrijven (B2B) en overheden (B2G). In België is een algemene B2B-e-factureringsverplichting vanaf 1 januari 2026 aangekondigd. Controleer altijd de actuele regelgeving voor jouw sector en land. Meer informatie over Peppol kun je terugvinden in onze Blog post ‘Wat is Peppol?‘ .
Benodigdheden (tooling & libraries)
- Peppol Certified Access Point (AP): bijvoorbeeld Scrada. Je verzendt/ontvangt Peppol-documenten via hun API.
- VBA-Web van Tim Hall: Maakt HTTP-requests, JSON opbouw/parsing en authenticatie in VBA eenvoudig. Werkt op Windows én Mac.
- VBA-Dictionary van Tim Hall: Cross-platform Dictionary als alternatief voor
Scripting.Dictionary(ActiveX) wat niet beschikbaar is op Mac. - (Optioneel) VB6: gebruik desnoods WinHTTP of MSXML2.ServerXMLHTTP voor HTTP-requests als je niet met VBA-Web werkt.
Werking in het kort (Peppol + API)
- Kies een Access Point (bijv. Scrada) en maak een (test)account aan.
- Haal je credentials op: Company ID, API key en eventueel wachtwoord.
- Installeer VBA-Web en voeg de modules toe aan je project (
IWebAuthenticator,WebClient,WebRequest,WebResponse,WebHelpers). - Bouw je e-factuur in object structuur van uw AP of maak uw eigen UBL 2.1/Peppol BIS (XML) bestand die je AP verwacht.
- POST je document via de API van je Access Point.
- Controleer de response (tracking, status, foutmeldingen).
Scrada als Peppol Certified Access Point
Scrada biedt twee API-varianten:
- Peppol Only API – richt zich op ontwikkelaars die enkel een API nodig hebben om facturen op Peppol te plaatsen of af te halen.
- Full API – naast Peppol-verzending ook fallback e-mail, doorsturen naar boekhoudpakketten, etc.
Extra voordeel: omdat het niet altijd vanzelfsprekend is om zelf een correcte UBL 2.1/Peppol BIS (XML) te maken, voorziet Scrada een eenvoudige manier om een object aan te maken dat door Scrada automatisch wordt omgezet naar een geldig Peppol BIS-bestand. Zo hoef je niet zelf alle XML-tags en -structuren op te bouwen, maar kun je in een eenvoudiger formaat werken.
Je kunt een Peppol Only account aanvragen via info@scrada.be of je registreren via https://my.scrada.be voor de full-variant. Toegang tot testomgevingen (verbonden met de Peppol-testomgeving) kun je ook aanvragen via info@scrada.be.
Na registratie vind je:
- API key en wachtwoord via Menu → Instellingen → API Keys
- Company ID via Menu → Instellingen → Bedrijf
Op onze postman pagina https://www.postman.com/scrada/overview/overview kunnen verschillende voorbeelden gevonden worden van het gebruik van onze API zoals versturen via API, ontvangen via API, verstuurde UBL bestanden downloaden, …
Voorbeeld: Factuur via Peppol versturen met VBA (Excel/Access)
Constanten definiëren
We definiëren 3 constanten om onze CompanyID, API Key en wachtwoord in te bewaren:
Public Const COMPANY_ID_SCRADA = ""
Public Const API_KEY_SCRADA = ""
Public Const PASSWORD_SCRADA = ""
Factuur versturen via Peppol (Peppol Only)
Maken we gebruik van de Peppol Only versie, dan kan de code om een factuur te versturen via Peppol er als volgt uitzien:
'https://www.scrada.be/api-documentation/#tag/Peppol-outbound/paths/~1v1~1company~1%7BcompanyID%7D~1peppol~1outbound~1salesInvoice/post
Dim wClient As New WebClient
wClient.BaseUrl = "https://apitest.scrada.be/v1/company/" & COMPANY_ID_SCRADA & "/peppol/outbound/salesInvoice"
Dim req As New WebRequest
req.Resource = "" 'Base URL already set
req.Method = HttpPost
req.Format = json
' Add Authorization header
req.AddHeader "X-API-KEY", API_KEY_SCRADA
req.AddHeader "X-PASSWORD", PASSWORD_SCRADA
'Build JSON invoice object
Dim invoiceObject As Dictionary
Set invoiceObject = BuildInvoiceJsonPeppol(False)
' Send request
' This will send the invoice to Scrada API that will put the invoice on Peppol.
' This is done async so we have to call the status of the invoice to know if already sent on Peppol or that there was an issue.
Set req.Body = invoiceObject
Dim res As WebResponse
Set res = wClient.Execute(req)
' Handle response
If Not res Is Nothing Then
If res.StatusCode >= 200 And res.StatusCode < 300 Then
' The content of the response contains the ID of the invoice at Scrada
s_lastSendInvoiceIDPeppolOnly = Replace(res.Content, """, "")
MsgBox "Invoice successfully sent. Received ID of invoice is " & res.Content, vbInformation
Else
MsgBox "Error sending invoice. Status: " & res.StatusCode & vbCrLf & res.Content, vbCritical
End If
Else
MsgBox "Error sending invoice. No message received from Scrada.", vbCritical
End If
Status van een factuur opvragen
Bij ontvangst van een factuur gaat Scrada deze niet onmiddellijk op Peppol plaatsen. Daarom ontvang je bij afleveren van de factuur een ID en deze ID kun je gebruiken om nadien de status op te vragen:
'https://www.scrada.be/api-documentation/#tag/Peppol-outbound/paths/~1v1~1company~1%7BcompanyID%7D~1peppol~1outbound~1document~1%7BdocumentID%7D~1info/get
Dim wClient As New WebClient
wClient.BaseUrl = "https://apitest.scrada.be/v1/company/" & COMPANY_ID_SCRADA & "/peppol/outbound/document/" & s_lastSendInvoiceIDPeppolOnly & "/info"
Dim req As New WebRequest
req.Resource = "" 'Base URL already set
req.Method = HttpGet
req.Format = json
' Add Authorization header
req.AddHeader "X-API-KEY", API_KEY_SCRADA
req.AddHeader "X-PASSWORD", PASSWORD_SCRADA
' Do API call
Dim res As WebResponse
Set res = wClient.Execute(req)
' Handle response
If Not res Is Nothing Then
If res.StatusCode >= 200 And res.StatusCode < 300 Then
Dim status As String
status = res.Data("status")
If status = "Created" Then
MsgBox "Scrada will pickup the invoice soon to send it over Peppol", vbInformation
ElseIf status = "Processed" Then
MsgBox "The invoice is sent over Peppol to access point with seat ID " & res.Data("peppolC3SeatID") & ". The reception ID of that access point is " & res.Data("peppolC3MessageID"), vbInformation
ElseIf status = "Retry" Then
MsgBox "There was an issue (" & res.Data("errorMessage") & ") when sending invoice over Peppol. Scrada will retry to send it. This is retry " & res.Data("attempt"), vbExclamation
Else
MsgBox "Error when sending invoice over Peppol. Status: " & status & vbCrLf & "Error: " & res.Data("errorMessage"), vbCritical
End If
Else
MsgBox "Error getting status of invoice. Status: " & res.StatusCode & vbCrLf & res.Content, vbCritical
End If
Else
MsgBox "Error getting status of invoice. No feedback received from Scrada.", vbCritical
End If
Exit Sub
Voorbeeldfunctie: BuildInvoiceJsonPeppol
In het voorbeeld hierboven wordt de factuur opgebouwd door de functie BuildInvoiceJsonPeppol. Hieronder ziet u hoe deze functie eruit kan zien.
Private Function BuildInvoiceJsonPeppol(buildForFullVersion As Boolean) As Dictionary
Dim inv As Object: Set inv = New Dictionary
' Invoice header
If buildForFullVersion Then
'The full version need also the property bookYear and journal to identify an invoice unique
inv.Add "bookYear", ""
inv.Add "journal", ""
End If
inv.Add "number", "test-json-invoice-scrada-2"
inv.Add "externalReference", "DB_1|46a5e373-4337-4d68-92be-30ec6d2c7d98"
inv.Add "creditInvoice", False
inv.Add "invoiceDate", "2024-12-20"
inv.Add "invoiceExpiryDate", "2024-12-25"
inv.Add "buyerReference", "0150abc"
'The full version does not need a supplier because for every supplier a company is created in Scrada and that company is used as supplier info
If (Not buildForFullVersion) Then
' Supplier
Dim sup As Object: Set sup = New Dictionary
sup.Add "peppolID", "9915:test-sender"
sup.Add "name", "SupplierTradingName BV"
Dim supAdr As Object: Set supAdr = New Dictionary
supAdr.Add "street", "Main street"
supAdr.Add "streetNumber", "1"
supAdr.Add "streetBox", ""
supAdr.Add "city", "Antwerpen"
supAdr.Add "zipCode", "2000"
supAdr.Add "countrySubentity", ""
supAdr.Add "countryCode", "BE"
sup.Add "address", supAdr
sup.Add "vatStatus", 1
sup.Add "legalPersonRegister", "RPR Antwerpen"
sup.Add "vatNumber", "BE0000000097"
' Supplier extraIdentifiers (array)
Dim extraIds As New Collection
Dim extraId1 As Object: Set extraId1 = New Dictionary
extraId1.Add "identifier", "ITAA nummmer: 155554"
extraIds.Add extraId1
sup.Add "extraIdentifiers", extraIds
inv.Add "supplier", sup
End If
' Customer
Dim cust As Object: Set cust = New Dictionary
cust.Add "name", "Scrada BV"
Dim custAdr As Object: Set custAdr = New Dictionary
custAdr.Add "street", "Unknown street"
custAdr.Add "streetNumber", "32"
custAdr.Add "streetBox", "5"
custAdr.Add "city", "Sint-Lievens-Houtem"
custAdr.Add "zipCode", "9521"
custAdr.Add "countryCode", "BE"
cust.Add "address", custAdr
cust.Add "vatNumber", "BE0793904121" 'The vat number of Scrada is used so that this test invoice will be delivered to Scrada
inv.Add "customer", cust
' Delivery
Dim deliv As Object: Set deliv = New Dictionary
deliv.Add "deliveryDate", "2024-12-23"
Dim delAdr As Object: Set delAdr = New Dictionary
delAdr.Add "street", "Delivery street"
delAdr.Add "streetNumber", "2"
delAdr.Add "city", "Gent"
delAdr.Add "zipCode", "9000"
delAdr.Add "countryCode", "BE"
deliv.Add "address", delAdr
inv.Add "delivery", deliv
' Invoice totals
inv.Add "totalExclVat", 1302.45
inv.Add "totalInclVat", 1575.65
inv.Add "totalVat", 273.2
inv.Add "currency", "EUR"
inv.Add "payableRoundingAmount", 0.05
' Invoice lines (array)
Dim lines As New Collection
Dim ln As Dictionary
' Invoice line 1
Set ln = New Dictionary
ln.Add "lineNumber", "1"
ln.Add "itemName", "item name"
ln.Add "quantity", 7
ln.Add "unitType", 103
ln.Add "itemExclVat", 400.05
ln.Add "vatType", 1
ln.Add "vatPercentage", 21
ln.Add "totalDiscountExclVat", 0
ln.Add "totalExclVat", 2800.35
lines.Add ln
' Invoice line 2
Set ln = New Dictionary
ln.Add "lineNumber", "2"
ln.Add "itemName", "item name 2"
ln.Add "quantity", -3
ln.Add "unitType", 103
ln.Add "itemExclVat", 500
ln.Add "vatType", 1
ln.Add "vatPercentage", 21
ln.Add "totalDiscountExclVat", 0
ln.Add "totalExclVat", -1500
lines.Add ln
' Invoice line 3
Set ln = New Dictionary
ln.Add "lineNumber", "3"
ln.Add "itemName", "item name 3"
ln.Add "quantity", 2.0096
ln.Add "unitType", 202
ln.Add "itemExclVat", 0.5242
ln.Add "vatType", 1
ln.Add "vatPercentage", 6
ln.Add "totalDiscountExclVat", 0
ln.Add "totalExclVat", 1.05
lines.Add ln
' Invoice line 4
Set ln = New Dictionary
ln.Add "lineNumber", "4"
ln.Add "itemName", "item name 4"
ln.Add "quantity", 2.0096
ln.Add "unitType", 202
ln.Add "itemExclVat", 0.5242
ln.Add "vatType", 1
ln.Add "vatPercentage", 6
ln.Add "totalDiscountExclVat", 0
ln.Add "totalExclVat", 1.05
lines.Add ln
inv.Add "lines", lines
' Invoice vatTotals (array)
Dim vatTotals As New Collection
Dim vt As Dictionary
' vat total 21%
Set vt = New Dictionary
vt.Add "vatType", 1
vt.Add "vatPercentage", 21
vt.Add "totalExclVat", 1300.35
vt.Add "totalVat", 273.07
vt.Add "totalInclVat", 1573.42
vatTotals.Add vt
' vat total 6%
Set vt = New Dictionary
vt.Add "vatType", 1
vt.Add "vatPercentage", 6
vt.Add "totalExclVat", 2.1
vt.Add "totalVat", 0.13
vt.Add "totalInclVat", 2.23
vatTotals.Add vt
inv.Add "vatTotals", vatTotals
' paymentTerms
inv.Add "paymentTerms", "Payment within 5 days"
' paymentMethods (array)
Dim pms As New Collection
Dim pm As Dictionary: Set pm = New Dictionary
pm.Add "paymentType", 2
pm.Add "paymentReference", "Snippet1"
pm.Add "name", "AccountName"
pm.Add "iban", "BE39900000010119"
pm.Add "bic", "GNOMBEBB"
pm.Add "totalPaid", 0
pm.Add "totalToPay", 1575.7 ' JSON doesn't require trailing zero; value = 1575.70
pms.Add pm
inv.Add "paymentMethods", pms
' attachments (array)
Dim atts As New Collection
Dim att As Object: Set att = New Dictionary
att.Add "filename", "invoice.pdf"
att.Add "fileType", 1
att.Add "mimeType", "application/pdf"
att.Add "base64Data", "test" 'A correct base 64 must be put here if you want to add a PDF of the invoice as attachment
att.Add "note", "Invoice"
atts.Add att
inv.Add "attachments", atts
' return invoice
Set BuildInvoiceJsonPeppol = inv
End Function
Zoals u kunt zien kunt u zeer eenvoudig in VB6 (Visual Basic 6) of in VBA-toepassingen de functionaliteit toevoegen om facturen of documenten via Peppol te versturen. Heb je nog vragen over Peppol of hoe je dit kunt doen, neem gerust contact op met ons.
Werkend voorbeeld
Een werkend voorbeeld Excel bestand kan gedownload worden via volgende link.
Veelgemaakte valkuilen & tips
- Formaat en validatie: zorg dat je UBL/Peppol-document valideert tegen het juiste BIS-profiel van je klant/land of maak gebruik van bijvoorbeeld Scrada object als je zelf de XML niet wil bouwen.
- Identifier van de ontvanger: gebruik de juiste Peppol-identifier (scheme + nummer, bv. Belgisch btw-nummer). Als je gebruik maakt van het Scrada object dan wordt automatisch door Scrada de juiste Peppol-identifier bepaald adhv van de informatie dat je op klant niveau hebt voorzien.
- Test vs productie: start in de testomgeving (test endpoints/keys) en schakel pas om naar productie als de flow stabiel is.
- Foutafhandeling: log statuscodes en response-body.
- Beveiliging: hard-code nooit secrets in je code; haal ze uit een versleutelde store of environment-variabelen.
FAQ (korte antwoorden)
Werkt dit op Mac?
Ja, VBA-Web en VBA-Dictionary werken op macOS. VB6 is Windows-only, maar VBA in Excel/Access draait ook op Mac.
Moet ik per se UBL-XML maken?
Voor Peppol doorgaans wel. Sommige Access Points accepteren ook JSON en zetten dit om naar UBL, maar controleer de documentatie van je AP. Bij Scrada kun je kiezen of je uw eigen UBL maakt of gebruik maakt van Scrada object dat door Scrada wodt omgezet naar juiste UBL formaat.
Is Peppol verplicht in België?
Er is een B2B-verplichting aangekondigd vanaf 1 januari 2026.
Kan ik in naam van mijn klanten verzenden?
Ja, via een Peppol Only API kun je als softwarebouwer documenten in naam van je klanten plaatsen/afhalen. Je hebt wel toestemming nodig van uw klant om dit te mogen doen.
Welke libraries heb ik nodig in VBA?
We raden VBA-Web aan. Aanvullend VBA-Dictionary voor een cross-platform Dictionary.






