Skip to content

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

composer require drupal/commerce_shipping
ddrush en commerce_shipping -y

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:

Subtotal: € 10,85
Verzending: € 4,10
BTW (9%): € 0,90
Order Total: € 14,95

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 logic
  • vg_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

  1. BTW display verbeteren in templates (transparante rekensom)
  2. Tweede verzendmethode voor Merchandise (21% BTW)
  3. Verzendkosten regels verfijnen:
  4. 1 nummer: €4,10
  5. 2-4 nummers: €5,15
  6. 5+ nummers: TBD

Middel Prioriteit

  1. "Publicatie" references verwijderen uit vg_commerce_tax module
  2. Email templates styling (consistent met huisstijl)
  3. Dubbele factuur generatie debuggen (webhook race condition?)
  4. Custom font in PDF (GAP Zuid VG) - onopgelost uit eerdere sessie

Lage Prioriteit

  1. "Shipping" checkout flow verwijderen (default van module, niet gebruikt)
  2. Product prijs bulk update tool (alle oude incl. prijzen omrekenen naar excl.)
  3. 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

  1. BTW display templates verbeteren
  2. Merchandise verzendmethode (21% BTW)
  3. Verzendkosten regels per hoeveelheid
  4. 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