Hoe je leveranciersfacturen omzet in Shopify-productpagina's met n8n en AI
Gepubliceerd op 13 oktober 2026·Door Stijn Scheltinga Koopman
Elke leveranciersfactuur verbergt een klus: van elke nieuwe regel een volledige, goed ingedeelde Shopify-productpagina maken. Voor een specialistische slijterij bouwden we een n8n-systeem dat dit voor hen doet. Een factuur gaat Slack in, en het team krijgt onderzochte, beschreven en van de juiste kenmerken voorziene producten terug, klaar om met één klik goed te keuren.
Dit artikel laat zien hoe het werkt: de architectuur, de ontwerpkeuzes erachter, en de onderdelen die lastiger bleken dan verwacht. Het is geen klik-voor-klik-handleiding, want het volledige systeem beslaat vier workflows. Het is de blauwdruk die je nodig hebt om je eigen versie te bouwen, of je nu een winkel hebt en je weg weet in n8n, of een ontwikkelaar bent die de aanpak afweegt.
Het probleem: een factuur is geen productpagina
Een factuur zegt wat er binnenkwam: een productnaam, een code, een aantal en een prijs. Een goede productpagina heeft veel meer nodig. Bij een whisky zijn dat de distilleerderij, de bottelaar, het land, de regio, het vattype en een tekst die de fles ook echt verkoopt.
Vóór de automatisering moest iemand elk nieuw product met de hand uitzoeken, de gegevens overnemen in Shopify en per kenmerk de juiste waarde kiezen. Voor een specialistische winkel met een grote, gedetailleerde catalogus telt dat snel op, en onderweg sluipen er kleine inconsistenties in.
De voor de hand liggende weg is de productnaam in ChatGPT plakken en om een productpagina vragen. In de praktijk loopt dat op drie manieren spaak:
- Het verzint feiten. Een taalmodel vult vol overtuiging een vattype of leeftijdsaanduiding in die het helemaal niet weet.
- Het negeert je catalogus. Het schrijft misschien "Speyside, Scotland" terwijl jouw winkel "Speyside" gebruikt, of het verzint een nieuwe spelling van een distilleerderij die je al voert. Elke inconsistentie laat een filter of een collectie stilletjes stuklopen.
- Het weet niet wat je al verkoopt. Een aangevuld product heeft een voorraadupdate nodig, geen dubbele productpagina.
Het systeem hieronder is om die drie problemen heen gebouwd. Het zoekt echte bronnen op, dwingt elk antwoord in de waarden die de winkel al gebruikt, kijkt eerst in de catalogus, en houdt een mens in de lus voordat er iets live gaat.
De architectuur: vier workflows, elk met één taak
Het systeem is opgesplitst in vier n8n-workflows. Invoice Parsing leest de factuur en controleert die tegen de catalogus, Products Sync houdt die catalogus actueel, Creation Flow verwerkt elke knopklik in Slack, en Error Workflow houdt de rest in de gaten.

Aangevulde producten slaan de AI helemaal over en krijgen alleen hun voorraad bijgewerkt. Nieuwe producten gaan door onderzoek en matching, en elk resultaat komt in Shopify binnen als concept dat het team controleert voordat het publiceert.
Stap 1: Maak van de factuur-pdf gestructureerde regels
De eerste workflow start wanneer iemand een factuur uploadt in een apart Slack-kanaal. Een Slack Trigger gaat af, een If-node controleert of het bericht echt een bestand bevat, en de bot antwoordt meteen zodat het team weet dat de factuur is opgepakt.
Daarna downloadt de workflow de pdf via de API van Slack en haalt die door de Extract from File-node van n8n om de ruwe tekst te krijgen. Die tekst gaat naar een AI Agent met een Structured Output Parser eraan. Die parser maakt dit betrouwbaar: in plaats van vrije tekst moet de agent een JSON-array van regels teruggeven, met vaste velden zoals naam, productcode en aantal.
Een Split Out-node maakt van die array vervolgens één item per product, zodat elke volgende stap met één product tegelijk werkt.
Kijk wat je al verkoopt
Tegelijk roept de workflow een sub-workflow aan die de Shopify-catalogus synchroniseert naar een n8n-datatabel, en leest die daarna terug. Een Code-node vergelijkt elke factuurregel met die catalogus, en een If-node splitst de resultaten:
- Al in Shopify: het product krijgt een Slack-bericht met de optie om het gefactureerde aantal aan de voorraad toe te voegen.
- Nog niet in Shopify: het product krijgt een Slack-bericht met de optie om het aan te maken.
Beide paden bouwen hun berichten met de Block Kit van Slack, worden weer samengevoegd en als één overzicht van de factuur in het kanaal geplaatst. Op dit moment is er in Shopify nog niets veranderd. Het team beslist wat er daarna gebeurt.
Stap 2: Onderzoek het product op het web
Wanneer iemand op aanmaken klikt, stuurt Slack de klik naar een webhook in de tweede workflow. Het eerste wat die workflow doet is onderzoek: twee webzoekopdrachten lopen parallel via de zoek-API van Tavily, en een Merge-node voegt de resultaten samen.
We gebruiken een zoek-API die voor AI is gebouwd, in plaats van Google te scrapen, omdat die schone paginainhoud teruggeeft in plaats van HTML. Daardoor blijven de prompts kort en de kosten voorspelbaar.
Een relevantiecheck vóór het dure deel
Zoekresultaten gaan niet altijd over het juiste product. Een limited edition kan een naam delen met een standaardbotteling, of een kleine producent is online nauwelijks te vinden. Daarom leest eerst een Relevantie-agent de resultaten en beslist of ze echt het product op de factuur beschrijven.

Doen ze dat niet, dan stopt de workflow en laat het team dat in Slack weten. Deze ene check voorkomt de schadelijkste fout: een zelfverzekerde, goed geschreven productpagina over de verkeerde whisky.
Haal de feiten eruit
Als de resultaten door de check komen, haalt een Extractie-agent de ruwe feiten op: producent, bottelaar, land, regio, vattype enzovoort. Zoals elke agent in dit systeem geeft hij gestructureerde output terug, zodat latere stappen altijd dezelfde velden krijgen. In deze fase staan de waarden nog in de vorm die de bronnen gebruikten. Ze omzetten naar de eigen waarden van de winkel is de volgende stap.
Stap 3: Koppel elk kenmerk aan je eigen catalogus
Dit is het deel dat de output bruikbaar maakt in een echte winkel. In plaats van de AI te laten beslissen wat er in elk veld komt, krijgt elk kenmerk een eigen kleine matcher die alleen mag kiezen uit waarden die de winkel al gebruikt.
Na de extractie waaiert de workflow uit in parallelle takken, één per kenmerk: land, regio, distilleerderij, bottelaar en vattype. Elke tak volgt hetzelfde patroon van vier nodes:

- If: heeft de extractie überhaupt een waarde voor dit kenmerk gevonden? Zo niet, dan wordt de tak overgeslagen in plaats van te gokken.
- Get row(s): laad de toegestane waarden voor dit kenmerk uit een n8n-datatabel, elk opgeslagen samen met zijn Shopify-ID.
- Code: zet die lijst samen met de geëxtraheerde waarde om in een compacte prompt.
- Matcher-agent: kies de dichtstbijzijnde bestaande waarde en geef het Shopify-ID terug, via een structured output parser.
Zegt een bron dus "Speyside region, Scotland", dan geeft de regio-matcher exact "Speyside" terug, want dat is de optie in de lijst van de winkel. Spelt een bron een distilleerderij net iets anders, dan koppelt de distilleerderij-matcher die aan de spelling die de winkel op andere producten al gebruikt.
Eén keer vastleggen, op elke fles hergebruiken
Elke rij in die tabellen bevat een waarde en het ID van het bijbehorende item in Shopify. De regio-matcher geeft dus niet alleen de tekst "Speyside" terug. Hij geeft het ID terug van het Speyside-item dat al in de winkel staat, en het nieuwe product wordt daaraan gekoppeld.
Daardoor is de rijkere content van de winkel herbruikbaar. De achtergrond van een distilleerderij of het verhaal van een bottelaar wordt één keer in Shopify geschreven, en elke nieuwe fles die eraan gekoppeld is toont die content automatisch. De AI hoeft die nooit opnieuw te schrijven, en de tekst kan niet uit de pas lopen tussen producten.
Waarom losse agents in plaats van één?
We hadden één agent kunnen vragen om alle velden tegelijk in te vullen. We hebben het opgesplitst om twee redenen. Elke matcher ziet alleen de referentielijst die hij nodig heeft, waardoor prompts kort en gericht blijven, en een smallere taak levert meestal minder fouten op. De keerzijde is meer modelaanroepen per product. Daar komen we bij de lessen op terug.
De beschrijving en proefnotities schrijven
Naast de matchers schrijft een Beschrijvingsagent de inhoud van de productpagina. Die draait parallel, dus hij voegt geen extra wachttijd toe. Naast de beschrijving geeft hij ook een titel in de huisstijl en smaaknotities terug. Elk veld mag een lege string zijn wanneer de bronnen niets zeggen. Zo kan de agent expliciet toegeven dat hij het niet weet, in plaats van notities te verzinnen.
Tot slot verzamelt een Merge-node elke tak, en zet een Code-node het volledige product voor Shopify in elkaar.
Stap 4: Beslis in Slack, controleer in Shopify
Mensen houden de regie op twee momenten: voordat een product wordt aangemaakt, en voordat het live gaat.
- In Slack, vóór het aanmaken. Elk nieuw product in het factuuroverzicht heeft drie knoppen. Accepteren start het onderzoek en het aanmaken, Afwijzen slaat het product over, en Bewerken opent een Slack-modal om eerst de gegevens te corrigeren.
- In Shopify, vóór publicatie. Elk gegenereerd product wordt als concept aangemaakt en nooit automatisch gepubliceerd. Het team controleert het in Shopify, zoals het in de winkel zal verschijnen, en publiceert het wanneer het klopt.
Dit stelt winkeleigenaren gerust wanneer AI hun catalogus aanraakt. De automatisering doet het trage onderzoek en de gegevensinvoer, maar iemand die de producten kent heeft het laatste woord, in het programma waarmee ze de winkel al draaien.
Eén webhook, veel knoppen
Slack stuurt elke interactie van je app (knopklikken, modal-inzendingen) naar één URL. De aanmaak-workflow begint daarom met een Webhook-node, een Code-node die de payload van Slack uitpakt, en een Switch-node die elke actie naar een eigen tak stuurt: accepteren, afwijzen, bewerken, bewerking opslaan en voorraad toevoegen.
Houd je aan de drie-secondenregel van Slack
Slack verwacht dat je app een interactie binnen drie seconden bevestigt, anders ziet de gebruiker een fout. Een product onderzoeken duurt veel langer. Daarom is in de meeste takken de allereerste node Respond to Webhook, die de klik meteen bevestigt, waarna het echte werk verdergaat.
De modal is de uitzondering. Wanneer iemand een bewerking opslaat, bepaalt het antwoord dat je terugstuurt wat er met de modal gebeurt. Die tak doet het werk dus eerst en antwoordt aan het eind.
Ingebouwde nodes versus HTTP-requests
Je ziet dat verschillende Slack- en Shopify-stappen HTTP Request-nodes gebruiken in plaats van de ingebouwde nodes van n8n. Dat is bewust. Modals openen en bijwerken en rijke Block Kit-berichten versturen hebben Slack-API-methodes nodig die de ingebouwde node niet volledig dekt, en voorraadupdates in Shopify stuur je direct via de API makkelijker aan. Bewaar je tokens in n8n-credentials, niet in de request-headers, zodat ze nooit in een geëxporteerde workflow belanden.
Stap 5: Houd het betrouwbaar
Twee ondersteunende workflows doen niets wat je ziet, maar zonder hen houdt het systeem dagelijks gebruik niet vol.
Products Sync houdt een kopie van de Shopify-catalogus bij in een n8n-datatabel. Een factuur controleren tegen een lokale tabel is sneller en eenvoudiger dan voor elke regel door de Shopify-API bladeren. De factuur-workflow roept hem aan als sub-workflow vóór het matchen, zodat de vergelijking altijd op actuele data draait.
Error Workflow staat ingesteld als error handler voor de andere workflows in hun n8n-instellingen. Faalt een node, of dat nu een timeout is, een verlopen token of een onverwachte pdf-indeling, dan waarschuwt hij het team in plaats van stil te falen. Bij een systeem dat zelfstandig draait is een stille fout de ergste soort: facturen stapelen zich op en niemand merkt het, tot een product in de winkel ontbreekt.
Wat we leerden
Het systeem draait in productie, maar een paar dingen werden pas duidelijk toen dat zo was. Bouw je iets vergelijkbaars, dan is dit het waard om vooraf te weten.
Gestructureerde output is niet optioneel. Elke agent in dit systeem heeft een Structured Output Parser. Zonder die parser breekt één raar opgemaakt antwoord elke node daarna. Met de parser gedraagt elke agent zich als een voorspelbare functie.
Reken op producten die het internet niet kent. Kleine onafhankelijke bottelingen hebben soms bijna geen informatie online. Op dit moment maakt de workflow een placeholder-product in Shopify aan en waarschuwt het team wanneer de relevantiecheck faalt.
Ken je kosten per product. Het werk verdelen over één agent per kenmerk verbetert de nauwkeurigheid, maar het betekent veel modelaanroepen per product. Meet wat het aanmaken van één product kost en hoe lang het duurt, zodat je kunt beoordelen of een kleiner model of een samengevoegde agent voor sommige velden zinvoller is.
Splits grote workflows vroeg. De aanmaak-workflow doet zowel de Slack-interacties als de hele verrijkingspipeline. Als we hem opnieuw bouwden, zouden we de verrijking in een eigen sub-workflow zetten, zodat die apart te testen is en ergens anders herbruikbaar.
Tot slot

Het eindresultaat: klik op publiceren en de fles staat live.
De echte waarde zit niet in één enkele AI-aanroep. Die zit in de structuur eromheen: kijk wat je al verkoopt, onderzoek echte bronnen, weiger te gokken wanneer de bronnen fout zijn, dwing elk antwoord in de waarden van je eigen catalogus, en laat een mens het resultaat controleren voordat het live gaat. Dat patroon werkt voor elke winkel met gedetailleerde productdata, of je nu sterke drank, wijn, koffie, boeken of onderdelen verkoopt.
Wil je zien wat dit in de praktijk voor de winkel veranderde? Lees de case. En wil je een systeem als dit, gebouwd rond je eigen catalogus en leveranciers, neem dan contact op.
