Idempotency in integraties: waarom dubbele orders ontstaan en hoe je dat voorkomt
Door Clen Mourik
Dubbele orders, gefactureerde transacties die er nooit waren, voorraad die drie keer wordt afgetrokken. Voor een gemiddeld MKB-bedrijf met €2 miljoen omzet kost dit €10.000-€40.000 per jaar. Het komt vaker voor dan je denkt — en het is te voorkomen.
Je opent maandagochtend je boekhouding. Dezelfde factuur staat er twee keer in. Een klant belt: waarom heeft hij een dubbele verzendbevestiging gekregen? Je voorraad klopt niet meer. En ergens loopt er een process dat orders blijft versturen die al zijn verwerkt.
Herkenbaar? Dit zijn geen uitzonderingen. Bij integraties tussen systemen — van webshops met AFAS tot voorraadsystemen met je boekhouding — ontstaan duplicaten sneller dan je denkt. Vooral wanneer netwerken traag zijn, systemen timeouts geven, of een API-call opnieuw wordt geprobeerd.
De oplossing heeft een naam die je waarschijnlijk nog nooit hebt gehoord: idempotency. Klinkt ingewikkeld, maar het concept is simpel. En het kan je duizenden euro's per jaar besparen.
Inhoudsopgave
- Belangrijkste punten
- Wat is idempotency precies?
- Waarom duplicaten ontstaan bij koppelingen
- De verborgen kosten van dubbele transacties
- Hoe idempotency dit voorkomt
- Praktijkvoorbeelden uit verschillende sectoren
- Verschillende manieren om idempotency te implementeren
- Veelgemaakte fouten bij systeemkoppelingen
- Hoe test je of je koppeling idempotent is?
- Veelgestelde vragen
Belangrijkste punten
| Punt | Details |
|---|---|
| Duplicaten zijn geen uitzondering | Bij systemen met 500+ transacties per dag kunnen duplicaten oplopen tot 2-5% zonder idempotency-controles |
| Kosten zijn substantieel | Handmatige correctie kost 15-30 minuten per incident. Bij €2 miljoen omzet: €10.000-€40.000 per jaar aan fouten |
| Oorzaak: retries | 40-60% van alle API-calls zijn retries. Zonder idempotency leiden 15-25% daarvan tot dubbele verwerkingen |
| Oplossing: idempotency-keys | Unieke identifier per transactie zorgt dat dezelfde actie meerdere keren veilig kan worden herhaald |
| Implementatie varieert | Van simpele database-constraints tot geavanceerde idempotency-key systemen, afhankelijk van complexiteit |
Wat is idempotency precies?
Idempotency betekent dat een operatie meerdere keren kan worden uitgevoerd met hetzelfde resultaat als wanneer deze één keer wordt uitgevoerd. Klinkt abstract, maar denk aan een lichtknop.
Je drukt op de lichtknop. Het licht gaat aan. Je drukt nog eens. Het licht blijft aan — niet dubbel zo fel. Dat is idempotent gedrag.
Bij systeemintegraties gaat het om API-calls en data-uitwisseling. Een order die vijf keer wordt verstuurd mag maar één keer worden aangemaakt. Een betaling die drie keer wordt geboekt, moet worden herkend als dezelfde transactie.
In de HTTP-specificatie zijn sommige operaties van nature idempotent:
- GET — lezen van data, altijd veilig te herhalen
- PUT — vervangen van een resource, als je dezelfde data stuurt krijg je hetzelfde resultaat
- DELETE — verwijderen kan je herhalen, tweede keer is het al weg
- POST — NIET idempotent, elke POST kan een nieuw record aanmaken
Dat laatste is het probleem. POST wordt gebruikt voor het aanmaken van orders, klantgegevens, facturen, werkbonnen — alles wat je niet dubbel wilt hebben.
Waarom duplicaten ontstaan bij koppelingen
Netwerken zijn onbetrouwbaar. Daar draait het om. Je stuurt een order van je webshop naar je boekhouding. De order komt aan, wordt verwerkt, maar de bevestiging raakt onderweg kwijt.
Wat doet je webshop? Precies — het stuurt de order opnieuw. En nog eens. En nog eens.
Dit gebeurt vaker dan je denkt. In cloud-omgevingen is ongeveer 40-60% van alle API-calls een retry na een timeout of netwerkfout. Zonder de juiste bescherming leidt dit in 15-25% van de gevallen tot dubbele verwerkingen.
Veelvoorkomende scenario's
Trage systemen — Je ERP-systeem is aan het eind van de maand langzaam door alle administratieve processen. Een order wordt verstuurd, maar de response duurt langer dan de timeout van 30 seconden. De verzendende kant denkt dat het mislukt is en probeert opnieuw.
Wisselende internetverbinding — Monteurs in een bestelbus boeken hun uren via een mobiele app. De verbinding valt weg net nadat de data is verstuurd maar voordat de bevestiging terugkomt. De app probeert het automatisch opnieuw.
Webhooks die opnieuw worden verstuurd — Shopify stuurt een webhook naar je voorraadsysteem. Die is offline voor onderhoud. Shopify probeert het opnieuw. En opnieuw. Tot 48 uur lang met exponential backoff. Als je voorraadsysteem weer online komt, krijg je alle retries binnen.
Race conditions bij gelijktijdige verwerking — Twee processen checken tegelijk of een order al bestaat. Beide zien "nee". Beide maken de order aan. Je hebt nu een duplicaat.
In de praktijk zie ik dat bedrijven vaak pas na maanden ontdekken dat ze duplicaten hebben. Tijdens de jaarafsluiting blijkt de omzet ineens €87.000 hoger te staan dan de bankrekening laat zien.
De verborgen kosten van dubbele transacties
Een dubbele order kost niet alleen de tijd om het op te lossen. De impact is breder.
| Type kosten | Impact | Voorbeeld |
|---|---|---|
| Handmatige correctietijd | 15-30 min per incident | Bij 5 duplicaten per week: 6,5 uur/maand = €780/jaar aan loonkosten |
| Verkeerde voorraadcijfers | Overstock of tekorten | Groothandel met €45.000 overstock door dubbele inkooporders |
| Klantcompensatie | Korting/retour bij fouten | Dubbel verzonden product, retourkosten + klantkorting |
| Boekhouding niet sluitend | Extra accountantsuren | 400+ transacties handmatig uitzoeken bij jaarafsluiting |
| Reputatieschade | Klanten verliezen vertrouwen | Klant ontvangt drie keer dezelfde factuur, gaat naar concurrent |
Voor een MKB-bedrijf met €2 miljoen omzet lopen de kosten op tot €10.000-€40.000 per jaar aan correcties, retouren en klantcompensaties. Dat is 0,5-2% van de omzet.
Een onderzoek van de KVK laat zien dat 62% van de Nederlandse MKB-bedrijven 3 of meer verschillende softwarepakketten gebruikt. 34% gebruikt zelfs 5 of meer systemen. Hoe meer systemen, hoe meer koppelingen, hoe groter de kans op duplicaten.
Hoe idempotency dit voorkomt
De kern van idempotency is simpel: geef elke transactie een uniek nummer. Check bij het verwerken of je dat nummer al eerder hebt gezien. Zo ja, doe dan niets (of geef het eerdere resultaat terug). Zo nee, verwerk de transactie en onthoud het nummer.
Dit unieke nummer heet een idempotency-key. Het kan van alles zijn:
- Het ordernummer uit je webshop
- Een UUID die je genereert bij het versturen
- Een combinatie van datum + klant-ID + factuurnummer
- De webhook-ID die Shopify meestuurt
Voorbeeld: webshop naar boekhouding
Zonder idempotency:
- Webshop stuurt order #12345 naar boekhouding-API
- Boekhouding maakt factuur aan
- Response raakt kwijt door netwerkfout
- Webshop stuurt order #12345 opnieuw
- Boekhouding maakt nóg een factuur aan → duplicaat
Met idempotency:
- Webshop stuurt order #12345 + idempotency-key: "order-12345"
- Boekhouding checkt: heb ik "order-12345" al gezien? Nee
- Boekhouding maakt factuur aan en slaat "order-12345" op als verwerkt
- Response raakt kwijt door netwerkfout
- Webshop stuurt order #12345 + key "order-12345" opnieuw
- Boekhouding checkt: heb ik "order-12345" al gezien? Ja
- Boekhouding geeft het eerdere resultaat terug zonder nieuwe factuur → geen duplicaat
Praktijkvoorbeelden uit verschillende sectoren
Laten we eerlijk zijn: dit is geen theoretisch probleem. Het gaat fout in de praktijk.
E-commerce: dubbele verzendingen
Een webshop met 200-300 orders per dag koppelt Shopify aan AFAS voor automatische orderverwerking. Bij een trage netwerkverbinding krijgt Shopify geen bevestiging binnen de timeout. De webhook wordt opnieuw verstuurd.
Zonder idempotency-check werden dezelfde orders dubbel aangemaakt in AFAS. Dit gebeurde vooral op maandagochtenden wanneer veel orders tegelijk binnenkwamen. Resultaat: 10-15 dubbele orders per week, klanten die dubbele verzendbevestigingen kregen, en soms zelfs dubbel verzonden producten.
De oplossing: implementatie van idempotency-keys gebaseerd op het Shopify order ID. Elke order wordt maar één keer verwerkt, ongeacht hoeveel keer de webhook wordt verzonden.
Groothandel: voorraadchaos door dubbele inkooporders
Een technische groothandel synchroniseert hun voorraadsysteem Picqer met Exact Online. Wanneer voorraad onder het minimum komt, wordt automatisch een inkooporder aangemaakt.
Door een bug in de synchronisatie werden bij elke voorraadwijziging de inkooporders opnieuw verstuurd. Vijf keer dezelfde inkooporder kwam bij de leverancier binnen. Die leverde alles keurig — €45.000 aan producten die niet direct verkocht konden worden.
De oplossing: idempotency-controle op basis van een unieke combinatie van product-ID, datum en bestelhoeveelheid. Het systeem herkent nu duplicaten voordat ze worden verstuurd.
Bouw: monteurs die uren dubbel boeken
Een installatiebedrijf met 15 monteurs koppelt hun urenregistratie-app aan Twinfield. Monteurs boeken hun uren via een mobiele app op bouwlocaties.
Door wisselende internetverbinding werden uren soms twee of drie keer doorgestuurd. De app probeerde de sync opnieuw bij elke netwerkfout. Resultaat: gefactureerde uren die 120-150% van de werkelijke uren bedroegen.
Klanten weigerden te betalen. Cashflow-problemen. De oplossing: elke urenregistratie kreeg een UUID. Het ontvangende systeem checkt of deze UUID al eerder is verwerkt.
Wat ik vaak zie: bedrijven denken dat netwerkfouten zeldzaam zijn. Maar in cloud-omgevingen komt een retry scenario bij 1 op de 5 tot 1 op de 10 API-calls voor. Bij 100+ transacties per dag betekent dit bijna dagelijks een potentieel duplicaat.
Marktplaatsen: dubbele betalingen in de boekhouding
Een bedrijf verkoopt via Bol.com en Amazon en synchroniseert betalingen naar hun boekhouding. Door API-retries bij Bol.com werden sommige betalingen dubbel geboekt.
Dit viel pas op bij de jaarafsluiting: omzet stond €87.000 hoger dan de werkelijk ontvangen bedragen. De accountant moest handmatig 400+ transacties uitzoeken. Kosten: extra accountantsuren en uitgestelde jaarrekening.
De oplossing: gebruik van het transactie-ID van de marktplaats als idempotency-key bij het boeken.
Verschillende manieren om idempotency te implementeren
Er zijn meerdere manieren om idempotency te implementeren. De beste keuze hangt af van je situatie.
Aanpak 1: Idempotency-keys aan client-kant
De verzendende partij genereert een unieke key (meestal een UUID) en stuurt deze mee met elke request. De ontvangende partij slaat deze key op en checkt bij elk nieuw request of de key al eerder is gebruikt.
Voordeel: Client heeft controle, kan retries veilig uitvoeren
Nadeel: Client moet keys persistent opslaan, extra complexiteit
Geschikt voor: Systemen waar je controle hebt over de verzendende kant
Zo werkt het bij grote payment providers zoals Stripe: je stuurt een Idempotency-Key header mee. Stripe slaat deze 24 uur op en geeft bij een retry het eerdere resultaat terug.
Aanpak 2: Server-side deduplicatie op business-logica
Het ontvangende systeem checkt op basis van business-gegevens of een transactie al bestaat. Bijvoorbeeld: is er al een order met dit ordernummer voor deze klant?
Voordeel: Werkt ook als de client geen idempotency-keys stuurt
Nadeel: Lastig bij complexe scenario's, kan vals-positieven geven
Geschikt voor: Eenvoudige koppelingen met duidelijke unieke identifiers
Aanpak 3: Database constraints
Gebruik UNIQUE constraints op database-niveau voor velden zoals extern_ordernummer of transactie_id. De database weigert dan automatisch duplicaten.
Voordeel: Geforceerd op database-niveau, kan niet per ongeluk worden overgeslagen
Nadeel: Geeft vaak generieke errors, moeilijker te debuggen
Geschikt voor: Wanneer er duidelijke unieke velden zijn
Aanpak 4: Message queue deduplicatie
Bij asynchrone verwerking via message queues (RabbitMQ, Azure Service Bus) kun je ingebouwde deduplicatie gebruiken. AWS SQS FIFO queues hebben bijvoorbeeld content-based deduplication.
Voordeel: Ingebouwd in de infrastructuur
Nadeel: Beperkte deduplicatie window (meestal 5 minuten tot 7 dagen)
Geschikt voor: Asynchrone verwerking met message queues
Welke aanpak voor het MKB?
Voor de meeste MKB-integraties werkt een combinatie van aanpak 1 en 3 het beste: idempotency-keys gebruiken waar mogelijk, aangevuld met database constraints als vangnet. Dit geeft dubbele zekerheid zonder onnodig complex te worden.
Veelgemaakte fouten bij systeemkoppelingen
Laten we eerlijk zijn: idempotency wordt vaak vergeten of verkeerd geïmplementeerd. Hier zijn de meest voorkomende fouten.
Fout 1: "Het gebeurt toch niet vaak"
Veel ondernemers denken dat netwerkfouten zeldzaam zijn. In de praktijk komt een retry scenario bij 1 op de 5 tot 1 op de 10 API-calls voor. Bij 100 transacties per dag betekent dit 10-20 potentiële duplicaten per dag zonder bescherming.
Fout 2: Alleen checken op tijdstip
Sommige implementaties checken of dezelfde transactie binnen 5 minuten al is verwerkt. Dit werkt niet bij systemen die batches verwerken of waarbij verwerkingstijd kan oplopen. Bij geplande synchronisaties (elke 15 minuten) pikt deze check duplicaten niet op.
Fout 3: Interne database-ID's als idempotency-key
Een auto-increment ID uit je database is geen goede idempotency-key. Deze kan verschillen tussen test- en productie, of na database-migraties. Gebruik UUID's of externe referentienummers die in beide systemen hetzelfde zijn.
Fout 4: Geen idempotency bij updates
Veel implementaties checken alleen of een record al bestaat (create-operaties), maar niet bij updates. Dit leidt tot race conditions waarbij dezelfde voorraadmutatie 3x wordt afgetrokken in plaats van 1x.
Fout 5: Keys te kort bewaren
Als je idempotency-keys maar 24 uur bewaart, maar je synchroniseert wekelijks, dan kunnen alsnog duplicaten ontstaan bij het opnieuw afspelen van oude data.
Fout 6: Geen monitoring
Zelfs met idempotency-controles kunnen door bugs duplicaten ontstaan. Zonder monitoring — bijvoorbeeld alerts bij meerdere orders met hetzelfde externe ordernummer — ontdek je problemen te laat.
Hoe test je of je koppeling idempotent is?
De theorie is mooi, maar hoe weet je of het écht werkt? Hier zijn praktische tests die je kunt uitvoeren.
Test 1: Handmatige retry
Verstuur dezelfde API-call twee keer handmatig (bijvoorbeeld via Postman). Check of er maar één record is aangemaakt. Simpel maar effectief.
Test 2: Timeout simuleren
Zet een kunstmatig lage timeout op je API-client (bijvoorbeeld 1 seconde). Verstuur een request die langer duurt. De client zal een retry doen. Check of er geen duplicaat ontstaat.
Test 3: Gelijktijdige verwerking
Verstuur dezelfde request 5x tegelijk (parallel). Dit test of race conditions goed worden afgehandeld. Er moet maar 1 record zijn na afloop.
Test 4: Productiedata replay
In een test-omgeving: speel een batch oude productiedata opnieuw af. Check of het systeem herkent dat deze al zijn verwerkt.
Test 5: Monitoring alerts
Maak bewust een duplicaat aan en check of je monitoring-systeem dit oppikt. Test je alerts.
Bij SyncIT testen we dit standaard bij elke branche-specifieke integratie die we bouwen. Niet omdat we het leuk vinden, maar omdat we weten wat er gebeurt als je het niet test.
Veelgestelde vragen
Wat is idempotency in integraties?
Idempotency betekent dat een operatie meerdere keren kan worden uitgevoerd met hetzelfde resultaat als één keer. Bij integraties zorgt dit ervoor dat een order, factuur of andere transactie maar één keer wordt verwerkt, zelfs als de API-call meerdere keren wordt verstuurd door netwerkfouten of retries.
Waarom krijg ik dubbele klantgegevens na een koppeling?
Dit gebeurt meestal door retry-mechanismes in webhooks of API-calls. Als een systeem geen bevestiging terugkrijgt binnen de timeout, stuurt het de data opnieuw. Zonder idempotency-check wordt elk bericht als nieuw beschouwd en ontstaan duplicaten. De oplossing is het gebruik van unieke identifiers (idempotency-keys) die het ontvangende systeem herkent.
Hoe voorkom je dubbele orders in e-commerce integraties?
Gebruik het ordernummer of webhook-ID van je webshop als idempotency-key. Bij systemen zoals Shopify stuurt de webhook een unieke X-Shopify-Webhook-Id mee. Check bij het verwerken of deze ID al eerder is gezien. Zo ja, sla de verwerking dan over. Database constraints op het externe ordernummer zijn een extra vangnet.
Ondersteunen AFAS en Exact Online idempotency?
Beide systemen hebben geen ingebouwde idempotency-key ondersteuning in hun API's. Bij AFAS moet je zelf logica bouwen om via GetConnector te checken of een element al bestaat. Bij Exact Online kun je unieke velden zoals YourRef gebruiken om duplicaten te detecteren. In de praktijk bouwen we bij SyncIT deze logica in de integratielaag.
Hoe test je idempotentie in procesautomatisering?
Verstuur dezelfde API-call handmatig twee keer en controleer of er maar één record is aangemaakt. Simuleer timeouts door de timeout-waarde kunstmatig laag te zetten. Test gelijktijdige verwerking door dezelfde request parallel 5x te versturen. En belangrijk: monitor in productie op duplicaten door alerts in te stellen op meerdere records met dezelfde externe identifier.
Wat kosten dubbele transacties een gemiddeld MKB-bedrijf?
Voor een bedrijf met €2 miljoen omzet lopen de kosten op tot €10.000-€40.000 per jaar (0,5-2% van omzet). Dit komt door handmatige correctietijd (15-30 min per incident), verkeerde voorraadcijfers, klantcompensaties, extra accountantsuren en reputatieschade. Bij bedrijven met 500+ transacties per dag zonder idempotency-controles kunnen duplicaten oplopen tot 2-5% van alle transacties.
Kun je idempotente integraties laten bouwen voor AFAS en Shopify?
Ja, dit is een veelvoorkomende vraag. Bij het koppelen van Shopify aan AFAS bouwen we standaard idempotency-logica in. Dit betekent dat we het Shopify order-ID of webhook-ID gebruiken om te checken of een order al in AFAS bestaat voordat we deze aanmaken. Dit voorkomt duplicaten bij retries of netwerkfouten. Neem contact op voor een adviesgesprek over jouw specifieke situatie.
Conclusie: beter voorkomen dan genezen
Dubbele orders, gefactureerde uren die niet kloppen, voorraad die niet klopt — het zijn geen zeldzame uitzonderingen. Bij elk bedrijf dat systemen aan elkaar koppelt, is het risico aanwezig. Vooral bij meer dan 50 transacties per dag.
Idempotency is geen fancy technische term waar je wakker van moet liggen. Het is gewoon: zorg dat dezelfde actie meerdere keren veilig kan worden herhaald zonder duplicaten. Met een unieke identifier, een simpele check, en goede monitoring kom je al heel ver.
De investering is minimaal vergeleken met de kosten van het handmatig corrigeren van duplicaten. En eerlijk gezegd: als je procesautomatisering goed wilt doen, is het gewoon onderdeel van een degelijke implementatie.
Heb je nu koppelingen zonder idempotency-controles? Dan is de kans groot dat je al duplicaten hebt zonder het te weten. Check je boekhouding, voorraad en orderhistorie eens kritisch. En als je nieuwe integraties bouwt of laat bouwen: vraag expliciet hoe duplicaten worden voorkomen.
Wil je weten of jouw huidige koppelingen goed zijn beveiligd tegen duplicaten? Of ben je van plan systemen te integreren en wil je het meteen goed doen? Plan een vrijblijvend adviesgesprek. We kijken samen naar je situatie en vertellen eerlijk of je iets moet aanpassen — en zo ja, hoe.