Sessie 30 december 2024: Mollie Payment Crisis & Docs Reorganisatie¶
Doel¶
Critical: Mollie payment flow ghost invoices en database locks oplossen. Documentatie reorganiseren voor betere vindbaarheid.
Crisis: Ghost Invoices & Database Locks¶
Symptomen¶
- Ghost facturen: dubbele facturen bij refresh op mollie_return pagina
- Database locks tijdens payment processing
- Users klikken meerdere keren op refresh → pending payments
- Onvertrouwelijk checkout proces
Root Cause¶
Race condition tussen Mollie webhook en return URL
Beide endpoints probeerden tegelijk: 1. Payment status ophalen van Mollie 2. Payment entity updaten 3. Order plaatsen 4. Invoice genereren
Oplossingen Geprobeerd¶
Poging 1: PaymentProcessingLock Event Subscriber¶
- Lock mechanism tijdens payment processing
- Bleef hangen bij concurrent requests
- Locks werden niet altijd vrijgegeven
Poging 2: PaymentIdempotency Event Subscriber¶
- Idempotency checks op payment events
- Voorkwam dubbele processing maar niet de locks
Poging 3: MollieWebhookInterceptor (Queueing)¶
- Probeerde webhook te queueen
- Route detection werkte niet goed
stopPropagation()had geen effect
Poging 4: QueuedPaymentNotifyController (Override)¶
- Override van
commerce_payment.notifyroute - Access denied errors (missing permissions)
- Complexity escaleerde
Finale Oplossing: Simplificatie¶
Principe: Webhook doet NIETS, return URL doet ALLES
Webhook (/payment/notify/{gateway}):
- Returns immediate HTTP 200 OK
- Geen processing, geen database queries
- Mollie is tevreden
Return URL (/mollie_return/{order}):
- User komt terug na betaling
- Haalt status op van Mollie API
- Update payment state
- Plaatst order
- Genereert invoice
- Redirect naar checkout completion
Implementatie:
QueuedPaymentNotifyController.php:
public function notify(Request $request, string $commerce_payment_gateway) {
return new Response('OK', 200);
}
MollieReturnController.php:
public function returnFromMollie(OrderInterface $commerce_order) {
// Haal payment op
// Check status bij Mollie API
// Update payment state
// Place order
// Redirect naar /checkout/{order}/complete
}
Routes (vg_commerce.routing.yml):
commerce_payment.notify.mollie:
path: '/payment/notify/{commerce_payment_gateway}'
defaults:
_controller: '\Drupal\vg_commerce\Controller\QueuedPaymentNotifyController::notify'
_title: 'Payment notification'
requirements:
_access: 'TRUE'
vg_commerce.mollie_return:
path: '/mollie_return/{commerce_order}'
defaults:
_controller: '\Drupal\vg_commerce\Controller\MollieReturnController::returnFromMollie'
requirements:
_entity_access: 'commerce_order.view'
Safety Layers (behouden voor extra zekerheid):
- PaymentProcessingLock event subscriber
- PaymentIdempotency event subscriber
Resultaat¶
✅ Geen ghost invoices meer ✅ Geen database locks ✅ Snelle response (geen polling/AJAX) ✅ Vertrouwelijk checkout proces
Invoice Template Fixes¶
Probleem¶
Factuur PDF toonde geen klantgegevens, geen ordernummer
Oorzaak¶
- Invoice entity heeft
ordersfield (plural), nietgetOrder()method - Customer profile fields waren hidden in display mode
- Template verwachtte billing_information maar kreeg niets
Oplossing¶
Handmatig address extraction in preprocess:
vg25_preprocess_commerce_invoice():
$orders = $invoice->get('orders')->referencedEntities();
$order = reset($orders);
$billing_profile = $order->getBillingProfile();
$address_data = $billing_profile->get('address')->first()->getValue();
// Build address markup
$variables['customer_details'] = [
'name' => $address_data['given_name'] . ' ' . $address_data['family_name'],
'organization' => $address_data['organization'],
'address' => $address_data['address_line1'],
'postal' => $address_data['postal_code'],
'city' => $address_data['locality'],
'country' => $address_data['country_code'],
];
Template updates: - Klantgegevens: naam, organisatie, adres, postcode, plaats, land - Factuurnummer + Ordernummer - BTW met percentages: "BTW (9%)" / "BTW (21%)" - Betaalstatus: Betaald - Verwijderd: vervaldatum, payment terms
Resultaat¶
✅ Volledige factuur met alle gegevens ✅ PDF generatie werkt perfect
Checkout Completion Page¶
Aanpassing: Geen auto-redirect meer, maar twee buttons
Template: commerce-checkout-completion-message.html.twig
- Groene checkmark
- "Bedankt voor je bestelling!"
- Ordernummer
- "Je ontvangt een bevestiging per email"
- Button: "Naar de voorpagina" (/)
- Button: "Ga naar mijn account" (/user)
WWW Redirect¶
Probleem: www.voedingsgeneeskunde.nl → voedingsgeneeskunde.nl werkte niet
Oplossing: Apache VirtualHost split
/etc/apache2/sites-available/voedingsgeneeskunde.nl-le-ssl.conf:
# WWW redirect
<VirtualHost *:443>
ServerName www.voedingsgeneeskunde.nl
Redirect permanent / https://voedingsgeneeskunde.nl/
# SSL certificates...
</VirtualHost>
# Main site
<VirtualHost *:443>
ServerName voedingsgeneeskunde.nl
DocumentRoot /var/www/sites/live.voedingsgeneeskunde.nl/web
# Rest of config...
</VirtualHost>
Resultaat¶
✅ curl -I https://www.voedingsgeneeskunde.nl → 301 redirect
Backup Script Fix¶
Probleem: ldrush command not found in script
Oorzaak: ldrush is bash alias, niet beschikbaar in script context
Oplossing: Volledig pad gebruiken
backup-script.sh:
DRUSH="/var/www/sites/live.voedingsgeneeskunde.nl/vendor/drush/drush/drush"
$DRUSH sql:dump --gzip --result-file="${BACKUP_DIR}/db-${DATE}.sql"
Script maakt backup van:
- Database → db-DATUM.sql.gz
- Config → config-DATUM.tar.gz
- Files (optioneel) → files-DATUM.tar.gz
Locatie: /var/www/sites/docs.voedingsgeneeskunde/docs/scripts/backup-script.sh
Docs Reorganisatie¶
Oude structuur: Verspreid over commerce/, patches/, user-experience/, integraties/
Nieuwe structuur:
docs/
├── everlasting-todo-lijst.md # Start elke sessie hier
├── project-traject.md # Timeline hele project
├── sessies/ # Chronologisch dagboek
├── documentatie/ # Per onderwerp
│ ├── commerce.md
│ ├── user-profiles.md
│ ├── integraties.md
│ └── vgbc.md
└── scripts/ # Backup, migration tools
Voordelen: - Blog/dagboek stijl: nieuwste sessies bovenaan - Tags: Commerce, Users, Integraties, VGBC, UX, Patches, Migration - Documentatie per onderwerp voor technische details - Scripts georganiseerd op één plek - Everlasting todo lijst voor snelle start elke sessie - Leesbaar voor mensen én AI agents
Navigatie (tabs): 1. Home - Quick links 2. Todo & Traject - Everlasting todo + project timeline 3. Sessies - Alle sessieverslagen chronologisch 4. Documentatie - Technische overzichten per onderwerp 5. Scripts - Backup, migration, config import
Config Export voor Live¶
Exported: config-export-for-live-20251230-1553.tar.gz (377KB)
Bevat: - Mollie payment gateway config (test keys) - Commerce settings - Tax configuration - Shipping methods - Invoice templates - User profile types - Mailchimp integration
Instructies: scripts/live-config-import-instructies.md
Technische Details¶
Files aangepast vandaag:
- /web/modules/custom/vg_commerce/src/Controller/QueuedPaymentNotifyController.php
- /web/modules/custom/vg_commerce/src/Controller/MollieReturnController.php
- /web/modules/custom/vg_commerce/vg_commerce.routing.yml
- /web/modules/custom/vg_commerce/src/EventSubscriber/PaymentProcessingLock.php
- /web/modules/custom/vg_commerce/src/EventSubscriber/PaymentIdempotency.php
- /web/themes/custom/vg25/templates/commerce-invoice/commerce-invoice.html.twig
- /web/themes/custom/vg25/vg25.theme - vg25_preprocess_commerce_invoice()
- /web/modules/custom/vg_commerce/templates/commerce-checkout-completion-message.html.twig
- /etc/apache2/sites-available/voedingsgeneeskunde.nl-le-ssl.conf
Zensical/Docs:
- zensical.toml - Updated navigation
- Nieuwe docs structuur met 5 documentatie overzichten
- Sessie index met alle 27+ sessies getagd
Resultaat¶
Critical fixes compleet:
✅ Mollie payment flow: ghost invoices opgelost
✅ Database locks verholpen
✅ Invoice template: klantgegevens + BTW percentages
✅ WWW redirect geconfigureerd
✅ Checkout completion page met buttons
✅ Backup script gereed
✅ Config export voor live (377KB)
✅ Documentatie volledig gereorganiseerd
Site is klaar voor live migration (31 dec / 1 jan)
Known Issues (Fase 3)¶
- Studentenkorting per attendee (nu hele order) - VGBC tickets
- Email templates styling
- User profile velden optimalisatie
Tags: Commerce, Patches, Critical, Documentatie, Migration