De aanbieding kwam niet aan bij 99 vaste klanten

In het account van de eigenaar stond de actie er gewoon. Zijn vaste klanten kregen hem niet te zien.

Illustratie bij de case: een prijskaartje met een doorgestreepte actieprijs naast een afgesloten map met prijsafspraken

CoolCards is een groothandel in Amsterdam. Rokersbenodigdheden en souvenirs, ruim vierhonderd zakelijke klanten. Zoals in veel groothandels heeft lang niet iedereen dezelfde prijs: 227 klanten hebben een eigen prijsafspraak, samen op 2.142 producten. Die afspraken staan in de webshop, in een plugin die daarvoor gemaakt is.

Eind augustus ging de eerste actie live. Drieëndertig artikelen in de aanbieding, met een begindatum en een einddatum.

In het account van Patrick, de eigenaar, stond de actie er gewoon, met doorgestreepte prijs en al.

Waarom hij het zelf niet kon zien

Zijn eigen account heeft geen prijsafspraken. Hij ziet dus precies wat een nieuwe klant ziet, en daar klopte alles aan.

Bij een klant mét een afspraak gebeurde iets anders. Die kreeg zijn eigen prijs te zien, ook als die hoger was dan de actieprijs. Geen doorgestreepte prijs, geen actielabel, en in de winkelwagen werd die hogere prijs ook echt afgerekend.

Ik ben het gaan tellen op de winkel zelf, want "klanten zien de actie niet" is een vermoeden.

In de aanbieding
33 artikelen
Waarvan met klantprijzen erop
32
Klanten met een eigen prijs daarop
99
Daarvan eigen prijs hoger dan de actie
95, op minstens één artikel
Grootste verschil
eigen prijs 160,00 bij een actieprijs van 139,95

De klanten die het meest bij hem kopen kregen dus de slechtste prijs, precies andersom dan de bedoeling van een actie.

Waar het aan lag

Zo is de plugin gebouwd. Customer Specific Pricing for WooCommerce, versie 4.6.17.8, laat een eigen prijsafspraak altijd voorgaan, ook als de actieprijs lager is. In het beheerscherm zit geen knop om dat om te draaien.

In de code zit die vergelijking er wel, maar hij staat standaard uit, achter het filter wdm_csp_lesser_price_disable. Eén regel PHP zet hem aan.

Wat ik heb gedaan

Op de testomgeving, een volledige kopie van de winkel, heb ik drie gevallen nagelopen op de productpagina en in de winkelwagen. Eigen prijs hoger dan de actie geeft de actie. Eigen prijs lager houdt de eigen prijs. Geen actie verandert niets.

Patrick gaf op 30 augustus akkoord. Diezelfde dag stond het op de echte winkel, en daar heb ik nagemeten dat klanten zonder prijsafspraak er niets van merken.

En toen bleek er een bug onder te zitten

Bij het lezen van die code viel me iets anders op. In dezelfde functie wordt de actieprijs vergeleken met de staffelprijzen van een product, de prijzen die gelden vanaf een bepaald aantal stuks:

$lowestPrice = min(array(1 => number_format((float)$salePrices, 4, '.', '')), $mergedPrices);

min() krijgt hier twee arrays. PHP vergelijkt arrays eerst op lengte en pas daarna op inhoud. De actieprijs zit in een array van één element, de staffels in een array van meer. De korte is dus altijd de laagste, wat de prijzen ook zijn.

Wat dat betekent voor een winkel met staffels: zet één product in de aanbieding en de hele staffel verdwijnt. Een klant die 25,00 per stuk betaalt en 22,00 vanaf vijf stuks, krijgt de actieprijs bij elk aantal.

Bij CoolCards zat er op geen van de actieproducten een staffel, dus daar deed het niets. In een winkel die staffels en acties wel combineert, gebeurt het gewoon.

Wat de maker ermee deed

Op 30 augustus heb ik het gemeld bij WisdmLabs, de maker van de plugin. Met het bestand, het regelnummer en het scenario erbij, plus het verzoek om van dat verborgen filter een gewone instelling te maken.

Op 3 september ging het naar hun ontwikkelaars. Op 10 september kwam het antwoord:

"You were absolutely right about the quantity-tier issue. The min() call was indeed comparing the single-element sale-price array to the full tier array, and because of how PHP compares arrays, the shorter array was always treated as lower regardless of the actual prices."

WisdmLabs, 10 september 2026

Ze hebben de patch geschreven en die gaat mee in de volgende versie. De vergelijking loopt nu per staffel, zodat alleen de staffels worden overschreven waar de actieprijs echt lager is. Verder lieten ze weten dat het filter officieel ondersteund is, en dat er een vinkje bij komt naast de bestaande instelling, met de tekst die ik had voorgesteld: "Apply the lower of the customer price and the sale price".

Dat laatste is voor CoolCards het belangrijkste. Wat nu met één regel eigen code aan staat, wordt straks een knop die iedereen kan zien staan.

Het risico dat overbleef

Tot die versie er is, hangt de oplossing aan een filter in andermans plugin. Verdwijnt dat filter bij een update, dan blijft die ene regel gewoon draaien en doet hij niets meer. Geen foutmelding, geen regel in het log. De prijzen vallen terug op "eigen prijs wint altijd" en je merkt het pas als een klant belt.

Daar staat sinds 30 augustus een controle op. Die kijkt elke ochtend naar vier dingen: welke versie van de plugin er draait, of het filter nog in de code staat, en of de twee bestanden nog zijn wat ze horen te zijn. Verandert er iets, dan komt er die dag een bericht binnen.

Waarom zoiets blijft liggen

Niemand deed hier iets fout. De actie stond goed ingesteld en de plugin deed wat hij hoort te doen. Alleen hangt het antwoord op "wat kost dit artikel" in deze winkel af van wie het vraagt, en dat zie je niet zolang je in je eigen account kijkt.

Er komt geen melding van en hij staat in geen enkel overzicht. De klanten die het treft zijn bovendien de klanten die er al jaren zijn en niet snel bellen over een paar euro.

Weet jij wat jouw klanten zien?

Een uur meekijken levert meestal al een lijst op. Ik begin met tellen.

Boek een gesprek Liever mailen? info@stolksupport.nl