Als je Shopify-koppeling nog op API-versie 2025-10 draait, is 16 oktober 2026 de harde grens waarop die versie niet meer beschikbaar is. Een foute upgrade toont zich niet altijd als een rode API-fout. Soms wordt een betaling wel als geslaagd opgeslagen, terwijl de payout niet meer matcht. Soms komt de order aan, maar verdwijnt een nieuwe fulfilmentstatus uit je vertaling.
Behandel een versioned cutover daarom als een bedrijfswijziging met een technische implementatie. Iemand moet eigenaar zijn van de vraag of geld, voorraad en leveringen nog aantoonbaar kloppen.
Een Shopify API-cutover is de gecontroleerde overgang van één vaste Shopify API-versie naar een andere, waarbij je eerst dezelfde data met de nieuwe versie leest, uitkomsten vergelijkt, writes klein houdt en pas na menselijke vrijgave de nieuwe route activeert. Het bewijs bestaat uit order-, betaal-, voorraad- en fulfilmentrecords die naar dezelfde zakelijke gebeurtenis terugwijzen.
Op 13 oktober 2026 is 2026-10 de nieuwste stabiele Shopify-versie. Shopify brengt versies elk kwartaal uit, ondersteunt een stabiele versie minimaal twaalf maanden en adviseert een versie expliciet in je request-URL te zetten in de actuele versioningkalender. Dat maakt een cutover planbaar. Het maakt hem niet automatisch veilig.
Wat je nodig hebt voordat je iets omzet
Je hebt geen groot programma nodig om te beginnen. Je hebt wel een besluit, een bewijsmodel en een plek nodig waar de oude en nieuwe uitkomst naast elkaar kunnen bestaan. Zonder die drie dingen wordt een API-upgrade een gok met productieorders als testdata.
1. Een reconciliatie-eigenaar met mandaat
Benoem één persoon als reconciliatie-eigenaar. Dat is niet per se de ontwikkelaar. Deze persoon beslist of de vergelijking voldoende bewijs bevat om geld te laten boeken, fulfilment door te laten gaan en writes vrij te geven. Finance levert de financiële acceptatiecriteria, operations de fulfilmentcriteria en engineering de technische meetpunten. Eén naam houdt het besluit bij elkaar.
Leg vast:
- de geplande cutoverdatum en een tijdvenster met lage orderdruk;
- de systemen die geraakt worden, zoals Shopify, een WMS, een PSP, Moneybird of Exact Online;
- de zakelijke processen die niet mogen breken: orderimport, betaling, refund, voorraad, pick, verzending en retour;
- de toegestane noodmaatregel per proces, bijvoorbeeld tijdelijk handmatig vrijgeven;
- de naam die een stopbesluit mag nemen zonder nieuwe vergadering.
NIST SP 800-128, oorspronkelijk uit augustus 2011 en voorzien van errata op 10 oktober 2019, beschrijft change control als formeel aanvragen, vastleggen, impact analyseren, testen, goedkeuren en na uitvoering verifiëren in de change-controlprocedure. Voor een API-cutover vertaal ik dat naar één eigenaar die kan zeggen: nog niet vrijgeven.
2. Een afhankelijkhedenregister
Maak één tabel, niet vijf losse lijstjes in tickets. Noteer per onderdeel de huidige versie, de doelversie, de gebruikte query of mutatie, de relevante webhook of batch, de bronhouder, het effect bij een fout en de fallback. Voeg ook toe wie het bewijs beoordeelt.
| Onderdeel | Wat je registreert | Voorbeeld van acceptatiebewijs |
|---|---|---|
| Shopify Admin API | endpoint, versie, scopes, response-header | X-Shopify-API-Version is 2026-10 |
| Orders | queryvelden, order-ID, regels, valuta, belasting | aantallen, totalen en belastingen matchen |
| Betalingen | transactie-ID, gateway, status, bedrag, valuta | iedere geldactie heeft een provider-ID |
| Voorraad | SKU, inventoryItemId, locatie, state, bronhouder | geen onverklaarde delta per locatie |
| Fulfilment | fulfillment order, status, tracking, transfer-ID | pick en verzending wijzen naar dezelfde order |
| Webhooks | topic, payloadversie, delivery-ID, retry en timestamp | geen dubbele of onverklaarde delivery |
| Writes | mutatie, idempotency key, referentie-URI, read-back | response en nieuwe stand zijn opgeslagen |
| Boekhouding | factuur, creditnota, payout en boekings-ID | Finance kan de keten narekenen |
Gebruik zakelijke sleutels naast Shopify’s globale ID’s. Een ordernummer dat een medewerker ziet is handig, maar een technische order-ID, orderregel-ID, betaaltransactie-ID en fulfilment-ID zijn nodig om een event opnieuw te kunnen vinden. Dit sluit aan op de bestaande scheiding tussen order, betaaltransactie, payout en boeking.
3. Een testset die geld en dozen nabootst
Een testorder met één product en een succesvolle betaling is te vriendelijk. Leg in een testwinkel of afgeschermde administratie minimaal deze gevallen klaar:
- een normale betaalde order met één fulfilment;
- een order met twee regels en twee locaties;
- een gedeeltelijke refund;
- een geannuleerde order;
- een retour waarbij de geldactie later komt dan de fysieke ontvangst;
- een order met korting, btw en een adreswijziging;
- een voorraadtransfer en een ontvangst die tijdens de test binnenkomt;
- een dubbele webhook en een webhook die pas na een retry aankomt;
- een time-out na een write, zodat je herstelroute echt getest wordt.
Shopify’s release notes voor 2026-10, gecontroleerd op 13 oktober 2026, noemen onder meer nieuwe belastingberekening na een adreswijziging, de enum FULFILLMENT_NOT_REQUIRED, een asynchrone orderCancel-uitkomst en nieuwe identifiers bij voorraadzendingen in de versieaankondiging. Neem juist die randgevallen op in je testset.
4. Een duurzame bewijslaag
Bewaar niet alleen workflowlogs. Maak een tabel of dossier met minimaal cutover_id, bron-ID, doel-ID, aangevraagde versie, werkelijk gebruikte versie, payload-hash, gelezen uitkomst, nieuwe uitkomst, actie, idempotency key, status, foutreden, eigenaar en tijdstip.
Voor reads is dat een vergelijking. Voor writes is het een ledger vóór de actie. Een nieuwe poging met dezelfde zakelijke bedoeling gebruikt dezelfde sleutel. Een nieuwe zakelijke correctie krijgt een nieuwe sleutel en een nieuwe beslissing. De gids over financiële replay zonder dubbele boeking werkt dat onderscheid verder uit.
5. Toegang en tooling
Voor de Shopify GraphQL Admin API heb je de juiste read_*- en write_*-scopes nodig, plus een app of integratielaag die de gevraagde versie in de URL zet. Gebruik Shopify Flow alleen voor triggers, meldingen of eenvoudige doorsturing. Flow is gratis op Basic, Grow, Advanced en Plus, maar de actie Send HTTP Request is alleen beschikbaar op Grow, Advanced en Plus. De helpdocumentatie is gecontroleerd op 13 oktober 2026 op de Flow-pagina.
Voor een klein proces kan n8n of Make prima zijn. n8n rekent op workflowuitvoeringen. De Starter-prijs is op 13 oktober 2026 €20 per maand bij jaarlijkse betaling voor 2.500 uitvoeringen met onbeperkte stappen; Pro kost €50 voor 10.000 uitvoeringen. De Community Edition is zelf te hosten volgens de actuele prijspagina. Make rekent per handeling. Op 13 oktober 2026 is het gratis plan $0 met 1.000 credits per maand, Core $9 en Pro $16 per maand bij jaarlijkse betaling, met Teams op $29 op de actuele prijspagina. Dat zijn uitvoerlagen, geen reconciliatiedossier.
Vink dit af voordat je een productie-endpoint aanraakt. De lijst is kort. De uitwerking erachter is je veiligheidsnet.
Concrete stappen: van version pin naar menselijke vrijgave
De route hieronder is geen big bang. Eerst maak je de nieuwe route zichtbaar zonder dat hij schrijft. Daarna bewijs je dat de uitkomsten gelijk zijn, voer je een beperkte write uit, lees je terug wat er echt gebeurde en geef je pas dan de volgende groep vrij.
Stap 1: Zet de huidige toestand vast
Maak een nulmeting van één representatieve periode, bijvoorbeeld de laatste zeven dagen plus alle open orders. Leg per order vast: order-ID, regels, aantallen, subtotalen, btw, totalen, betaaltransacties, refunds, fulfilments, tracking en voorraadrelaties. Neem ook openstaande payouts en uitzonderingen mee.
Registreer tegelijk:
- de huidige API-versie in elke service, niet alleen in de hoofdapp;
- de response-header die Shopify werkelijk terugstuurt;
- de lijst van webhooks, hun payloadversie en delivery-ID’s;
- de laatste succesvolle reconciliatie en openstaande verschillen;
- geplande jobs, imports en exports die tijdens het venster kunnen lopen.
Als je request 2025-10 vraagt, maar de response-header al iets anders meldt, is dat geen detail. Shopify valt bij een ontoegankelijke versie door naar de oudste beschikbare stabiele versie. Een mismatch is dan meteen een stopteken, omdat je test niet meer bewijst wat je denkt te testen.
Stap 2: Pin de doelversie en maak de contractverschillen expliciet
Zet voor de productiecutover 2026-10 expliciet in de GraphQL-endpointconfiguratie. Gebruik de release candidate of unstable alleen voor ontwikkeling. Verwijder geen oude adapter voordat de nieuwe route stabiel is en de oude versie nog binnen de ondersteuningsperiode valt.
Maak per verschil een contractkaart:
| Wijziging | Risico | Test en besluit |
|---|---|---|
reserved en committed bij actieve conceptorders, transfers en zendingen | een rapport telt een hold dubbel of mist hem | vergelijk beide states en leg vast welke zakelijke hold je zoekt |
| adreswijziging op ongeleverde order herberekent belasting | betaling, refund of factuurtotaal wijkt af | wijzig adres, lees taxLines, totalen en betaalbalans opnieuw |
FULFILLMENT_NOT_REQUIRED kan terugkomen | een uitputtende statusvertaling markeert een order fout | behandel expliciet als aparte eindstatus |
orderCancel kan asynchroon eindigen | groen na request is nog geen geslaagde annulering | lees jobResult en de uiteindelijke orderstatus terug |
voorraadmutatie meldt niet meer ITEM_NOT_STOCKED_AT_LOCATION | foutafhandeling verwacht een verdwenen enum | test echte fouten en verwijder alleen de obsolete tak |
Shopify wijzigde op 5 augustus 2026 de betekenis van actieve voorraadholds: waarden die voor draft orders, transfers en shipments onder reserved stonden, verschuiven naar committed; available en on_hand veranderen niet in de changelog over die migratie. Dat is geen reden om blind twee velden op te tellen. Het is een reden om je zakelijke definitie van gereserveerde voorraad expliciet te maken.
Stap 3: Bouw shadow-read naast de bestaande route
Laat de huidige adapter productie blijven lezen en schrijven. Laat de nieuwe adapter dezelfde order, betaal-, voorraad- en fulfilmentdata met 2026-10 ophalen en opslaan zonder vervolgactie. Dit is shadow-read. Het is geen tweede import. De nieuwe route krijgt een eigen cutover_id en schrijft alleen naar je bewijslaag.
Vergelijk op vier niveaus:
- Identiteit. Komen dezelfde orders, regels, transacties en fulfilments terug?
- Betekenis. Zijn statussen, voorraadstates, belastingregels en valuta hetzelfde geïnterpreteerd?
- Bedrag en aantal. Kloppen totalen, aantallen, refunds en voorraad per locatie?
- Tijd. Zijn
createdAt,updatedAt, webhook-tijd en verwerkingstijd logisch?
Gebruik een tolerantie alleen waar de bron dat verklaart, bijvoorbeeld afronding in een valuta. Een ontbrekende refund of fulfilment is geen afronding.
Stap 4: Reconcileer gebeurtenissen, niet alleen records
Een recordvergelijking kan groen zijn terwijl het proces breekt. Vergelijk daarom de keten per order:
order aangemaakt → betaling bevestigd → voorraad gereserveerd → fulfilment vrijgegeven → zending gemeld → refund of retour verwerkt → boeking of payout gematcht
Shopify-webhooks zijn nuttig als bijna-realtime trigger, maar ze zijn geen complete waarheid. Shopify zegt expliciet dat de volgorde binnen en tussen topics niet gegarandeerd is, dat delivery kan missen en dat je periodiek via de API moet reconciliëren in de webhookdocumentatie. Gebruik de webhook om een order in de wachtrij te zetten. Gebruik een periodieke query op updated_at om te controleren wat werkelijk is gebeurd.
Controleer ook de headers X-Shopify-Webhook-Id, X-Shopify-Hmac-Sha256 en X-Shopify-Api-Version. Een dubbele delivery is dan een herhaling van dezelfde brongebeurtenis, geen nieuwe order. Een event met een oudere updated_at mag een nieuwere toestand niet terugzetten.
Stap 5: Test drie keer met een echte releasekandidaat
Draai eerst een synthetische testset, daarna een replay van echte productiedata zonder writes en ten slotte een proefvenster met één kleine ordergroep. Geef elke run een eigen versie, input-hash en uitkomst. Laat de reconciliatie-eigenaar de uitzonderingen lezen, niet alleen het groene percentage.
De acceptatiecriteria zijn concreet:
- iedere geselecteerde order is terug te vinden met dezelfde zakelijke sleutel;
- totalen, btw en valuta kloppen of hebben een verklaarde transformatie;
- elke betaalactie en refund wijst naar een providerobject;
- voorraadverschillen zijn per SKU en locatie verklaard;
- fulfilmentstatussen en tracking zijn semantisch vertaald;
- dubbele, late en ontbrekende webhooks eindigen in dezelfde eindtoestand;
- geen request gebruikt een andere API-versie dan bedoeld;
- iedere uitzondering heeft een eigenaar en een volgende beslissing.
Een nulmeting met alleen gemiddelde aantallen is onvoldoende. Eén gemiste refund van €2.400 kan belangrijker zijn dan 10.000 goed ingelezen orders.
Stap 6: Beperk writes tot een gecontroleerde proefgroep
Laat de oude route nog steeds de productiebron zijn. Kies een kleine proefgroep met lage financiële en operationele risico’s. Schrijf niet tegelijk orders, voorraad en refunds om de route snel volledig te maken. Kies per domein één write en zet de rest op pending totdat het read-back-bewijs er is.
Voor voorraad is inventoryAdjustQuantities de delta-mutatie. De actuele referentie voor API 2026-10 vereist write_inventory, een reden, een optionele referentie-URI en sinds API 2026-04 een idempotency key via @idempotent; Shopify geeft een InventoryAdjustmentGroup en userErrors terug in de mutationdocumentatie.
Gebruik inventorySetQuantities alleen als jouw WMS of centrale voorraadlaag de bronhouder is. De mutatie werkt met compare-and-set via compareQuantity; zonder gelijke gelezen stand hoort hij te falen. Shopify waarschuwt dat je bij gelijktijdige requests onjuiste aantallen kunt krijgen als je de compare-check uitschakelt in de set-mutatie.
Voor iedere write bewaar je:
{
"cutover_id": "CUT-2026-10-13-001",
"business_action": "inventory-correction",
"source_id": "WMS-8841",
"target": "shopify:inventoryAdjustQuantities",
"api_version": "2026-10",
"idempotency_key": "CUT-2026-10-13-001:WMS-8841",
"reference_uri": "stocktake://CUT-2026-10-13-001",
"status": "staged"
}
Een time-out maakt de status unknown, niet failed. Zoek eerst je eigen ledger, de bestaande Shopify-mutatie en de providerrespons. Een retry met dezelfde bedoeling gebruikt dezelfde sleutel. Shopify houdt idempotency keys voor mutaties met @idempotent 24 uur bij en behandelt dubbele requests binnen die periode volgens de oorspronkelijke status in de idempotentierichtlijnen. Bewaar daarom ook buiten Shopify je eigen bewijs voor herstel na die periode.
Stap 7: Lees terug wat er echt is veranderd
Na iedere proefwrite haal je de bron en het doel opnieuw op. Kijk niet alleen naar HTTP 200. Controleer userErrors, de adjustment- of job-ID, de nieuwe quantity, ordertotalen, betaalstatus, fulfilmentstatus en de opgeslagen auditregel.
Bij een orderwijziging met nieuw bezorgadres lees je belastingregels en betaalbalans opnieuw. Bij orderCancel wacht je op de asynchrone uitkomst. Bij voorraad lees je per locatie de states opnieuw. Bij fulfilment controleer je dat tracking en orderregel nog dezelfde zakelijke relatie hebben.
Pas wanneer read-back gelijk is aan de verwachte business-uitkomst gaat de proefgroep naar released. Een technische response zonder read-back is een aanvraag, geen bewijs.
Stap 8: Vergroot in ringen en sluit de change af
Werk met ringen: proefgroep, één fulfilmentroute, één betaalmethode, één voorraadlocatie, daarna de rest.
Leg vóór de eerste ring deze rollbackcriteria vast, zodat een groen gemiddelde een ernstige fout niet maskeert.
| Afwijking | Gevolg | Beslissing en hervatting |
|---|---|---|
De response-header is niet 2026-10, een contractfout raakt meerdere ringen, een order, betaling, refund of fulfilment ontbreekt of dupliceert, er is een onverklaarde financiële delta, een write blijft unknown of wordt dubbel uitgevoerd, twee schrijvers zijn actief, of de ledger/reconciliatiejob kan de gebeurtenissen niet volledig vastleggen | Hele cutover stoppen. Zet alle nieuwe writes uit, houd eventopvang en bewijsregistratie actief en val alleen terug op de ondersteunde oude adapter nadat de stopbeslissing is vastgelegd. | De reconciliatie-eigenaar neemt het stopbesluit. Hervatting mag pas na oorzaak en impactanalyse, herstel van de route, reconciliatie of veilige replay van de getroffen events, groen read-back-bewijs op de getroffen data en akkoord van Finance bij geld of Operations bij fulfilment. De eigenaar legt de nieuwe vrijgave vast. |
| De afwijking blijft aantoonbaar binnen één ring en één domein, bijvoorbeeld één niet-vertaalde status, één SKU-locatieverschil of eventlag boven de vooraf afgesproken ringgrens, zonder geldverschil, dubbele of onbekende write, gedeelde ledgerfout of effect op een andere ring | Alleen die ring blokkeren. Zet de writes van de ring uit; andere ringen mogen alleen door als hun onafhankelijkheid in het dossier staat. | De reconciliatie-eigenaar blokkeert de ring. Hervatting mag na herstel, een nieuwe run van die ring, groen read-back- en eventreconciliatiebewijs en expliciete vrijgave door de eigenaar; Finance of Operations tekent mee als het eigen domein geraakt is. |
Na elke ring draait een reconciliatiejob en controleert de eigenaar de uitzonderingen. Laat de oude adapter nog even naast de nieuwe route bestaan voor reads, niet om twee schrijvers tegelijk actief te laten.
Zet de wijziging pas op complete als:
- alle afgesproken businessprocessen een groen read-back-resultaat hebben;
- de laatste eventlag binnen de afgesproken grens valt;
- er geen eigenaarloze uitzonderingen zijn;
- de oude route aantoonbaar niet meer schrijft;
- monitoring, runbook en contactpersonen zijn bijgewerkt;
- de reconciliatie-eigenaar expliciet heeft vrijgegeven.
De overgang is pas geslaagd als de nieuwe route dezelfde bedrijfsuitkomst kan verklaren. Niet als de nieuwe query toevallig minder fouten logt.
Valkuilen die je livegang laten ontsporen
Je test de query, niet de bedrijfsuitkomst
Een query kan dezelfde velden teruggeven en toch een andere beslissing veroorzaken. Een nieuw belastingveld, statusenum of voorraadstate kan downstream een andere route activeren. Schrijf per veld op wat het bedrijf ermee doet: boeken, picken, annuleren, terugbetalen of niets doen. Test daarna de beslissing.
Je laat twee schrijvers tegelijk actief
Een oude adapter die nog voorraad schrijft en een nieuwe adapter die ook schrijft, maakt reconciliatie bijna onmogelijk. Zet de oude route in read-only of schakel per domein uit. Twee lezers zijn tijdelijk nuttig. Twee schrijvers zijn een race.
Je vertrouwt op webhookvolgorde
Shopify garandeert niet dat een update na een create aankomt. Gebruik delivery-ID voor ontdubbeling, updated_at voor volgorde en een periodieke reconciliatie voor gemiste events. Een queue met retries is geen vervanging voor een controlejob.
Je telt reserved als universele reservering
De betekenis van een inventory state hangt af van het proces. Vanaf de Shopify-wijziging van augustus 2026 kunnen actieve holds van conceptorders, transfers en shipments onder committed vallen. Maak je normalisatie daarom gericht op de bedrijfsbetekenis: welke hoeveelheid is al toegezegd, aan welke order of transfer en tot wanneer?
Je maakt van een API-versie een rollbackknop
Een versiewissel terugzetten draait geen al uitgevoerde refund, voorraadmutatie of fulfilmentactie terug. Zet writes uit, bewaar de events, gebruik een nog ondersteunde adapter als die bestaat en laat Finance of operations een expliciete herstelactie vrijgeven. Een downgrade zonder bewijs maakt het spoor juist onduidelijker.
Je gebruikt een nieuwe idempotency key na een time-out
De eerste write kan geslaagd zijn terwijl het antwoord verloren ging. Een nieuwe sleutel voert dezelfde zakelijke actie opnieuw uit. Zoek eerst op cutover_id, sleutel en doelobject. Alleen een nieuwe beslissing krijgt een nieuwe sleutel.
Je laat Shopify Flow een kritieke beslissing dragen
Flow is handig voor meldingen en eenvoudige acties. De Send HTTP Request-actie wacht maximaal 30 seconden en kan bij fouten tot 24 uur opnieuw proberen. Dat is nuttige infrastructuur, maar zonder eigen ledger en business-key weet Flow niet of een eerdere write al geslaagd was in de actuele actiehandleiding. Gebruik Flow niet als enige bron voor financiële of voorraadreconciliatie.
Je maakt rollback afhankelijk van blauwgroen wisselen
Martin Fowler beschreef blue-green deployment op 1 maart 2010 en werkte het stuk in 2015 bij. De router snel terugzetten kan software terugschakelen, maar gemiste transacties en datamutaties blijven een apart probleem in zijn uitleg over blue-green deployment. Voor Shopify betekent dit: maak eerst je eventledger en read-back betrouwbaar. Pas daarna helpt een parallelle adapter echt.
Beslis-kader: welke cutover-aanpak past bij jouw risico?
De keuze gaat niet over de vraag of je Shopify Flow, Make of n8n prettig vindt. De echte keuze is hoeveel bewijs en herstel je nodig hebt voordat een fout geld of fulfilment raakt. Leg vier vragen langs je situatie: hoeveel writes doet de koppeling, hoeveel systemen bezitten een deel van de waarheid, hoe duur is een fout en wie beheert de route na livegang?
Kies een standaardroute bij lage impact
Een standaardroute past als de koppeling vooral leest, weinig writes doet, één bronhouder heeft en een medewerker de uitkomst snel kan controleren. Shopify Flow of Make kan dan een melding, label of eenvoudige doorsturing uitvoeren. Gebruik de ingebouwde retries niet als financiële zekerheid. Sla de bron-ID, doel-ID en beslissing alsnog op.
Kies orkestratie met eigen bewijs bij middelhoge impact
n8n of Make past wanneer je meerdere API’s, wachtrijen, meldingen en uitzonderingen nodig hebt, maar de kernbeslissing overzichtelijk blijft. Laat n8n of Make de stappen aanroepen. Zet de bron van waarheid, idempotency key, reconciliatie en menselijke vrijgave in een eigen tabel. Zo kun je de workflowtool vervangen zonder het bedrijfsgeheugen kwijt te raken.
Kies maatwerk bij hoge impact
Bouw een eigen adapter wanneer de koppeling refunds, voorraadcorrecties, fulfilmentvrijgave of meerdere boekhoudroutes schrijft. Maatwerk is hier geen prestigeproject. Het geeft je versiepinning, contracttests, shadow-read, ringgewijze vrijgave, read-back, dead-letterqueue en een herstelbesluit op maat. De kosten zitten in ontwerp, testdata, monitoring en beheer, niet alleen in de eerste API-call.
Gebruik deze beslisregel: hoe onomkeerbaarder de write en hoe meer bronhouders, hoe minder je mag leunen op een kant-en-klare workflow zonder eigen bewijslaag. Als de kern alleen een melding of niet-kritieke tag is, is maatwerk overkill. Als de kern een refund of voorraadbelofte is, is alleen een groene run te weinig.
Wat doet je koppeling tijdens de cutover?
De keuzehulp geeft dezelfde drie uitkomsten als het geschreven kader: standaardroute, orkestratie met eigen bewijslaag of maatwerkadapter. Het verschil is alleen dat je sneller ziet waar jouw risico ligt.
Uitgewerkt voorbeeld: een order naar geld en fulfilment volgen
Neem een Nederlandse webshop met Shopify, een PSP, een WMS en Exact Online. De koppeling draait op 2025-10 en verwerkt nieuwe orders, voorraadreserveringen, fulfilmentmeldingen en refunds. Op 13 oktober 2026 staat een cutover gepland naar 2026-10. De winkel ontvangt op een normale dag ongeveer 180 orders. Dat getal is alleen de casusgrootte, niet een algemene grens voor automatisering.
De reconciliatie-eigenaar maakt eerst één dossier: CUT-2026-10-13-001. Engineering legt vast dat de huidige route orders leest met 2025-10, het WMS de bronhouder is van verkoopbare voorraad en Exact Online de boekingsbeslissing bezit. Finance bepaalt dat een bedrag, valuta, belastingregel, PSP-transactie en boekings-ID aan elkaar moeten hangen. Operations bepaalt dat een fulfilment pas door mag als SKU, aantal en locatie kloppen.
Nulmeting
In de openstaande ordergroep staan 37 orders. Daarvan hebben 31 één fulfilment, vier twee fulfilments en twee een gedeeltelijke refund. Er staat één transfer tussen magazijn Noord en magazijn Zuid open. Shopify toont voor SKU JAS-OL-42 in Noord 24 beschikbare stuks; het WMS heeft 22 verkoopbare stuks en twee stuks in kwaliteitscontrole. De nulmeting noteert dit als verklaard verschil, niet als fout.
De nieuwe adapter leest met 2026-10 dezelfde 37 orders. Hij ziet bij één order de status FULFILLMENT_NOT_REQUIRED, omdat de order geen resterende fulfilbare hoeveelheid heeft. De oude adapter kende alleen UNFULFILLED en zou deze order als fout hebben gemarkeerd. De contracttest krijgt daarom een nieuwe expliciete statusmapping.
Shadow-read en zakelijke vergelijking
De nieuwe route leest voor order #10482 dezelfde orderregels en betaaltransactie. De order heeft een adreswijziging die nog niet gefactureerd is. 2026-10 herberekent de belasting. De nieuwe adapter haalt daarom opnieuw taxLines, totalTaxSet, ordertotalen en betaalbalans op. Finance markeert de oude en nieuwe uitkomst als verschillend, maar niet als defect. De nieuwe versie is hier juist de betere bron van de actuele uitkomst.
Voor de transfercontrole vergelijkt de adapter inventory_transfer_id uit de voorraadshipment-events met de transfer in het WMS. Voor JAS-OL-42 telt hij available niet samen met committed, reserved en quality_control. Het WMS blijft de bronhouder van verkoopbare aantallen. De twee stuks kwaliteitscontrole mogen dus niet door de nieuwe route als verkoopbare voorraad worden gepubliceerd.
Beperkte write
De proefgroep bevat drie nieuwe orders met lage orderwaarde en één voorraadwrite op de gecontroleerde transfer. De voorraadwrite gebruikt inventoryAdjustQuantities met delta -2, reden correction, referentie stocktake://CUT-2026-10-13-001 en een vaste idempotency key. De order- en refundwrites blijven nog op pending. Zo kan de eigenaar de technische write en de operationele read-back los beoordelen.
Na de call staan userErrors leeg en is een InventoryAdjustmentGroup opgeslagen. De adapter leest available, on_hand en de relevante locatie opnieuw op. Het WMS-event voor de transfer komt twee keer binnen. De tweede delivery heeft een andere delivery-ID, maar dezelfde zakelijke transfer-ID. De ledger verwerkt hem als dubbele bezorging en verandert de voorraad niet opnieuw.
Vrijgave of stop
De proefgroep voldoet aan de criteria. De 37 openstaande orders zijn terug te vinden, de adreswijziging heeft een verklaarde belastingmutatie, de fulfilmentstatus is volledig vertaald, de voorraadwrite is teruggelezen en de dubbele transfer is ontdubbeld. De eigenaar geeft eerst de fulfilmentroute vrij, daarna orders en ten slotte refunds.
Stel dat bij de volgende ring een refund twee keer in de doeladministratie dreigt te komen. De juiste actie is niet de nieuwe adapter stilletjes opnieuw starten. De eigenaar zet alle refundwrites op stop, laat reads en eventopvang doorlopen, zoekt de bestaande doelboeking op met de business key en bepaalt of een correctie nodig is. De andere ringen kunnen alleen door als zij geen afhankelijkheid van die refundroute hebben.
Dit is het verschil tussen een technische uitrol en een bedrijfswijziging. De vraag is niet alleen of de nieuwe query antwoord geeft. De vraag is of je nog kunt bewijzen wat er met een order, euro, voorraadstuk en zending is gebeurd.
Vergelijkingstabel: kant-en-klaar, orkestratie of maatwerk
| Route | Concrete tool | Kosten en actuele details, gecontroleerd op 13 oktober 2026 | Goed als | Breekpunt |
|---|---|---|---|---|
| Shopify-intern | Shopify Flow | Gratis app op Basic, Grow, Advanced en Plus. Send HTTP Request alleen op Grow, Advanced en Plus. | Meldingen, tags, eenvoudige routes en niet-kritieke acties | Geen eigen reconciliatieledger of versiecontract |
| Visuele orkestratie | Make | Free $0 met 1.000 credits per maand. Core $9, Pro $16, Teams $29 per maand bij jaarlijkse betaling. Elke modulehandeling kost credits. | Veel apps, lage tot middelhoge impact, snel testen | Credits, retries en uitvoerlogs zijn geen businessbewijs |
| Technische orkestratie | n8n | Starter €20 per maand bij jaarbetaling voor 2.500 uitvoeringen, Pro €50 voor 10.000. Community Edition zelf te hosten. | Wachtrijen, eigen code, API’s en self-hosted beheer | Zonder eigen ledger blijft het een workflow met goede techniek |
| Eigen adapter | Shopify GraphQL Admin API 2026-10 plus staging en vrijgavescherm | Geen losse Shopify API-licentieprijs; bouw, test, monitoring en beheer zijn de echte kosten | Refunds, voorraad, fulfilment en meerdere bronhouders | Te duur als niemand eigenaar wordt van onderhoud en reconciliatie |
De standaardroute wint wanneer de actie klein en herstelbaar is. Make wint op snelheid wanneer elke credit en retry begrijpelijk blijft. n8n wint wanneer technische controle, eigen hosting en API-logica belangrijk zijn. Maatwerk wint zodra één verkeerde write direct geld, voorraad of fulfilment kan raken.
Mijn voorkeur voor een kritieke Shopify-koppeling is niet automatisch maatwerk. Eerst bepaal ik de bronhouders, de foutkosten en de gewenste menselijke beslissing. Is het antwoord daarop eenvoudig, dan kan een bestaande tool volstaan. Is het antwoord verdeeld over Shopify, PSP, WMS en boekhouding, dan bouw ik een bewijslaag die de toolkeuze overleeft.
De vrijgave is het product
Een API-versie is een technische instelling. Een cutover is een verandering in de manier waarop je bedrijf orders, geld en voorraad vertrouwt. Daarom hoort de laatste knop niet bij de ontwikkelaar die de query groen krijgt, maar bij de eigenaar die kan uitleggen waarom de order, betaling, voorraadbeweging en fulfilment nog dezelfde werkelijkheid beschrijven.
Als je dat bewijs vooraf organiseert, wordt een Shopify-upgrade geen sprong. Het wordt een reeks kleine besluiten met een zichtbare uitkomst, een eigenaar en een terugweg.
Veelgestelde vragen
Shopify-cutover laten bouwen?
Ik breng de afhankelijkheden, reconciliatie en vrijgave samen en bouw de Shopify-koppeling end-to-end rond je orders, voorraad, fulfilment en boekhouding.
Dit artikel is geproduceerd samen met het Agent Team. Meer over de redactie.
