Commerce Verzending en BTW Display Setup¶
Datum: 11 november 2025
Doel: Verzendkosten integreren met correcte BTW-tarieven en prijsdisplay verbeteren
Uitgangspunt¶
Na eerdere sessies was checkout werkend met Mollie betalingen en automatische facturen. Deze sessie richt zich op: 1. Verzendkosten toevoegen voor fysieke producten 2. BTW-tarieven correct toepassen op verzending (9% drukwerk, 21% merchandise) 3. Prijsdisplay wijzigen van inclusief naar exclusief BTW
Problemen en Oplossingen¶
Probleem 1: Database Lock Timeout bij Checkout Return¶
Symptoom: Error bij /checkout/19/payment/return:
SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded
SELECT ... FROM commerce_number_pattern_sequence ... FOR UPDATE
Oorzaak:
- Order 19 zat vast in "validation" state
- Mollie webhook en checkout return URL probeerden tegelijk order te updaten
- Database lock op commerce_number_pattern_sequence tabel
Analyse: - Order kreeg al ordernummer 16 toegewezen - State transition van "validation" naar "completed" hing - Concurrent access door webhook + browser redirect
Oplossing: Cache rebuild (ddrush cr)
Preventie: Mollie webhook is geoptimaliseerd, maar race conditions blijven mogelijk bij snelle redirects.
Status: Incident, geen structureel probleem.
Probleem 2: Invoice Display Bug (Gin Theme Incompatibiliteit)¶
Symptoom: /admin/commerce/invoices/11 crasht met:
Drupal\Core\Render\Component\Exception\InvalidComponentDataException:
Unable to render component "navigation:title"
Oorzaak:
- Gin 5.0.6 admin theme gebruikt Drupal core's nieuwe SDC (Single Directory Components)
- Commerce Invoice module genereert page title op manier die niet compatibel is met navigation:title component
- Orders pagina werkt wel, Invoices pagina niet
Analyse: - Bug zit in hoe Commerce Invoice module page title doorgeeft aan theme systeem - Niet specifiek aan één invoice, maar alle invoice canonical routes - Gin's navigation component verwacht specifieke data structuur die Commerce Invoice niet levert
Tijdelijke Workaround:
- Menu item "Facturen" omgeleid naar Orders pagina
- Via hook in vg_commerce_tax.module:
function vg_commerce_tax_menu_links_discovered_alter(&$links) {
// Redirect Facturen menu item to Orders page as workaround for Gin/Commerce Invoice bug.
if (isset($links['entity.commerce_invoice.collection'])) {
$links['entity.commerce_invoice.collection']['route_name'] = 'entity.commerce_order.collection';
}
}
Voordelen workaround: - Eén regel code in bestaande module - Duidelijke comment (tijdelijk, waarom) - Geen config export nodig - Makkelijk terugdraaien (regel verwijderen + cache clear) - Live migratie: module bestaat al, werkt automatisch
Permanente oplossing: Wachten op update van Commerce Invoice of Gin theme die compatibiliteit herstelt.
Status: Workaround actief, gebruikers merken niets.
Probleem 3: Prijsdisplay Inclusief vs Exclusief BTW¶
Situatie: Collega's willen prijzen exclusief BTW tonen zodat factuur logischer is (excl. + BTW = incl.)
Beslissing: Omschakelen van inclusief naar exclusief BTW display.
Implementatie:
ddrush php-eval "
\$store = \Drupal\commerce_store\Entity\Store::load(1);
\$store->set('prices_include_tax', FALSE);
\$store->save();
"
ddrush cr
Gevolg: - Productpagina's tonen nu excl. BTW prijzen - Winkelwagen toont BTW apart - Checkout en factuur: duidelijk overzicht met BTW regel
Let op: Bestaande productprijzen moeten handmatig aangepast worden (waren ingevoerd als incl. prijzen).
Omrekening: Nieuwe prijs = Oude prijs ÷ 1,09 (voor 9% BTW producten)
Verzendkosten Implementatie¶
Belastingdienst Regelgeving Verzending Drukwerk¶
Bron: Belastingdienst - BTW-tarief verzendwerkzaamheden drukwerk
Regelgeving: - Verzendwerkzaamheden drukwerk (adressering, bundeling, porto) vallen onder zelfde BTW-tarief als het drukwerk zelf - Tijdschriften en boeken = 9% BTW → verzending ook 9% - Merchandise = 21% BTW → verzending ook 21%
Uitzondering PostNL: - Porto kan 0% BTW als: 1. PostNL vrijgestelde postdienst gebruikt 2. Porto afzonderlijk in rekening gebracht 3. Bedrag exact gelijk aan PostNL tarief - Beslissing: Niet gebruiken (€0,18 besparing, veel administratieve overhead)
Verzendkosten Structuur¶
Gegeven tarieven: - 1 los nummer: €4,10 - 2+ losse nummers: €5,15 - 5+ losse nummers: nog te bepalen
Producttypen met verzending: - Los nummer (9% BTW) - fysiek tijdschrift - Uitgave (9% BTW) - fysieke boeken - Merchandise (21% BTW) - fysieke producten
Producttypen zonder verzending: - Abonnement (digitale toegang) - Ticket (toegangsbewijs, geen fysiek object)
Commerce Shipping Module Installatie¶
Dependencies geïnstalleerd: - drupal/commerce_shipping 2.15.0 - drupal/physical 1.5.0 (gewicht, afmetingen)
Warnings tijdens installatie: - Oude velden (publicatie, profile bundles) - niet relevant - ECA deprecation warning - geen impact
Variation Types Configuratie¶
"Verzendbaar" eigenschap aangezet: - Los nummer: Ja - Uitgave: Ja - Merchandise: Ja - Abonnement: Nee - Ticket: Nee
Locatie: /admin/commerce/config/product-variation-types/[type]/edit → Eigenschappen
Oude variation type verwijderd: - "Publicatie" type verwijderd uit UI (was gesplitst in Los nummer + Uitgave in eerdere sessie) - BTW resolver module verwijst nog naar 'publicatie' in code maar schaadt niet (dode code)
TODO: Publicatie references opruimen uit vg_commerce_tax module voor cleane live migratie.
Verzendmethode Aangemaakt¶
Naam: Verzending drukwerk (9% BTW)
Locatie: /admin/commerce/shipping-methods
Configuratie: - Plugin: Flat rate per item - Rate label: Standaard verzending (klant-zichtbaar) - Rate amount: €4,10 - Tax category: Reduced rate (9%) - Restrict to stores: Leeg (alleen VG Webshop bestaat)
Voorwaarden: - Bestelling bevat variatietypes: Los nummer OF Uitgave - "Publicatie" type niet geselecteerd (oud type)
Reden voor "per item": Bij meerdere nummers moeten verzendkosten oplopen (later verfijnen met custom regels).
TODO toekomstig: Tweede verzendmethode voor Merchandise (21% BTW).
BTW op Verzending - Custom Module Uitbreiding¶
Event Subscriber toegevoegd: ShippingTaxSubscriber
Locatie: web/modules/custom/vg_commerce_tax/src/EventSubscriber/ShippingTaxSubscriber.php
Functie: Documenteert business rule dat verzending drukwerk 9% BTW krijgt (volgt Belastingdienst regelgeving).
Services registratie:
# vg_commerce_tax.services.yml
vg_commerce_tax.shipping_tax_subscriber:
class: Drupal\vg_commerce_tax\EventSubscriber\ShippingTaxSubscriber
tags:
- { name: event_subscriber }
Note: Commerce Tax past automatisch correct tarief toe op verzending wanneer tax category ingesteld is in shipping method. Subscriber is vooral documentatie.
Order Type Configuratie¶
Cruciale instelling: "Enable shipping for this order type"
Locatie: /admin/commerce/config/order-types/default/edit
Configuratie: - Enable shipping: AAN - Shipment type: Standaard - Workflow: Default
Symptoom bij UIT: Verzending stap verschijnt in checkout maar verzendkosten worden niet toegevoegd aan order (geen shipping adjustment).
Checkout Flow Aangepast¶
Flow: Mollie
Locatie: /admin/commerce/config/checkout-flows/manage/mollie
Nieuwe stap toegevoegd: Verzendinformatie
Structuur:
Inloggen - Login
Orderinformatie (stap) - Contactinformatie (pane) - Verzendinformatie (pane) - NIEUW - Betaalinformatie (pane)
Overzicht (stap) - Overzicht (pane)
Betaling (stap) - Voortgang betaling (pane)
Voltooid (stap) - Afrondingsbericht (pane) - Gast registreren na betaling (pane)
Rationale structuur: - "Betaalinformatie" onder Orderinformatie = methode kiezen - "Voortgang betaling" onder Betaling = daadwerkelijk betalen bij Mollie - Deze scheiding voorkomt "payment information en payment process op zelfde stap" conflict
Note: Commerce Shipping module creëert automatisch "Shipping" checkout flow bij installatie. Deze wordt niet gebruikt (Mollie flow is actief).
Eerste Test - Verzending Werkt¶
Test order: 2x Los nummer "Voedingsgeneeskunde 4 - 2025"
Checkout ervaring: - Verzendinformatie stap verscheen - Keuze: "Standaard verzending" (enige optie) - Verzendkosten zichtbaar in overzicht
Bestelbevestiging ontvangen:
Factuur: PDF gegenereerd, verzendkosten correct vermeld.
Status: Verzending werkt!
BTW Display Verbetering (TODO)¶
Huidig Probleem¶
Verwarrende display in emails en facturen:
Subtotal: € 10,85 (onduidelijk - is dit incl. of excl.?)
Verzending: € 4,10
BTW (9%): € 0,90 (alleen voor verzending, niet product)
Total: € 14,95
Wat er gebeurt: - Product toont prijs incl. BTW in subtotaal - BTW-regel toont alleen verzend-BTW - Product-BTW is "verborgen" in subtotaal - Onlogische som voor gebruiker
Gewenste Display¶
Ideaal overzicht:
Product: € 9,13 (excl. BTW)
Verzending: € 4,10 (excl. BTW)
─────────────────────
Subtotaal excl. BTW: € 13,23
BTW (9%): € 1,19 (totaal: €0,82 product + €0,37 verzending)
─────────────────────
Totaal incl. BTW: € 14,42
Voordeel: Transparante rekensom, duidelijk voor klant.
Implementatie Vereist¶
Templates aan te passen: 1. Order email template (bestelbevestiging) 2. Invoice email template 3. Invoice PDF template 4. Checkout overzicht pagina
Aanpak:
- Twig template overrides in vg25 theme
- Custom order total summary rendering
- BTW adjustments samenvoegen en onderaan tonen
Prioriteit: Medium - berekening klopt al, dit is display verbetering.
Status: Op TODO voor volgende sessie.
Gerealiseerd Vandaag¶
Configuratie¶
- Store ingesteld op exclusief BTW display
- Commerce Shipping module geïnstalleerd en geconfigureerd
- Verzendmethode "Verzending drukwerk (9% BTW)" aangemaakt
- Variation types Los nummer, Uitgave, Merchandise = verzendbaar
- Order type: shipping enabled met Standaard shipment type
- Checkout flow Mollie: Verzendinformatie stap toegevoegd
Code¶
vg_commerce_tax.module: Menu link redirect Facturen → Orders (Gin bug workaround)ShippingTaxSubscriber.php: Event subscriber voor verzend-BTW business logicvg_commerce_tax.services.yml: Service registratie subscriber
Testing¶
- Verzending werkt end-to-end
- Verzendkosten correct berekend (€4,10)
- BTW correct toegepast (9% op verzending)
- Emails verzonden (order + factuur)
- Factuur PDF bevat verzendkosten
Openstaande Issues¶
Hoge Prioriteit¶
- BTW display verbeteren in templates (transparante rekensom)
- Tweede verzendmethode voor Merchandise (21% BTW)
- Verzendkosten regels verfijnen:
- 1 nummer: €4,10
- 2-4 nummers: €5,15
- 5+ nummers: TBD
Middel Prioriteit¶
- "Publicatie" references verwijderen uit vg_commerce_tax module
- Email templates styling (consistent met huisstijl)
- Dubbele factuur generatie debuggen (webhook race condition?)
- Custom font in PDF (GAP Zuid VG) - onopgelost uit eerdere sessie
Lage Prioriteit¶
- "Shipping" checkout flow verwijderen (default van module, niet gebruikt)
- Product prijs bulk update tool (alle oude incl. prijzen omrekenen naar excl.)
- Views voor winkel afmaken
Technische Details¶
Modules Geïnstalleerd¶
- drupal/commerce_shipping 2.15.0
- drupal/physical 1.5.0
Belangrijke Paden¶
- Verzendmethoden:
/admin/commerce/shipping-methods - Shipment types:
/admin/commerce/config/shipments - Order types:
/admin/commerce/config/order-types - Checkout flows:
/admin/commerce/config/checkout-flows - Variation types:
/admin/commerce/config/product-variation-types
Custom Code Locaties¶
- Menu redirect hook:
web/modules/custom/vg_commerce_tax/vg_commerce_tax.module - Shipping tax subscriber:
web/modules/custom/vg_commerce_tax/src/EventSubscriber/ShippingTaxSubscriber.php - Services:
web/modules/custom/vg_commerce_tax/vg_commerce_tax.services.yml
Drush Commands Gebruikt¶
# Store BTW display wijzigen
ddrush php-eval "\$store = \Drupal\commerce_store\Entity\Store::load(1); \$store->set('prices_include_tax', FALSE); \$store->save();"
# Commerce Shipping installeren
composer require drupal/commerce_shipping
ddrush en commerce_shipping -y
# Cache clears
ddrush cr
Belangrijke Beslissingen¶
Prijsdisplay Exclusief BTW¶
Beslissing: Prijzen exclusief BTW tonen
Reden: Duidelijkere facturen (excl. + BTW = incl.), professioneler voor B2B
Impact: Bestaande productprijzen moeten handmatig aangepast
Verzending Volgt Product BTW-Tarief¶
Beslissing: Drukwerk verzending 9%, merchandise verzending 21%
Reden: Belastingdienst regelgeving (verzending volgt product)
Impact: Twee aparte verzendmethoden nodig
PostNL BTW-Vrijstelling Niet Gebruiken¶
Beslissing: Normale 9% BTW berekenen op verzending
Reden: Minimale besparing (€0,18), veel administratieve complexiteit
Impact: Eenvoudigere setup, minder foutgevoelig
Gin Invoice Bug Workaround via Menu Redirect¶
Beslissing: Menu item redirecten ipv view dupliceren of theme downgraden
Reden: Minste code, makkelijk terugdraaien, config-export friendly
Impact: Gebruikers zien geen verschil, technisch schoon
Flat Rate Per Item (voorlopig)¶
Beslissing: Simpele per-item berekening als basis
Reden: Snel werkend, later verfijnen met services/rules
Impact: Voorlopig lineaire verzendkosten, verfijning volgende sessie
Geleerde Lessen¶
Commerce Shipping Vereist Order Type Enable¶
Shipping stap in checkout is niet genoeg - "Enable shipping for this order type" is cruciaal. Anders geen shipping adjustments.
Store BTW Setting Herberekent Oude Prijzen Niet¶
Bij omschakelen incl. → excl. BTW moet je bestaande prijzen handmatig aanpassen. Commerce past niet automatisch aan.
Gin Theme SDC Incompatibiliteit met Commerce Invoice¶
Nieuwe Single Directory Components in Drupal core/Gin hebben breaking changes voor contrib modules. Workarounds nodig tot updates.
Belastingdienst Verzending Drukwerk Regel¶
Verzendkosten drukwerk vallen onder zelfde BTW-tarief als product - belangrijke fiscale regel die systeemarchitectuur beïnvloedt.
Volgende Sessie Planning¶
Prioriteiten¶
- BTW display templates verbeteren
- Merchandise verzendmethode (21% BTW)
- Verzendkosten regels per hoeveelheid
- Email templates styling
Nice to Have¶
- Custom font in PDF oplossen
- Dubbele factuur bug
- Bulk prijs update tool
Status¶
Huidige fase: Verzending werkend, display verfijning nodig
Volgende milestone: Professionele factuur layout + merchandise ondersteuning
Live deployment: Na email/PDF template styling en testing
Werkend: - Verzendkosten berekening - BTW op verzending (9% drukwerk) - Checkout flow met verzending stap - Order completion met factuur incl. verzending - Menu workaround voor Gin bug
In progress: - BTW display verbeteren (transparante rekensom) - Verzendkosten regels per hoeveelheid - Merchandise verzendmethode
Nog te doen: - Template overrides (email, PDF, checkout) - Tweede verzendmethode configureren - Testing met verschillende scenario's - Live deployment