# Leeftijdscontrole PrestaShop: Blokkerend Venster voor CBD, Alcohol, Vape & Zorgverleners: volledige gids

> De module dfagegate voegt een blokkerend leeftijdsverificatievenster toe aan uw PrestaShop 8- of 9-winkel. Hij dekt twee aparte markten: de standaardmodus voor leeftijdsgereguleerde producten (CBD, alcohol, vape, wapenhandel, aanstekers, 18+-producten),…

- Pagina: <https://www.datafirefly.com/nl/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/>
- Taal: nl
- Bijgewerkt op: 2026-09-28
- Andere talen: [fr](https://www.datafirefly.com/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md), [en](https://www.datafirefly.com/en/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md), [es](https://www.datafirefly.com/es/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md), [de](https://www.datafirefly.com/de/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md), [it](https://www.datafirefly.com/it/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md), [pl](https://www.datafirefly.com/pl/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md), [pt](https://www.datafirefly.com/pt/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md)
- Index: <https://www.datafirefly.com/nl/documentation/llms.txt>

De module **dfagegate** voegt een **blokkerend** leeftijdsverificatievenster toe aan uw PrestaShop 8- of 9-winkel. Hij dekt twee aparte markten: de **standaardmodus** voor leeftijdsgereguleerde producten (CBD, alcohol, vape, wapenhandel, aanstekers, 18+-producten), en de **medische modus** voor medische hulpmiddelen die aan zorgverleners zijn voorbehouden, in de zin van artikel L5122-9 van de Franse Code de la santé publique.

**Compatibiliteit** — PrestaShop 1.7.7+, 8.x en 9.0. PHP 7.4 minimum, 8.1+ aanbevolen. Multistore en meertalig (FR/EN/ES/DE vooringevuld bij de installatie).

## Installatie

De installatie volgt de standaard PrestaShop-workflow. Na aankoop op DataFirefly ontvangt u een ZIP-bestand `dfagegate-X.Y.Z.zip`.

### Via de back-office (aanbevolen)

1. Log in op uw PrestaShop back-office
2. Ga naar **Modules → Modulecatalogus**
3. Klik rechtsboven op **Een module uploaden**
4. Selecteer de ZIP `dfagegate-X.Y.Z.zip`
5. Klik na de upload op **Installeren**

### Via FTP

1. Pak de ZIP lokaal uit
2. Upload de map `dfagegate/` naar `modules/` van uw PrestaShop
3. Ga naar **Modules → Modulecatalogus**
4. Zoek "DataFirefly Age Gate" en klik op **Installeren**

**Belangrijk** — Na de installatie **is de module standaard uitgeschakeld**. Dat is opzettelijk: zo kunt u de teksten en de modus configureren voordat u uw winkel blokkeert. Ga naar de configuratie van de module en activeer de schakelaar in het tabblad _Algemeen_ zodra alles is ingesteld.

## Eerste configuratie

Open de configuratie: **Modules → Geïnstalleerde modules → DataFirefly Age Gate → Configureren**.

De configuratie is georganiseerd in 6 tabbladen:

- **Algemeen** — activering, modus, verificatietype, minimumleeftijd, weergavebereik
- **Inhoud** — meertalige teksten (titel, bericht, knoppen, wettelijke vermeldingen)
- **Uiterlijk** — logo, kleuren, backdrop blur
- **Gedrag** — cookie, redirect, bypass
- **Medische modus** — beroepen en RPPS/ADELI (verschijnt alleen in de medische modus)
- **Logs & AVG** — logging, statistieken en diagnose

### Tabblad Algemeen

Hier configureert u het hoofdgedrag van de module.

- **Module inschakelen** — Ja/Nee-schakelaar, bepaalt de globale weergave van het venster
- **Modus** — _Standaard_ (CBD, alcohol, vape, wapenhandel) of _Medisch_ (zorgverleners)
- **Verificatietype** — _Ja/nee-knop_, _Geboortedatum_, of _Beroepsverklaring_
- **Minimumleeftijd** — standaard 18, 21 voor bepaalde markten (bijvoorbeeld Noorwegen voor alcohol)
- **Weergavebereik**: de hele winkel, gekozen categorieën of gekozen producten
- **Venster testen**: knop die de winkel in de voorbeeldmodus opent (zie de sectie Diagnose)

**Welk verificatietype kiezen?** De _ja/nee-knop_ past bij de meeste gevallen (CBD, alcohol voor het brede publiek, vape): snel, weinig frictie, voldoende afschrikkend voor een controle van de toezichthouder. De _geboortedatum_ is strikter en aanbevolen voor wapenhandel of nicotinehoudende vloeistoffen. De _beroepsverklaring_ is voorbehouden aan de medische modus.

### Weergavebereik: categorieën of producten kiezen

Sinds versie 1.1.0 hoeft het venster niet meer de hele winkel te dekken. U stelt het weergavebereik in via drie standen:

- **De hele winkel**: het bekende gedrag en de standaardinstelling. Het venster verschijnt op elke frontpagina
- **Gekozen categorieën**: het venster verschijnt op de pagina's van de gekozen categorieën en op de productpagina's van de producten die erin zitten. U vinkt de categorieën aan in een boomstructuur met selectievakjes, een filterveld en een selectieteller
- **Gekozen producten**: het venster verschijnt alleen op de productpagina's van de gekozen producten. U zoekt op naam of referentie, en de gekozen producten verschijnen als verwijderbare labels

In de categoriestand staat de optie **Subcategorieën meenemen** standaard aan. Vinkt u de categorie CBD aan, dan zijn de subcategorieën Oliën, Bloemen en Harsen gedekt zonder ze stuk voor stuk aan te vinken. De toewijzing wordt opgelost via de nested sets van PrestaShop, in één SQL-query.

**Gemengde winkel?** Dat is het typische gebruiksgeval: een delicatessenwinkel met een afdeling gedistilleerd, of een parafarmacie met enkele voorbehouden hulpmiddelen. Richt het venster op de gevoelige categorieën en de rest van de catalogus blijft zonder frictie toegankelijk.

In de productstand worden de overzichtspagina's (categorieën, zoekresultaten) niet geblokkeerd: de bezoeker kan de miniaturen van de betrokken producten zien, en het venster verschijnt pas bij het openen van de productpagina. Wilt u een hele afdeling beschermen, inclusief de overzichten, kies dan de categoriestand.

De weergavebeslissing wordt server-side genomen, pagina per pagina, en is zichtbaar in het diagnosecommentaar via de waarde `scope=all|categories|products`. Een lege selectie wordt bij het opslaan geweigerd: de module laat u geen gerichte stand bewaren zonder gekozen categorie of product.

### Tabblad Inhoud

Elke in uw PrestaShop geactiveerde taal heeft haar eigen tekstblok. De standaardwaarden zijn vooringevuld in **FR, EN, ES en DE**. Per taal kunt u configureren:

- **Titel** — verschijnt groot bovenaan het venster (standaard: "Leeftijdsverificatie")
- **Bericht** — verklarende hoofdtekst, regeleinden blijven behouden
- **Bevestigknop** — label van de positieve knop (standaard: "Ik ben 18 jaar of ouder")
- **Weigerknop** — label van de negatieve knop
- **Wettelijke vermelding** — tekst onderaan het venster (bijvoorbeeld: "Alcoholmisbruik is gevaarlijk voor de gezondheid. Geniet, maar drink met mate.")
- **Bericht bij weigering** — scherm dat wordt getoond wanneer de gebruiker weigert, vóór de redirect

**HTML** — De inhoud wordt bij het opslaan gesaneerd (alleen platte tekst). De regeleinden worden bij de weergave omgezet in <br>-tags via een automatisch `nl2br`-filter.

### Tabblad Uiterlijk

Personaliseer de look van het venster zodat hij bij uw huisstijl past:

- **Logo** — PNG, JPG, SVG of WEBP, max. 2 MB, getoond bovenaan het venster
- **Achtergrondkleur** — kleur van de hoofdkaart (standaard wit)
- **Primaire kleur** — titel en hoofdknop (standaard zwart #111111)
- **Tekstkleur** — de berichttekst
- **Overlaykleur** — laag achter het venster, accepteert de CSS-formaten `rgba()` en hex (standaard: `rgba(15,15,20,0.85)`)
- **Backdrop blur** — vervaging op de achtergrond (modern effect, werkt in alle actuele browsers)

### Tabblad Gedrag

Bepaalt de persistentie van de keuze en de uitsluitingsgevallen.

- **Cookieduur** — in dagen (standaard 90). Zet `0` voor een sessiecookie (verwijderd bij het sluiten van de browser)
- **Redirect-URL bij weigering** — laat leeg om alleen het weigeringsbericht te tonen, of vul een externe URL in (Google, leverancierspagina, enzovoort)
- **IP-bypass** — lijst met IP's (één per regel) waarvoor het venster niet verschijnt. Ideaal voor u en uw team tijdens de tests
- **URL-bypass** — uitgesloten gedeeltelijke paden. Vooringevuld met `/legal`, `/contact`, `/cgv`, `/mentions-legales`, `/politique-confidentialite`
- **Bypass voor ingelogde klanten** — ingeschakeld zien al ingelogde klanten het venster niet (nuttig als uw winkel is voorbehouden aan al gevalideerde accounts)

### Tabblad Medische modus

Dit tabblad geldt alleen als de **modus** op _Medisch_ staat en het **verificatietype** op _Beroepsverklaring_.

- **Beroepenlijst** — één per regel. Standaard: Arts, Apotheker, Verpleegkundige, Kinesitherapeut, Tandarts, Dierenarts, Andere zorgverlener. Aanpasbaar aan uw doelgroep
- **RPPS-/ADELI-nummer verplicht** — ingeschakeld verschijnt een veld in het venster. Validatie via regex die 9 tot 11 cijfers accepteert. **Het nummer wordt niet opgeslagen**, het dient uitsluitend voor de server-side validatie

**Juridische conformiteit** — De medische modus materialiseert een verklaring op erewoord in de zin van artikel L5122-9 van de Franse Code de la santé publique, dat de reclame voor bepaalde medische hulpmiddelen voorbehoudt aan bevoegde zorgverleners. **Deze module vervangt geen juridische review van uw catalogus door een gespecialiseerde advocaat**. Raadpleeg uw adviseur om uw configuratie te valideren.

### Tabblad Logs & AVG

Optionele logging en conformiteitsinformatie.

- **Weigeringen loggen** — registreert elke weigering in de tabel `ps_dfagegate_log` met SHA-256-gehasht IP (nooit in klare tekst), datum, reden
- **Bewaartermijn van de logs**: in dagen (standaard 365). Zet `0` voor onbeperkt bewaren. Regels ouder dan de ingestelde termijn worden automatisch opgeschoond bij het openen van de configuratiepagina

Dit tabblad toont ook een AVG-geheugensteun:

- **Geplaatste cookie** — `dfagegate_ok`
- **Categorie** — strikt noodzakelijk (wettelijke toegangsconformiteit)
- **Gegevens** — waarde "1", configureerbare duur, SameSite=Lax, Secure bij HTTPS

Sinds versie 1.1.0 toont dit tabblad ook de **weigeringsstatistieken**: het totaal van de laatste 30 dagen, de verdeling per reden en de 15 meest recente weigeringen. Een knop **Logs opschonen**, met bevestiging, leegt de tabel in één klik, bijvoorbeeld na een audit.

## Configureren volgens uw markt

Enkele typeconfiguraties ter inspiratie.

### CBD-winkel voor het brede publiek

- Modus: **Standaard**
- Verificatietype: **Ja/nee-knop**
- Minimumleeftijd: **18**
- Cookieduur: **90 dagen** (goede balans tussen conformiteit en UX)
- Redirect-URL: _leeg_ (alleen het weigeringsbericht)
- Wettelijke vermelding: "Het gebruik van cannabidiol kan een wisselwerking hebben met bepaalde geneesmiddelen. Raadpleeg uw arts."

### Winkel voor gedistilleerd / premium alcohol

- Modus: **Standaard**
- Verificatietype: **Geboortedatum** (striktere controle voor premium markten)
- Minimumleeftijd: **18** (of 21 voor de Amerikaanse/Noorse markten)
- Redirect-URL: een officiële informatiepagina over verantwoord alcoholgebruik
- Wettelijke vermelding: "Alcoholmisbruik is gevaarlijk voor de gezondheid. Geniet, maar drink met mate."

### Vape- / nicotinehoudende e-liquidwinkel

- Modus: **Standaard**
- Verificatietype: **Geboortedatum** (sterk aanbevolen voor nicotine)
- Minimumleeftijd: **18**
- Weigeringen loggen: **Ja** (nuttig bij een controle van de toezichthouder)

### Wapenwinkel

- Modus: **Standaard**
- Verificatietype: **Geboortedatum** (verplicht)
- Minimumleeftijd: **18**
- URL-bypass: voeg `/reglementation`, `/permis-de-chasse` toe
- Weigeringen loggen: **Ja**

### Delicatessenwinkel met afdeling gedistilleerd (gemengde winkel)

- Modus: **Standaard**
- Verificatietype: **Ja/nee-knop**
- Minimumleeftijd: **18**
- Weergavebereik: **Gekozen categorieën**, met de categorie Gedistilleerd en haar subcategorieën
- Resultaat: klanten die olijfolie of conserven kopen, browsen zonder frictie, en het venster verschijnt alleen in de leeftijdsgebonden afdeling

### Winkel voor medisch materiaal (professionele hulpmiddelen)

- Modus: **Medisch**
- Verificatietype: **Beroepsverklaring**
- Beroepenlijst: Arts, Apotheker, Kinesitherapeut, Osteopaat (aan te passen aan uw catalogus)
- RPPS-/ADELI-nummer verplicht: **Ja**
- Bypass voor ingelogde klanten: **Ja** (als u het beroep al bij de registratie valideert)

## Hoe de verificatie op geboortedatum werkt

In tegenstelling tot een simpele knop voert de verificatie op geboortedatum een berekening **server-side** uit, niet in de browser. Het volledige verloop:

1. De bezoeker voert dag, maand en jaar in het venster in
2. Het JavaScript verstuurt deze waarden naar de AJAX-controller `DfagegateAjaxModuleFrontController`
3. PHP valideert de datum met `checkdate()` en berekent daarna de leeftijd via `DateTimeImmutable::diff()`
4. Is de leeftijd lager dan de geconfigureerde drempel, dan geeft de server een JSON-antwoord `success=false, denied=true` terug met de foutmelding
5. Het venster toont het weigeringsbericht en redirect na 2 seconden
6. Is de leeftijd hoger dan of gelijk aan de drempel, dan wordt de cookie `dfagegate_ok` geplaatst en sluit het venster

**Waarom server-side?** Een puur JavaScript-controle kan via DevTools in minder dan 10 seconden worden omzeild. De serverberekening garandeert dat een gebruiker onder de wettelijke leeftijd geen toegang tot de site krijgt, zelfs met technische kennis. Dat is essentieel om een controle van de toezichthouder te doorstaan.

Merk op dat **de geboortedatum nooit wordt opgeslagen** — ze wordt gebruikt voor de duur van een berekening en daarna vergeten. Alleen de binaire validatie (geaccepteerd / geweigerd) wordt via de cookie onthouden.

## Hoe de medische modus werkt

De medische modus volgt een vergelijkbare logica maar met andere velden:

1. Het venster toont een keuzelijst met beroepen (configureerbaar) en eventueel een RPPS-/ADELI-veld
2. Een selectievakje voor de **verklaring op erewoord** is aanwezig en verplicht
3. De AJAX-controller valideert dat een beroep is geselecteerd
4. Is RPPS/ADELI verplicht, dan valideert de server het formaat via een reguliere expressie die 9 tot 11 opeenvolgende cijfers accepteert
5. Geen enkele opslag: noch het beroep noch het nummer wordt in de database bewaard — de cookie `dfagegate_ok` materialiseert alleen de geslaagde passage

**Ontwerpkeuze** — De regelgeving L5122-9 vereist een materialisatie van de verklaring, niet noodzakelijk een realtimeverificatie in het nationale register. Onze aanpak is _compliance minimum viable_: we vragen de verklaring, valideren haar formeel, traceren de weigering indien ingeschakeld, maar verzamelen geen onnodig persoonsgegeven. Hebt u een realtime-RPPS-verificatie tegen het ANS-register nodig, dan is dat een aparte maatwerkontwikkeling.

## Multistore

De module is **100% multistore-compatibel**. Alle configuraties (modus, verificatietype, meertalige teksten, kleuren, bypass, weergavebereik) worden per winkelcontext opgeslagen via `id_shop_group` en `id_shop`. Dat betekent dat u in eenzelfde PrestaShop kunt hebben:

- Een winkel **CBD FR** in standaardmodus 18 jaar met Franse teksten
- Een winkel **vape UK** in standaardmodus 18 jaar met Engelse teksten
- Een winkel **medisch materiaal DE** in medische modus met verplichte RPPS en Duitse teksten

Om een specifieke subwinkel te configureren:

1. Kies in de contextkiezer bovenaan de back-office de doelsubwinkel
2. Open de configuratie van de module
3. Wijzig de waarden — ze worden alleen voor deze winkel bewaard

De **hooks worden bij de installatie op alle winkels geregistreerd** via `Shop::getCompleteListOfShopsID()`, wat de klassieke valkuil vermijdt van de module die alleen op de huidige winkel draait.

## Compatibiliteit met aangepaste thema's

De module gebruikt de standaardhook `displayBeforeBodyClosingTag` om het venster vlak vóór het sluiten van de body-tag te injecteren. Deze hook hoort universeel te zijn op PrestaShop 1.7.5+.

Helaas **roepen sommige aangepaste thema's deze hook niet aan** in hun layout. Voor dat geval bevat dfagegate een **JavaScript-fallback**:

1. PHP pre-rendert de volledige HTML van het venster en geeft die aan het JS door via `Media::addJsDef`
2. Bij `DOMContentLoaded` controleert het script of het element met de ID `dfagegate-modal` in de DOM bestaat
3. Zo ja, alles is in orde — de hook heeft gewerkt
4. Zo nee, dan injecteert het script het venster zelf via `insertAdjacentHTML('beforeend', ...)`
5. Een bericht `console.info` bevestigt de activering van de fallback: "[dfagegate] modal injected via JS fallback (theme does not trigger displayBeforeBodyClosingTag)."

**Praktisch resultaat** — De module werkt op elk PrestaShop 1.7.5+-thema, inclusief onvolledige aangepaste thema's, **zonder de layout te hoeven wijzigen**. U kunt hem uitrollen zonder afstemming met uw thema-agentschap.

## Diagnose en debug

Eenmaal geactiveerd voegt dfagegate een **HTML-commentaar in de head-tag** van elke frontpagina toe, in de vorm "dfagegate v1.1.0 enabled=1 scope=all should_display=1".

Dit commentaar is uw eerste diagnosepunt. Bekijk de broncode van een frontpagina (Ctrl+U of Cmd+U) en zoek "dfagegate".

| Commentaar | Interpretatie |
| --- | --- |
| Helemaal geen commentaar | De hook `displayHeader` is niet geregistreerd — controleer of de module daadwerkelijk is geïnstalleerd en actief |
| `enabled=0` | De schakelaar "Module inschakelen" staat op Nee in het tabblad Algemeen |
| `enabled=1 should_display=0` | Er is een bypass actief: uw IP staat op de whitelist, de huidige URL matcht een uitgesloten pad, u bent een ingelogde klant met ingeschakelde bypass, of de huidige pagina valt buiten het gerichte weergavebereik. Controleer de waarde `scope=` in het commentaar |
| `enabled=1 should_display=1` | Alles is in orde aan serverzijde. Verschijnt het venster niet, kijk dan in de browserconsole naar een eventueel JS-fallback- of foutbericht |

### Het venster verschijnt nog steeds niet?

Snelle checklist:

1. Is het diagnosecommentaar aanwezig met `should_display=1`? Zo nee, corrigeer de configuratie
2. Open de winkel in **privénavigatie**. De cookie `dfagegate_ok` kan uit een vorige sessie stammen
3. Controleer uw IP in de bypass van het tabblad _Gedrag_
4. Staat het weergavebereik op gekozen categorieën of producten, controleer dan of de pagina waarop u zich bevindt binnen het bereik valt: de waarde `scope=` in het commentaar toont de actieve stand
5. Open de browserconsole (F12). Zoek `[dfagegate]` voor eventuele fallback-injectie- of foutberichten
6. Raadpleeg de PrestaShop-logs in **Geavanceerde instellingen → Logs**, filter op "dfagegate"
7. **Leeg de PrestaShop-cache** na elke configuratiewijziging: _Geavanceerde instellingen → Prestaties → Cache legen_

### Testen met de voorbeeldmodus

Sinds versie 1.1.0 hoeft u de cookie niet meer te verwijderen om het venster opnieuw te zien. De testknop **Venster testen** op het tabblad _Algemeen_ opent de winkel met de parameter `?dfagegate_preview=1` in de URL. In deze stand verschijnt het venster ook wanneer de cookie `dfagegate_ok` aanwezig is, en er wordt geen enkele cookie geplaatst: u kunt de test zo vaak herhalen als u wilt, zonder uw browsersessie te raken.

Is het weergavebereik gericht ingesteld, houd de parameter dan in de URL terwijl u naar een gedekte pagina navigeert: de voorbeeldmodus respecteert het ingestelde bereik.

### De cookie in de browser resetten

Om het venster opnieuw te testen zonder van IP te wisselen:

1. Open de DevTools (F12)
2. Tabblad **Application** (Chrome) of **Storage** (Firefox)
3. Sectie **Cookies** → uw domein
4. Verwijder de regel `dfagegate_ok`
5. Herlaad de pagina

## AVG-conformiteit

De module is standaard ontworpen om AVG-conform te zijn.

### De cookie `dfagegate_ok`

- **Type** — strikt noodzakelijk voor het naleven van een wettelijke toegangsverplichting
- **Rechtsgrond** — vrijgesteld van voorafgaande toestemming (categorie van de strikt noodzakelijke cookies volgens de aanbevelingen van de toezichthouders)
- **Waarde** — binair (`1` = bevestigd)
- **Duur** — configureerbaar (standaard 90 dagen), of sessie als u 0 invult
- **Attributen** — `SameSite=Lax`, automatisch `Secure` bij HTTPS, `Path=/`

**Concreet** — U hoeft deze cookie **niet** aan uw toestemmingsbanner toe te voegen. Hij valt in dezelfde categorie als de PrestaShop-sessiecookie of de CSRF-cookie: noodzakelijk voor de wettelijke werking van de site, dus vrijgesteld.

### De weigeringslogs

Schakelt u de optie _Weigeringen loggen_ in, dan wordt elke weigering geregistreerd in de tabel `ps_dfagegate_log` met:

- `id_shop` — betrokken subwinkel
- `reason` — reden van de weigering (`user_refused` of `dob_under_age`)
- `age` — opgegeven leeftijd indien van toepassing
- `profession` — opgegeven beroep indien van toepassing
- `ip_hash` — **SHA-256 van het IP**, nooit het IP in klare tekst
- `date_add` — tijdstempel

De SHA-256-hashing maakt het IP **onomkeerbaar** en laat tegelijk toe pogingen te ontdubbelen (eenzelfde IP produceert altijd dezelfde hash). Dat is het aanbevolen compromis voor toegangsstatistieken.

Sinds versie 1.1.0 is de bewaartermijn automatisch: regels ouder dan de termijn die op het tabblad _Logs & AVG_ is ingesteld (standaard 365 dagen), worden opgeschoond bij het openen van de configuratiepagina. Dat is een directe toepassing van het minimalisatiebeginsel van de AVG, zonder crontaak of handmatige actie. De statistieken in de back-office zijn gebaseerd op deze gehashte gegevens, zonder ooit een IP in klare tekst te tonen.

### De verificatiegegevens

- De **geboortedatum** passeert via AJAX voor de berekening maar **wordt nooit opgeslagen**
- Het **RPPS-/ADELI-nummer** wordt server-side gevalideerd en daarna **vergeten**, nooit opgeslagen
- Alleen de **binaire validatie** wordt bewaard, via de cookie

## Technische structuur en integratie

Voor ontwikkelaars die verder willen gaan of de module in een aangepaste workflow willen integreren.

### Gebruikte hooks

- `displayHeader` — injecteert het diagnosecommentaar
- `actionFrontControllerSetMedia` — registreert CSS en JS, geeft de configuratie en de pre-gerenderde HTML van het venster door aan het JS
- `displayBeforeBodyClosingTag` — rendert het venster server-side (JS-fallback als hij in het thema ontbreekt)

### AJAX-endpoints

De AJAX-controller antwoordt op de URL `/module/dfagegate/ajax` en accepteert twee acties:

- `action=confirm` — met de parameters volgens het verificatietype (niets voor ja/nee, day/month/year voor geboortedatum, profession/rpps voor medisch)
- `action=refuse` — registreert de weigering en geeft de redirect-URL terug

De antwoorden zijn in JSON. Een bevestiging geeft `success=true` terug. Een weigering wegens onvoldoende leeftijd geeft `success=false`, `denied=true` en de aangepaste foutmelding terug. Een validatiefout geeft `success=false` met het bericht terug. Een gebruikersweigering geeft `success=true` en `redirect_url` met de geconfigureerde redirect-URL terug.

### Databaseschema

Er wordt maar één tabel aangemaakt: `ps_dfagegate_log`. Ze bevat de kolommen `id_log` (auto-increment primaire sleutel), `id_shop`, `reason` (varchar 64), `age` (nullable), `profession` (varchar 128 nullable), `ip_hash` (char 64 voor de SHA-256) en `date_add` (datetime). Twee secundaire indexen optimaliseren de rapportagequery's: `idx_shop_date` op (id_shop, date_add) en `idx_reason` op reason.

## Deïnstallatie

Twee niveaus van deïnstallatie:

### Uitschakelen zonder verwijderen

**Modules → Geïnstalleerde modules → DataFirefly Age Gate → Uitschakelen**. De configuratie blijft behouden, de logtabel ook. U kunt op elk moment opnieuw activeren zonder te herconfigureren.

### Volledig deïnstalleren

**Modules → Geïnstalleerde modules → DataFirefly Age Gate → Deïnstalleren**. Deze actie:

- Verwijdert de tabel `ps_dfagegate_log`
- Verwijdert alle configuratie-items (23 scalaire sleutels + 6 meertalige sleutels)
- Deregistreert de hooks
- Verwijdert de module uit het systeem

**Let op** — De deïnstallatie is **onomkeerbaar**. Wilt u de geschiedenis van de weigeringslogs bewaren (bijvoorbeeld voor een audit), exporteer dan de tabel vooraf.

## Support en updates

Elke licentie omvat:

- **12 maanden updates** — PrestaShop-compatibiliteit, correcties, verbeteringen
- **Technische support per e-mail** — antwoord binnen 24 werkuren, FR/EN
- **30 dagen geld terug**
- **Niet-versleutelde broncode** — u bent vrij de module aan uw specifieke behoeften aan te passen

Neem voor elke technische vraag of bugmelding contact met ons op vanuit uw DataFirefly-account. Vermeld de PrestaShop-versie, de PHP-versie, de moduleversie (zichtbaar bovenaan het configuratiescherm) en, indien mogelijk, het diagnosecommentaar in de head-tag van uw winkel.
