Module 2 · 2.4
Wat je shop openbaar laat zien
Module 2: Installeren en inrichten · Leestijd: 10 minuten
Leerdoel: Na deze les kun je uitleggen wat de Store API en de REST API van WooCommerce zijn, welke gegevens openbaar horen te zijn en welke niet, en hoe je API-sleutels en webhooks veilig gebruikt.
Kernbegrippen: API, REST API van WordPress, Store API (wc/store/v1), REST API van WooCommerce (wc/v3), JSON, openbaar en afgeschermd, API-sleutel, lees- en schrijfrechten, minste rechten, webhook, geheime sleutel van een webhook, X-WP-Total
Een winkel met twee deuren
Een bezoeker ziet je shop als webpagina's. Maar je shop heeft ook "deuren" voor programma's: adressen waar een programma gegevens kan opvragen of versturen, zonder de opmaak van een pagina. Zo'n deur heet een API (application programming interface). WordPress heeft er een onder /wp-json/, de REST API. De WordPress-cursus liet in les 7.3 zien dat je daar bijvoorbeeld gebruikersnamen kunt opvragen als je niets afschermt.
WooCommerce voegt twee eigen API's toe, met een heel verschillend doel:
| Store API | REST API van WooCommerce | |
|---|---|---|
| Adres | /wp-json/wc/store/v1/... | /wp-json/wc/v3/... |
| Voor wie | De browser van een bezoeker (de blokken voor winkelwagen en afrekenen, les 2.2) | Andere programma's: boekhouding, voorraad, een app, een koppeling met een marktplaats |
| Sleutel nodig | Nee, openbaar | Ja, een API-sleutel van een beheerder (of een ingelogde gebruiker met rechten) |
| Wat erin zit | Producten, prijzen, voorraadstatus, categorieën, beoordelingen; de winkelwagen en bestelling van de bezoeker zelf | Alles: bestellingen van iedereen, klanten, coupons, instellingen, rapporten |
De Store API is dus de etalage-ingang: wat in je winkel op een productpagina staat, staat er ook in, alleen als gegevens. De REST API van WooCommerce is de achterdeur van het magazijn: die hoort op slot.
De Store API: wat een bezoeker (en iedereen) kan opvragen
Open in je browser:
https://shop.example.com/wp-json/wc/store/v1/productsJe krijgt een lijst in JSON, een tekstformaat voor gegevens. Voor elk product zie je onder meer de naam, de slug, het type (enkelvoudig, variabel), het adres van de productpagina (permalink), de SKU, de prijzen, afbeeldingen, categorieën, of het op voorraad is en of het te koop is. In de kopregels van het antwoord staat X-WP-Total: het aantal producten dat de winkel aan bezoekers laat zien.
Een paar dingen om te weten:
- Prijzen staan in centen. Een theepot van € 34,95 staat erin als
"price": "3495"met"currency_minor_unit": 2. Je deelt door 100. Of dat de prijs met of zonder btw is, hangt af van je instelling bij "Prijzen weergeven in de winkel" (les 4.1). Die eigenschap gebruiken we in de opdracht van les 4.1. - Alleen wat zichtbaar is. Producten die in concept staan, privé zijn of verborgen in de catalogus, telt de Store API niet mee. Daarom kan
X-WP-Totallager zijn dan het aantal in je beheer. - Lezen mag iedereen, schrijven niet zomaar. Iets in de winkelwagen leggen of afrekenen via de Store API kan alleen met een eenmalige code (nonce) uit de pagina, en dan alleen voor de eigen winkelwagen van die bezoeker.
Is het erg dat dit openbaar is? Nee: het zijn dezelfde gegevens die op je productpagina's staan. Een concurrent die je prijzen wil volgen, kan dat ook met de gewone pagina's. Wel goed om te beseffen: alles wat je in een productveld zet, kan in de Store API terechtkomen. Zet nooit inkoopprijzen, namen van leveranciers of interne notities in de korte of lange beschrijving "omdat het thema dat veld toch niet toont".
Zet de Store API ook niet dicht. De blokken voor winkelwagen en afrekenen hebben hem nodig (les 2.2). Beveiligingsplugins die "de REST API uitzetten voor bezoekers" breken daardoor soms het afrekenen. Wil je de REST API beperken, zonder dan de Store API uit.
Misbruik van de Store API bestaat wel, maar dan aan de schrijfkant: aanvallers die met gestolen kaartnummers duizenden kleine bestellingen proberen. Dat heet card testing; daarover gaat les 6.3.
De REST API van WooCommerce: altijd achter een sleutel
Open nu, zonder ingelogd te zijn:
https://shop.example.com/wp-json/wc/v3/ordersHet goede antwoord is een foutmelding met status 401 (niet ingelogd) en een code als woocommerce_rest_cannot_view. Je shop zegt: "dit mag jij niet zien". Zo hoort het. Krijg je hier een lijst met bestellingen, dan is er iets ernstig mis: een plugin die rechten openzet, een aangepaste code in het thema, of een sleutel die in een openbaar adres staat. Dan heb je een mogelijk datalek (WordPress-cursus, les 7.5, en kennisbank 6749).
Programma's die bij je bestellingen moeten, krijgen een API-sleutel. Die maak je bij WooCommerce > Instellingen > Geavanceerd > REST API (Advanced > REST API). Een sleutel bestaat uit twee delen (een consumer key en een consumer secret) en hoort bij een WordPress-gebruiker. Je kiest de rechten:
- Lezen: het programma mag gegevens opvragen;
- Schrijven: het programma mag gegevens aanmaken en wijzigen;
- Lezen/schrijven: beide.
Regels die je altijd volgt:
- Minste rechten. Een boekhoudkoppeling die alleen bestellingen ophaalt, krijgt alleen lezen. Een voorraadkoppeling die voorraad bijwerkt, heeft schrijven nodig, maar een rapportagetool niet.
- Eén sleutel per koppeling, met een duidelijke omschrijving ("Boekhouding, alleen lezen, 2026"). Stopt een koppeling, dan trek je alleen die sleutel in.
- Koppel de sleutel aan een gebruiker met passende rechten. Een sleutel van een beheerder kan alles wat een beheerder kan. Maak liever een aparte gebruiker met de rol Winkelmanager (les 6.2).
- Bewaar de geheime helft veilig. Je ziet hem één keer bij het aanmaken. Hij hoort in de instellingen van het programma of in een wachtwoordmanager, niet in een mail, een gedeeld document of een openbare code-opslag.
- Ruim op. Bij REST API zie je per sleutel wanneer hij voor het laatst is gebruikt. Een sleutel die maanden niet is gebruikt, trek je in.
Webhooks: je shop belt een ander programma
Een API wacht tot iemand vraagt. Een webhook werkt andersom: bij een gebeurtenis in je shop (een nieuwe bestelling, een gewijzigd product) stuurt WooCommerce zelf een bericht naar een adres dat jij opgeeft. Zo hoort je verzendprogramma direct dat er een bestelling is, zonder elke minuut te vragen. Je stelt ze in bij WooCommerce > Instellingen > Geavanceerd > Webhooks.
Drie dingen om op te letten:
- Het bericht bevat persoonsgegevens. Een webhook bij een nieuwe bestelling stuurt naam, adres en bestelde producten mee. Stuur dat alleen naar een adres via https en naar een partij die in je privacyverklaring en verwerkingenlijst staat (les 5.5).
- De geheime sleutel. Bij een webhook vul je een geheime sleutel in. Daarmee kan het ontvangende programma controleren dat het bericht echt van jouw shop komt en niet van iemand die het adres heeft geraden. Laat hem niet leeg en deel hem alleen met de ontvanger.
- Mislukte aflevering. Is het ontvangende adres een tijd onbereikbaar, dan kan WooCommerce de webhook na herhaalde fouten uitschakelen. Kijk na een storing bij Webhooks of ze nog actief zijn.
Verwar dit niet met de webhook van je betaalprovider (les 4.4). Die werkt andersom: de provider meldt jouw shop dat een betaling gelukt is.
In de praktijk: zo ziet het eruit in WooCommerce
Bij andere hosters werkt het hetzelfde; dit zijn onderdelen van WooCommerce zelf.
- Open in een privévenster
/wp-json/wc/store/v1/productsop je (test)winkel. Zoek een product op en reken de prijs om. - Open in hetzelfde privévenster
/wp-json/wc/v3/orders. Je hoort status 401 te zien. - Ga naar WooCommerce > Instellingen > Geavanceerd > REST API. Bekijk welke sleutels er zijn, bij welke gebruiker en met welke rechten. Trek sleutels in die je niet (meer) kent.
- Bekijk bij Webhooks welke webhooks er zijn en naar welk adres ze gaan.
- Heb je een beveiligingsplugin die de REST API beperkt, controleer dan dat de Store API is uitgezonderd.
Samenvatting
- De Store API (
wc/store/v1) is openbaar en bevat wat ook op je productpagina's staat; de blokken voor winkelwagen en afrekenen hebben hem nodig. - Zet geen interne gegevens in productvelden: ze kunnen via de Store API zichtbaar worden.
- De REST API van WooCommerce (
wc/v3) hoort zonder sleutel een 401 te geven; een lijst met bestellingen zonder sleutel is een mogelijk datalek. - API-sleutels: minste rechten, één per koppeling, aan een passende gebruiker, geheim bewaren, ongebruikte intrekken.
- Webhooks sturen persoonsgegevens naar een ander programma: alleen via https, met een geheime sleutel, naar een partij uit je verwerkingenlijst.
Quiz
Opdracht
Opdracht A2.4: Wat laat je shop openbaar zien? Vul het adres van je (test)winkel in en het aantal producten dat zichtbaar is in je winkel. Het programma doet drie opvragingen, zonder cookies en zonder sleutel, alleen lezen:
/wp-json/wc/store/v1/products?per_page=1(de Store API, via het REST-adres dat je site zelf opgeeft);/wp-json/wc/v3/orders?per_page=1;/wp-json/wc/v3/customers?per_page=1.
Goed is: de Store API antwoordt met status 200 en een JSON-lijst; de kopregel X-WP-Total is gelijk aan het aantal dat je invulde; orders en customers geven 401, 403 of 404.
Oranje: X-WP-Total wijkt af (producten in concept, privé of verborgen tellen niet mee); de Store API geeft 401 of 403, meestal door een beveiligingsplugin, waardoor de afrekenblokken niet werken.
Rood: de Store API is niet bereikbaar terwijl je site WooCommerce draait; of orders of customers geven een lijst terug. Dat laatste is ernstig: zet het meteen dicht, controleer je API-sleutels en plugins, en bekijk of je een datalek moet melden. Het programma bewaart in dat geval alleen de statuscode, nooit de inhoud.
Kijk daarna zelf bij REST API en Webhooks: welke sleutels en webhooks staan er, en weet je van elk waarvoor hij is?
Verder lezen
- Gratis WordPress-cursus 7.3: Inloggen: wachtwoorden, tweestapsverificatie en brute force
- Gratis WordPress-cursus 7.5: Gehackt: herkennen, herstellen en voorkomen
- WordPress: toegang tot xmlrpc.php lukt niet
- Is dit een datalek en moet ik het melden?
- De Store API (developer.woocommerce.com, Engels): https://developer.woocommerce.com/docs/apis/store-api/
- Rate limiting voor de Store API (developer.woocommerce.com, Engels): https://developer.woocommerce.com/docs/apis/store-api/rate-limiting/
