Een ERP-koppeling bouwen zonder duidelijke architectuur leidt gegarandeerd tot problemen. In deze gids laat ik zien hoe je Laravel inzet als middleware-laag tussen je ERP en je webshop.
# ERP-koppeling via Laravel als middleware — architectuurgids
Een ERP-koppeling die direct praat met je webshop is een tijdbom. Je hebt dan twee systemen die elkaar kennen, afhankelijk zijn van elkaars API-beschikbaarheid en synchroon moeten draaien. Dat gaat vroeg of laat mis. De oplossing: Laravel als middleware-laag. Een aparte service die als vertaler, buffer en orkestrator fungeert tussen je ERP en je e-commerce platform.
In dit artikel leg ik uit waarom het middleware-patroon de juiste keuze is voor een ERP koppeling Laravel, hoe de architectuur eruitziet in de praktijk, en welke concrete patterns je toepast voor Exact Online, AFAS en SAP.
---
Waarom directe koppelingen falen
Stel: je Magento-shop praat rechtstreeks met Exact Online. Orderstatus A in Magento stuurt een API-call naar Exact, Exact stuurt een webhook terug bij een factuur, en je sync draait via cronjobs die elke vijf minuten pollen.
Dit werkt. Tot het niet meer werkt.
- Exact is even offline — je Magento-checkout blokkeert of gooit errors
- Je doet een Magento-upgrade — de directe integratie breekt
- Je voegt Shopify toe als tweede kanaal — je bouwt de hele koppeling opnieuw
- Een webhook mislukt — niemand merkt het, orders verdwijnen stil
Het fundamentele probleem is tight coupling: de twee systemen zijn afhankelijk van elkaars beschikbaarheid en contracten. Voeg je een derde systeem toe (een WMS, een tweede webshop), dan groeit de complexiteit exponentieel.
De oplossing is de middleware-laag: een dedicated Laravel-applicatie die als hub fungeert. Geen enkel systeem praat direct met een ander systeem — alles gaat via de middleware.
``
+------------------+ +-------------------+ +------------------+
| Magento Shop | <---> | Laravel Middleware| <---> | Exact Online |
+------------------+ | | +------------------+
| - Event Bus |
+------------------+ | - Queue Workers | +------------------+
| Shopify Store | <---> | - Data Mapping | <---> | AFAS / SAP |
+------------------+ | - Retry Logic | +------------------+
| - Monitoring |
+------------------+ | - Error Handling |
| WMS / 3PL | <---> | |
+------------------+ +-------------------+
`
Elk systeem praat alleen met de middleware. De middleware kent alle systemen. Dit noemen we het hub-and-spoke model.
---
De architectuur van een Laravel ERP-koppeling
Een goed ontworpen Laravel middleware voor ERP-koppelingen bestaat uit vijf lagen:
1. Inbound Layer — Webhook Receivers
Elk extern systeem dat events kan sturen, krijgt een dedicated endpoint. Geen generieke webhook-handler, maar specifieke controllers per systeem.
`php
// routes/api.php
Route::prefix('webhooks')->group(function () {
Route::post('/exact/invoice', [ExactWebhookController::class, 'invoice']);
Route::post('/exact/debtor', [ExactWebhookController::class, 'debtor']);
Route::post('/magento/order', [MagentoWebhookController::class, 'order']);
Route::post('/shopify/order', [ShopifyWebhookController::class, 'order']);
});
`
De webhook controller heeft één taak: valideer de payload, sla hem op, en gooi hem op de queue. Geen synchrone verwerking.
Kritische regel: een webhook endpoint returnt altijd 200 binnen twee seconden. Alles wat langer duurt, gaat op de queue.
2. Queue Layer — Asynchrone verwerking
Laravel's queue-systeem is het hart van de middleware. Gebruik Redis als driver — niet de database-driver voor productieomgevingen met hoge volumes.
Gebruik aparte queues voor inbound en outbound traffic. Zo kan een trage ERP-API niet de verwerking van inkomende webhooks blokkeren.
3. Data Mapping Layer — Transformatie
Dit is de kern van de middleware: vertalen tussen de datamodellen van verschillende systemen. Gebruik dedicated Transformer-klassen, geen ad-hoc mapping in je jobs.
Houd transformers puur: geen database-calls, geen HTTP-calls. Input array in, output array uit. Dit maakt ze testbaar zonder mocks.
4. Outbound Layer — API Clients
Voor elke externe service bouw je een dedicated API-client. Gebruik Laravel HTTP Client (Guzzle wrapper) met retry-logica ingebouwd.
5. Error Handling en Retry Logic
Een ERP-koppeling gaat fouten maken. Het verschil tussen een goede en slechte implementatie zit in hoe je omgaat met die fouten. Gebruik exponentiële backoff (1 min, 5 min, 15 min, 1 uur, 4 uur) en stuur alerts naar Slack bij definitief gefaalde jobs.
---
ERP-specifieke overwegingen
Exact Online
Exact Online werkt met OAuth2 en heeft een division-based API. Elke administratie heeft een eigen division-nummer. Sla tokens op in de database, niet in
.env.
- Rate limiting: maximaal 60 requests per minuut per division
- Webhooks: Exact stuurt webhooks voor een beperkte set events. Voor de rest moet je pollen
- GUID-based identifiers: Exact gebruikt GUIDs, niet incrementele IDs — sla de mapping op in een
erp_id_mappings tabel
AFAS
AFAS werkt met App Connectors en tokens. De API is XML/JSON gebaseerd, maar de datastructuur is complexer dan Exact. AFAS heeft geen native webhook-support — je moet een GetConnector pollen of gebruik maken van AFAS Outsite.
Gebruik voor AFAS altijd een dedicated polling job die op vaste intervallen de delta ophaalt.
SAP
SAP-koppelingen zijn een eigen categorie. De meest gangbare aanpak via middleware:
- SAP RFC/BAPI via middleware: gebruik een SAP-adapter service die REST exposed, en laat Laravel daartegen praten
- IDocs via SFTP: SAP genereert IDoc-bestanden die via SFTP beschikbaar komen — bouw een Laravel job die deze files ophaalt en verwerkt
- SAP OData API (voor S/4HANA): moderne SAP-installaties bieden OData v4 endpoints — dit is de cleanste integratieroute
---
Monitoring en observability
Een ERP-koppeling zonder monitoring is een black box. Je wil op elk moment kunnen zien:
Hoeveel events staan er in de queue? (Horizon dashboard of custom metrics)
Hoeveel jobs zijn er mislukt de afgelopen 24 uur?
Wat is de gemiddelde verwerkingstijd per job type?
Wanneer is de laatste succesvolle sync geweest per systeem?
Gebruik Laravel Horizon voor queue monitoring en stel alerts in op:
- Queue depth > 500 (verwerking loopt achter)
- Failed jobs > 10 in 15 minuten (structureel probleem)
- Geen succesvolle sync in > 2 uur (sync is gestopt)
---
Veelgemaakte fouten
Synchrone verwerking in webhook endpoints — Gooi altijd op de queue. Een ERP die een timeout krijgt gaat herhalen of duplicaten sturen.
Geen idempotency-checks — Webhooks worden soms dubbel gestuurd. Gebruik de externe ID als unieke sleutel.
Tokens in .env` opslaan — OAuth tokens verlopen. Bouw een TokenManager die tokens in de database beheert.
---
FAQ
Heb ik een aparte applicatie nodig of kan dit in mijn bestaande Laravel-project?
Voor kleinere projecten kan de middleware-logica in een bestaand Laravel-project als module. Zodra je meer dan twee externe systemen koppelt, is een dedicated middleware-service vrijwel altijd de betere keuze.
Welke queue driver gebruik ik het beste?
Redis. De database-driver is prima voor development, maar niet voor productie met hoge volumes. Gebruik Laravel Horizon voor monitoring bovenop Redis.
Moet ik de ERP-koppeling synchroon of asynchroon maken?
Altijd asynchroon. Synchrone koppelingen creëren een afhankelijkheid tussen de beschikbaarheid van je webshop en je ERP. Een ERP die even traag is, mag nooit de checkout van je webshop vertragen.
Kunnen we dit ook voor Magento of Shopify implementeren?
Ja. De middleware-architectuur is platform-agnostisch. We implementeren dit patroon regelmatig voor shops op Magento, Shopify en maatwerk Laravel platformen.

Geschreven door Ruthger Idema
15+ jaar ervaring in e-commerce development. Gespecialiseerd in Magento, Shopify en Laravel maatwerk.
Meer over ons team →