Shopify zegt dat de order 128,45 is. De verkooporder in Odoo zegt 106,16. Niemand heeft iets aangeraakt, de connector meldt geen fouten, en toch spreken de twee getallen elkaar tegen. In de praktijk komt vrijwel elk bedragsverschil tussen Odoo en Shopify neer op een van acht oorzaken, en elk daarvan laat een andere vingerafdruk achter. Deze gids loopt ze alle acht langs, geeft het symptoom dat elke oorzaak verraadt en wijst aan beide kanten precies het veld aan dat je moet controleren.
Het geldt voor elke Shopify-order die in Odoo leeft, ongeacht welke connector hem heeft geïmporteerd: de Shopify Odoo Connector van Emipro, Webkul, een OCA-module of een eigen koppeling. De veldnamen hieronder komen uit de standaardmodellen van Odoo, aangevuld — waar relevant — met de instellingen die een connector doorgaans op zijn instance-record aanbiedt.
Zorg er eerst voor dat je vergelijkbare getallen vergelijkt
Ga niet op jacht naar een bug voordat je nakijkt wát je vergelijkt. Beide systemen tonen meerdere «totalen», en die betekenen niet hetzelfde.
- Huidig Shopify-totaal: wat de klant vandaag verschuldigd is, na terugbetalingen en wijzigingen. In de Admin API: currentTotalPriceSet.
- Oorspronkelijk Shopify-totaal: wat bij de afrekening is afgesproken, vóór elke latere wijziging: originalTotalPriceSet.
- Totaal van de Odoo-verkooporder: amount_total op sale.order — wat de connector heeft geïmporteerd, plus wat hij daarna nog heeft gesynchroniseerd.
- Netto gefactureerd in Odoo: geboekte klantfacturen minus geboekte creditnota's (account.move, move_type out_invoice en out_refund).
Dat die vier getallen verschillen is op zich geen probleem. De enige echte vraag is welk paar zou moeten kloppen, en dat hangt af van hoe ver de order al is gekomen: een nog niet gefactureerde order vraagt om een andere vergelijking dan een order die gefactureerd, terugbetaald en gewijzigd is.
1 Oorzaak 1: prijzen inclusief btw
Dit is het meest voorkomende loze alarm, en het makkelijkst uit te sluiten. Als je Shopify-prijzen btw bevatten en je Odoo-btw is ingesteld als «Inbegrepen in de prijs», dan meten het Shopify-subtotaal en het bedrag exclusief btw in Odoo twee verschillende dingen: de eerste is inclusief btw, de tweede exclusief.
Het symptoom is onmiskenbaar: het gat is precies het btw-tarief. 128,45 tegenover 106,16 is geen afrondingsprobleem, dat is 21 % btw.
De oplossing is een vergelijking kiezen die deze instelling overleeft. Vergelijk totalen inclusief btw — het huidige Shopify-totaal tegen amount_total in Odoo — of vergelijk aan beide kanten netto door in Odoo amount_tax van amount_total af te trekken. Wat je nooit moet doen: het Shopify-subtotaal vergelijken met amount_untaxed in Odoo, tenzij je zeker weet dat beide kanten identiek zijn ingesteld.
2 Oorzaak 2: de order ligt vast, de factuur gaat door
Connectors importeren een Shopify-order in een sale.order. Zodra die order gefactureerd is, stoppen de meeste met het doorduwen van latere wijzigingen — terecht: een gefactureerde order is een boekhoudkundig document, geen spiegel. Vanaf dat moment legt de order vast wat er besteld is, en leggen de facturen vast wat er werkelijk in rekening is gebracht.
Komt er dus na de facturatie een terugbetaling binnen, dan daalt het huidige Shopify-totaal terwijl de Odoo-order blijft staan. Het geld is in Odoo wel degelijk bewogen, alleen ergens anders: in een creditnota, een account.move met move_type = out_refund.
Waar je moet kijken: sale.order.invoice_ids geeft je alle facturen en creditnota's bij de order. Tel de geboekte out_invoice op, trek de geboekte out_refund af, en dat nettobedrag is wat moet kloppen met het huidige Shopify-totaal. Per regel is qty_invoiced de maatgevende hoeveelheid, niet product_uom_qty.
Daarom levert het vergelijken van de verkooporder met Shopify steeds meer loze alarmen op naarmate de order ouder wordt: je vergelijkt een momentopname van het importmoment met een levend document.
3 Oorzaak 3: terugbetalingen — het geld klopt altijd, de aantallen misschien niet
Shopify-terugbetalingen bestaan in twee smaken, en maar één ervan raakt de voorraad. Een terugbetaling kan het geld teruggeven en de eenheden terugleggen, of het geld teruggeven en de eenheden laten waar ze zijn: beschadigd product, coulance, gedeeltelijke prijsaanpassing.
In de Admin API zit het onderscheid op elke terugbetalingsregel, in restockType: NO_RESTOCK, CANCEL, RETURN of LEGACY_RESTOCK. Voor de afstemming betekent dat: een NO_RESTOCK-terugbetaling verlaagt het bedrag zonder de levende hoeveelheid van de regel te wijzigen, dus een controle van aantallen per regel kan er fout uitzien terwijl het geld perfect klopt.
Dit is het meest verkeerd gelezen verschil van allemaal, omdat het instinct zegt aantallen meer te vertrouwen dan bedragen. Hier hebben de bedragen gelijk en vertellen de aantallen iets anders: wat er gefactureerd is tegenover wat er fysiek terug is gekomen.
4 Oorzaak 4: de order is achteraf in Shopify gewijzigd
Order editing in Shopify wijzigt een order ter plekke: regels worden toegevoegd, verwijderd of in aantal aangepast nadat de klant heeft betaald. Shopify bewaart beide cijfers — originalTotalPriceSet voor de afrekening, currentTotalPriceSet voor de gewijzigde order — en de meeste connectors synchroniseren de verkooporder opnieuw, waardoor amount_total in Odoo de wijziging volgt en niet langer overeenkomt met wat er besteld is.
Op zich is dat ongevaarlijk. De riskante variant is de wijziging die ná de facturatie binnenkomt: een regel die Odoo al gefactureerd heeft, wordt in Shopify verwijderd. Nu heeft Odoo meer gefactureerd dan Shopify ooit zal innen. Dat is geen weergavekwestie, dat is een echte overfacturatie en er hoort een creditnota bij.
Symptoom: het netto gefactureerde bedrag in Odoo is hoger dan het huidige Shopify-totaal, de order heeft geen terugbetaling, en het oorspronkelijke Shopify-totaal is hoger dan het huidige. Gelden die drie tegelijk, dan is de order na facturatie gewijzigd.
5 Oorzaak 5: cadeaubonnen, verkocht en ingewisseld
Cadeaubonnen leveren twee volledig verschillende verschillen op, afhankelijk van aan welke kant van de transactie ze staan — die zijn het waard om zorgvuldig uit elkaar te houden.
Een cadeaubon verkopen. In Shopify draagt de regel de markering isGiftCard en meestal helemaal geen SKU. Connectors koppelen hem niet op SKU: ze herkennen de markering bij import en sturen de regel naar een apart product dat op de connector-instance is ingesteld (bij Emipro gift_card_product_id). Koppelt jouw afstemming regels op SKU, dan verschijnt dezelfde bon als twee halflege regels: één aan de Shopify-kant met een naam en zonder SKU, één aan de Odoo-kant met de interne referentie van het synthetische product. Met de bon is niets mis; de koppelsleutel deugt niet.
Met een cadeaubon betalen. Hier heeft Shopify helemaal geen regel: een cadeaubon die als betaalmiddel wordt gebruikt is een tender en verschijnt alleen tussen de betaalgateways van de order. Connectors die de betaling in Odoo sluitend moeten krijgen, voegen een negatieve regel toe — «Gift card for …» — die naar datzelfde synthetische product wijst. Odoo heeft dan één regel meer dan Shopify, en elke naïeve regel-voor-regelweergave toont een regel zonder tegenhanger.
6 Oorzaak 6: kortingen, cadeaus en artefactproducten
Shopify en Odoo modelleren hetzelfde commerciële gebaar in verschillende vormen. Een cadeau is in Shopify een tweede regel van 0,00. Een korting is een bedrag op de regel zelf. Odoo-connectors drukken beide vaak uit als een extra orderregel die naar een synthetisch product op de instance wijst: doorgaans een kortingsproduct, een correctieproduct voor terugbetalingen, een invoerrechtenproduct, een fooiproduct en een verzendproduct.
Die artefactregels hebben geen tegenhanger in de lineItems van Shopify. Regel voor regel lijken het spookregels; op het totaal zijn ze precies wat de twee bedragen laat kloppen. Ze verwijderen zou de order kapotmaken, niet repareren.
Hoe je wél goed vergelijkt: aggregeer regels op SKU voordat je ze koppelt, en sluit de producten uit die op de connector-instance als artefact zijn ingesteld. Met die twee regels op hun plek zijn de overgebleven verschillen echt.
7 Oorzaak 7: verzending, invoerrechten en toeslagen
Verzending is in Shopify een eigen concept — een verzendregel met eigen prijs en btw — terwijl het in Odoo meestal binnenkomt als een gewone orderregel met de markering is_delivery, geprijsd vanuit het verzendproduct van de connector. Invoerrechten, fooien en betaaltoeslagen volgen hetzelfde patroon.
Het praktische gevolg is dat het aantal regels bijna nooit gelijk is, zelfs niet bij een perfect gesynchroniseerde order, en elke subtotaalvergelijking erft dat verschil. Vergelijk eerst totalen; vergelijk regels pas nadat je aan de Odoo-kant verzend- en toeslagregels hebt uitgesloten.
Hetzelfde geldt voor de leveringsas: achter een dienstregel zit geen voorraadmutatie, dus de geleverde hoeveelheid blijft voor altijd nul. Dat is correct gedrag, geen openstaande zending.
8 Oorzaak 8: valuta, presentment money en afronding
Shopify geeft elk geldveld dubbel terug: shopMoney, in de valuta van je winkel, en presentmentMoney, in de valuta die de klant daadwerkelijk zag. Verkoop je in meerdere valuta's, dan heeft de connector er één geïmporteerd en lees jij mogelijk de andere.
Odoo voegt daar een eigen tweede omrekening aan toe: de order wordt in zijn eigen valuta bewaard en tegen de dagkoers omgerekend naar de bedrijfsvaluta. Een verouderde wisselkoers levert een klein verschil op dat altijd dezelfde kant op leunt — een betrouwbare aanwijzing, want echte fouten zijn zelden zo consistent.
En dan is er nog gewone afronding. Verschillen van één tot drie cent op orders met meerdere regels en procentuele kortingen per regel zijn afronding, en daarop jagen kost je een middag. Alles wat groter is heeft een van de bovenstaande oorzaken.
Snelle referentie: van symptoom naar oorzaak
| Wat je ziet | Meest waarschijnlijke oorzaak | Waar te controleren |
|---|---|---|
| Het gat is precies het btw-tarief | Prijzen inclusief btw | Odoo-btw «Inbegrepen in de prijs»; totalen inclusief btw vergelijken |
| Odoo hoger dan Shopify, order heeft een terugbetaling | Terugbetaling geboekt na de facturatie | account.move out_refund; qty_invoiced per regel |
| Odoo hoger, geen terugbetaling, Shopify origineel > huidig | Order na facturatie gewijzigd (overfacturatie) | originalTotalPriceSet tegenover currentTotalPriceSet |
| De bedragen kloppen, het aantal van één regel niet | Terugbetaling zonder terugname in voorraad | refundLineItems.restockType; currentQuantity |
| Eén regel extra in Odoo, rond bedragsverschil | Cadeaubon gebruikt als betaalmiddel | Betaalgateways van de order; negatieve regel in Odoo |
| Eén cadeaubon verschijnt als twee halflege regels | Gekoppeld op SKU in plaats van op de cadeaubonmarkering | isGiftCard; cadeaubonproduct van de instance |
| Extra Odoo-regels met korting of invoerrechten in de naam | Artefactproducten van de connector | Kortings-/invoerrechten-/fooi-/verzendproduct van de instance |
| Een verschil van een paar cent | Afronding of wisselkoers | shopMoney tegenover presentmentMoney; dagkoers in Odoo |
Een controle van vijf minuten die je kunt herhalen
Belandt er een verschil op je bureau, dan lost deze volgorde het sneller op dan naar beide schermen staren:
- Open de Shopify-order. Noteer het huidige totaal en kijk of er terugbetalingen zijn of dat de order gewijzigd is.
- Open de Odoo-verkooporder. Noteer amount_total en bekijk invoice_status.
- Is hij gefactureerd: tel de geboekte facturen op, trek de geboekte creditnota's af en vergelijk dat cijfer — niet het ordertotaal — met het huidige Shopify-totaal.
- Is hij nog niet gefactureerd: vergelijk met amount_total en behandel het resultaat als voorlopig. Het verandert zodra de factuur geboekt is.
- Kloppen ze dan nog niet, loop dan de acht oorzaken op volgorde af: eerst btw, dan facturatie, terugbetalingen, wijzigingen, cadeaubonnen, artefacten, verzending, valuta. De eerste die past is bijna altijd het antwoord.
Vijf minuten per order is prima als het twee keer per maand gebeurt. Het is niet meer prima als een klantenservicemedewerker het moet doen vóór elk «jullie hebben me het verkeerde bedrag berekend»-mailtje, of als iemand een dag aan orders steekproefsgewijs moet nalopen voor de maandafsluiting.
Verder lezen
Of controleer het met één klik
Odoo–Shopify Order Check voert deze hele vergelijking voor je uit, in de orderpagina die je toch al open hebt staan: totalen, btw, aantallen, regels, adressen en levering, met terugbetalingen en cadeaubonnen als context in plaats van als fouten. De extensie is alleen-lezen — ze schrijft nooit naar Odoo of Shopify — en vraagt geen enkele API-sleutel.
Probeer 14 dagen gratis