Shopify en AFAS
Shopify AFAS koppeling
Orders uit Shopify staan als verkooporder in AFAS Profit, op de juiste verkooprelatie en het juiste magazijn. Debiteuren, prijsafspraken, staffels en voorraad per magazijn komen uit AFAS terug in Shopify B2B. Gebouwd op de connectoren van jouw omgeving, en daarna door ons gedraaid en bewaakt.
Wat je tussen Shopify en AFAS koppelt
AFAS Profit geeft gegevens vrij via connectoren: een GetConnector leest, een UpdateConnector schrijft. Shopify geeft ze vrij via de GraphQL Admin API en meldt wijzigingen met webhooks. AFAS heeft geen webhooks voor orders, artikelen of voorraad. Dat bepaalt de vorm van de koppeling: wat uit Shopify komt gaat direct, wat uit AFAS komt gaat in rondes.
| Stroom | Richting | Shopify | AFAS Profit |
|---|---|---|---|
| Orders | naar AFAS | webhook orders/create of orders/paid |
UpdateConnector FbSales |
| Zakelijke klanten | beide kanten | Company, CompanyLocation |
KnSalesRelationOrg |
| Prijzen en staffels | naar Shopify | catalogus met prijslijst | GetConnector Profit_SalesPrice |
| Voorraad per magazijn | naar Shopify | inventorySetQuantities per locatie |
GetConnector Profit_Stock |
| Artikelen | naar Shopify | productSet |
GetConnector Profit_Article of een eigen |
| Zending | naar Shopify | fulfillmentCreate |
pakbon met TrTr |
Het verschil met een WooCommerce- of Magento-webshop zit in de B2B-kant. Shopify heeft een eigen model voor zakelijke klanten: een company met een of meer company locations, elk met eigen catalogi, betaaltermijnen en adressen. Dat model moet aansluiten op de verkooprelaties in AFAS. De algemene opzet van een ERP-koppeling staat op ERP koppeling met je webshop.
Welk systeem is leidend, per gegeven
| Gegeven | Leidend | Richting | Gedrag |
|---|---|---|---|
| Debiteurnummer, btw-nummer, betaalvoorwaarde | AFAS | naar Shopify | DbId wordt externalId |
| Prijs per debiteur en staffel | AFAS | naar Shopify | nachtelijk, alleen gewijzigde regels |
| Voorraad per magazijn | AFAS | naar Shopify | per locatie, na aftrek van orders in de wachtrij |
| Productteksten, afbeeldingen, collecties | Shopify | blijft in Shopify | de koppeling schrijft er niet overheen |
| Order | Shopify | naar AFAS | één keer, met het Shopify-order-ID als sleutel |
| Inkoopordernummer van de klant | Shopify, poNumber |
naar AFAS | in RfCs, opdrachtnummer of referentie |
| Track-en-trace | AFAS | naar Shopify | één fulfilment per pakbon |
Wat Shopify en AFAS anders bewaren
Een verkooprelatie tegenover company en company location
In AFAS is een zakelijke klant één verkooprelatie met een debiteurnummer. Daarop staan de afspraken: PaCd voor de betaalvoorwaarde, PrLs voor de voorkeursprijslijst, VkMa voor het voorkeursmagazijn, Krli voor de kredietlimiet en VaId voor het btw-nummer, maximaal 21 tekens.
Shopify splitst dat over twee niveaus. De company is het bedrijf, met een externalId voor het nummer uit het ERP. De company location is een vestiging of afleveradres met eigen catalogi, een eigen betaaltermijn en eigen btw-instellingen, waaronder taxRegistrationId. Een groothandel met één debiteur en zes filialen heeft in Shopify één company met zes locations. In AFAS zijn dat één relatie en zes afleveradressen. De order verwijst in FbSales met een nummer, DlAd, naar een afleveradres dat al bij de relatie staat. De koppeling zet daarom elk adres van een location eerst bij de relatie in AFAS en onthoudt het nummer.
Een prijs per debiteur tegenover catalogi
Profit_SalesPrice geeft per debiteur, peildatum en artikel de velden GrossPrice, Discount en Nettoprijs, met een regel per staffel in Quantity als het filter Volume aanstaat. AFAS heeft dan al bepaald welke afspraak geldt: de prijslijst, een korting of een vaste prijs voor die klant.
Shopify werkt met catalogi. Een catalogus hoort bij een of meer company locations en heeft een prijslijst met vaste prijzen per variant. Staffels gaan als quantity price breaks mee, met quantityPricingByVariantUpdate. Die mutatie past alles of niets toe: faalt één wijziging, dan wordt geen enkele doorgevoerd. Gelden er voor een location meerdere catalogi met een prijs, dan krijgt de klant de laagste. Dat is een andere regel dan in AFAS, waar de meest specifieke afspraak wint. Een klant met een prijslijst en een hogere oude afspraak ziet in Shopify zo de verkeerde prijs.
De koppeling voorkomt dat door per location één prijscatalogus te vullen met de nettoprijs die AFAS heeft uitgerekend. De rekensom voor 300 debiteuren en 2.000 artikelen: 300 aanroepen van Profit_SalesPrice, een per debiteur, en 300 catalogi. priceListFixedPricesAdd neemt 250 prijzen per aanroep, dus 2.000 artikelen zijn 8 aanroepen per catalogus en 2.400 voor de eerste vulling. Daarna gaan alleen gewijzigde regels mee. Het plan van Shopify bepaalt of dit kan:
| Shopify-plan | B2B-catalogi | Wat dat voor AFAS-prijzen betekent |
|---|---|---|
| Basic, Grow, Advanced | 3 actief, voor alle B2B-markten samen | drie prijsgroepen, geen prijs per debiteur |
| Plus | 10.000 per winkel, 25 per company location | een catalogus per debiteur of per location |
Meer over de opzet op klantspecifieke prijzen.
Magazijnen tegenover locaties
Profit_Stock geeft per artikel, magazijn en locatie twee getallen: StockActual en StockEconomic. Shopify houdt voorraad per locatie bij, met maximaal 10 locaties op Basic, Grow en Advanced en 200 op Plus. De koppeling legt een tabel vast van AFAS-magazijn naar Shopify-locatie. Een order die Shopify aan een locatie toewijst, krijgt in FbSales het bijbehorende magazijn in War. Zie voorraad over meerdere magazijnen.
Prijs inclusief of exclusief btw
Een Shopify-order zegt in taxesIncluded of de regelprijzen inclusief btw zijn. B2B-orders zijn dat meestal niet, consumentenorders wel. AFAS heeft op de orderkop het veld InVa, prijs inclusief btw. De koppeling neemt de waarde per order over in plaats van één instelling voor de hele winkel.
De technische werkelijkheid van deze combinatie
| Onderwerp | Shopify | AFAS Profit |
|---|---|---|
| Tempo | 100 punten per seconde, 200 op Advanced, 1.000 op Plus | fair use, geen aantal |
| Tegelijk | het puntenbudget telt | 5 aanroepen |
| Per aanroep | 250 items in een invoerlijst | 100 regels zonder take, 75 MB |
| Wijziging melden | webhook, 8 nieuwe pogingen in 4 uur | geen webhook, pollen |
| Toegang | app met toegangstoken | app connector met token of OAuth |
De getallen zijn op 3 oktober 2026 nagelezen in de documentatie van Shopify en AFAS.
Voorraad doorgerekend. 8.000 artikelen in 2 magazijnen zijn 16.000 hoeveelheden. In AFAS is dat één Profit_Stock-aanroep per ronde met een filter op de wijzigingsdatum, zolang kolommen maal regels onder de 150.000 blijft die AFAS adviseert. In Shopify is het bij een volledige vergelijking 16.000 gedeeld door 250: 64 aanroepen van inventorySetQuantities. Een gewone ronde schrijft alleen de artikelen die sinds de vorige ronde zijn veranderd.
Het venster tussen order en voorraad. Shopify verlaagt available zodra een order binnenkomt. AFAS weet daar pas van als de order in FbSales staat. Een voorraadronde die in dat venster schrijft, zet de verkochte stuks terug. De koppeling trekt orders die nog in de wachtrij staan van het AFAS-getal af en geeft elke hoeveelheid changeFromQuantity mee, zodat Shopify een wijziging op een verouderde stand weigert.
Orders van meer dan 60 dagen oud. Een app ziet standaard alleen de orders van de laatste 60 dagen. Voor het inlezen van oudere orders bij de start is het recht read_all_orders nodig.
Tokens en IP-adressen. Een klassiek AFAS-token is na het aanmaken niet meer in Profit op te vragen. Op de app connector kan een IP-restrictie staan; een aanroep vanaf een ander adres krijgt een 403. Meer in AFAS-connectoren en Shopify API-limieten.
Wat een standaardkoppeling hier niet doet
Standaardkoppelingen en koppelplatformen voor AFAS en Shopify documenteren hun eigen grenzen:
- Eén richting per stroom. Een stroom loopt in een vaste richting. Klanten die in Shopify ontstaan en klanten die in AFAS ontstaan, zijn dan twee losse stromen die elkaar niet kennen.
- Zakelijke prijzen achter een instelling. Prijslijsten, staffels en kortinggroepen uit AFAS lopen via twee vaste connectoren en alleen als een standaardprijsgroep is ingesteld. Prijsafspraken per debiteur buiten die groep gaan niet mee.
- Een vaste set velden. Vrije velden die jullie in AFAS hebben toegevoegd, zoals een eigen magazijnindeling of een B2B-kenmerk, zitten niet in de meegeleverde GetConnectoren.
Een gebouwde koppeling zet de verkooprelaties uit AFAS om in companies en locations in Shopify, vult per location de prijzen die AFAS heeft uitgerekend en gebruikt de connectoren en vrije velden van jouw omgeving.
Als het misgaat
| Wat er misgaat | Wat de koppeling doet | Wat je ziet |
|---|---|---|
FbSales antwoordt 500 met externalMessage |
de order blijft staan, andere orders gaan door | het bericht van AFAS en de order |
Order van een company zonder externalId |
relatie zoeken of aanmaken, daarna de order | de nieuwe relatie in het logboek |
| Afleveradres bestaat niet in AFAS | adres eerst bij de relatie aanmaken | niets, tenzij dat faalt |
Shopify antwoordt THROTTLED |
wacht tot het puntenbudget is aangevuld | niets |
quantityPricingByVariantUpdate faalt |
de hele set opnieuw, daarna de fout tonen | de variant en de staffel |
| AFAS 401 of 403 | alle stromen pauzeren | token ongeldig of IP-adres geweigerd |
Voordat de koppeling een order schrijft, controleert hij of het Shopify-order-ID al bij een AFAS-order hoort. Een webhook die Shopify twee keer aflevert, maakt zo geen tweede verkooporder. Een order die blijft falen wordt met de oorspronkelijke inhoud bewaard en gaat opnieuw mee zodra de oorzaak is opgelost. Het profitLogReference uit de foutmelding staat erbij, zodat de beheerder de fout in AFAS terugvindt.
Wij hosten en bewaken de koppeling en passen hem aan als AFAS of Shopify iets wijzigt, zoals de overgang naar OAuth of een nieuwe API-versie van Shopify. De systeemkant staat op AFAS webshop koppeling, de platformkant op Shopify koppeling, en alle stromen op koppelingen. Verwante combinaties: WooCommerce AFAS koppeling, Magento AFAS koppeling en Shopify Business Central koppeling. Vertel hoeveel debiteuren, prijsafspraken en magazijnen er in AFAS staan.
Veelgestelde vragen
Heb ik Shopify Plus nodig voor prijzen per klant uit AFAS?
Voor een prijs per debiteur wel. Op Basic, Grow en Advanced zijn 3 actieve B2B-catalogi mogelijk voor alle B2B-markten samen, en een catalogus direct aan een company location toewijzen kan alleen op Plus. Met drie catalogi kun je drie prijsgroepen uit AFAS overnemen. Afspraken per debiteur, zoals AFAS ze in Profit_SalesPrice levert, vragen een catalogus per klantlocatie.
Hoe komt een nieuwe zakelijke klant uit Shopify in AFAS?
De koppeling zoekt eerst of de relatie al bestaat: op het debiteurnummer in externalId, dan op het btw-nummer, dan op het e-mailadres. Pas als niets overeenkomt, maakt hij een organisatie aan met KnSalesRelationOrg en zet het nieuwe debiteurnummer terug in Shopify. Zie dubbele klanten en debiteuren.
Wat gebeurt er met consumentenorders zonder company?
Die gaan naar een persoon met KnSalesRelationPer, of naar een vaste verzameldebiteur als je administratie dat zo wil. Dat leg je vooraf vast. Een Shopify-order heeft het veld purchasingEntity: is daar een company location ingevuld, dan is het een B2B-order, anders een consumentenorder.
Hoe snel staat een order in AFAS?
Shopify meldt een nieuwe order met een webhook, dus de koppeling heeft hem binnen enkele seconden. Het schrijven naar FbSales volgt direct, tenzij AFAS de order afkeurt of tijdelijk niet bereikbaar is. Dan wacht de order in de wachtrij. De andere kant op, van AFAS naar Shopify, loopt via rondes, omdat AFAS voor artikelen, voorraad en prijzen geen webhooks heeft.
Werkt de koppeling met meerdere Shopify-winkels of markten?
Ja. Elke winkel krijgt een eigen waarde in het verkoopkanaal, SaCh, of een eigen voorvoegsel in de referentie, en een eigen magazijn in War als de winkels uit verschillende voorraden leveren. Een tweede winkel is in Shopify ook een tweede app-installatie met een eigen puntenbudget.
Blijft de koppeling werken nu AFAS de klassieke tokens uitfaseert?
Ja. Volgens AFAS werken app connectoren met een klassiek token na 31 augustus 2027 niet meer. Nieuwe koppelingen gebruiken OAuth met een Bearer-token van 3.600 seconden. Een nieuwe koppeling bouwen wij op OAuth. Dit is nagelezen op 3 oktober 2026.
Vertel wat je nodig hebt
Vertel welke systemen je gebruikt en wat je wilt verbeteren. Je krijgt binnen één werkdag een persoonlijk antwoord. We helpen je de werkzaamheden helder te krijgen en spreken de prijs en planning af voordat je iets toezegt.
- Je weet de prijs en de doorlooptijd voordat je iets toezegt
- Wij zoeken uit welke koppeling het werk uit handen neemt
- Wij verzorgen de bouw, hosting, bewaking en het onderhoud
- Je team krijgt minder overtypwerk en minder uitzoekwerk