# Verificação de idade no PrestaShop: janela bloqueante para CBD, álcool, vape e profissionais de saúde

> O módulo dfagegate acrescenta à sua loja PrestaShop 8 ou 9 uma janela de verificação de idade bloqueante. Cobre dois mercados distintos: o modo padrão, para produtos com restrição de…

- Página: <https://www.datafirefly.com/pt/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/>
- Idioma: pt
- Atualizado em: 2026-09-28
- Outros idiomas: [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), [nl](https://www.datafirefly.com/nl/documentation/verification-age-prestashop-modal-cbd-alcool-vape-medical/index.md)
- Índice: <https://www.datafirefly.com/pt/documentation/llms.txt>

O módulo **dfagegate** acrescenta à sua loja PrestaShop 8 ou 9 uma janela de verificação de idade **bloqueante**. Cobre dois mercados distintos: o **modo padrão**, para produtos com restrição de idade (CBD, álcool, vape, armaria, isqueiros, produtos para maiores de 18 anos), e o **modo médico**, para dispositivos médicos reservados a profissionais de saúde.

**Compatibilidade**: PrestaShop 1.7.7+, 8.x e 9.0. PHP 7.4 no mínimo, 8.1+ recomendado. Multiloja e multi-idioma (FR/EN/ES/DE pré-preenchidos na instalação).

**Leia primeiro, se vende em Portugal.** Este módulo foi desenhado a partir do quadro legal francês, e vários pontos não se transpõem tal como estão. O modo médico refere-se ao artigo L5122-9 do Código da Saúde Pública francês e ao número RPPS/ADELI, que não existem em Portugal, onde a identificação profissional é a cédula das respetivas Ordens e a publicidade de dispositivos médicos é regulada pelo Decreto-Lei n.º 145/2009, sob supervisão do Infarmed. O exemplo do CBD também não se aplica diretamente: a venda de produtos com canabidiol está fortemente restringida em Portugal e nem todos os formatos são comercializáveis. Antes de configurar, valide o seu catálogo com um advogado: o módulo é uma ferramenta técnica, não um parecer jurídico.

## Instalação

A instalação segue o fluxo normal do PrestaShop. Depois da compra na DataFirefly, recebe um ficheiro ZIP `dfagegate-X.Y.Z.zip`.

### Pelo back-office (recomendado)

1. Inicie sessão no back-office do PrestaShop
2. Vá a **Módulos → Catálogo de módulos**
3. Clique em **Carregar um módulo**, no canto superior direito
4. Selecione o ZIP `dfagegate-X.Y.Z.zip`
5. Terminado o carregamento, clique em **Instalar**

### Por FTP

1. Descomprima o ZIP localmente
2. Envie a pasta `dfagegate/` para `modules/` do seu PrestaShop
3. Vá a **Módulos → Catálogo de módulos**
4. Procure «DataFirefly Age Gate» e clique em **Instalar**

**Importante**: depois da instalação, **o módulo fica desativado por predefinição**. É intencional, para lhe permitir configurar os textos e o modo antes de bloquear a loja. Vá à configuração do módulo e ative o interruptor no separador _Geral_ quando tiver tudo definido.

## Primeira configuração

Aceda à configuração em **Módulos → Módulos instalados → DataFirefly Age Gate → Configurar**.

A configuração está organizada em 6 separadores:

- **Geral**: ativação, modo, tipo de verificação, idade mínima, âmbito de exibição
- **Conteúdo**: textos multi-idioma (título, mensagem, botões, menções legais)
- **Aspeto**: logótipo, cores, desfocagem do fundo
- **Comportamento**: cookie, redirecionamento, exceções
- **Modo médico**: profissões e número profissional (só aparece no modo médico)
- **Registos e RGPD**: registo, estatísticas e diagnóstico

### Separador Geral

É aqui que configura o comportamento principal do módulo.

- **Ativar o módulo**: interruptor Sim/Não, que controla a apresentação global da janela
- **Modo**: _Padrão_ (CBD, álcool, vape, armaria) ou _Médico_ (profissionais de saúde)
- **Tipo de verificação**: _Botão sim/não_, _Data de nascimento_ ou _Declaração de profissão_
- **Idade mínima**: 18 por predefinição, 21 em certos mercados
- **Âmbito de exibição**: toda a loja, categorias selecionadas ou produtos selecionados
- **Testar a janela**: botão que abre a loja no modo de pré-visualização (ver a secção Diagnóstico)

**Que tipo de verificação escolher?** O _botão sim/não_ serve para a maioria dos casos, por ser rápido, de baixo atrito e suficientemente dissuasor. A _data de nascimento_ é mais exigente e recomendável para armaria ou líquidos com nicotina. A _declaração de profissão_ destina-se ao modo médico.

Em Portugal, a idade mínima é 18 anos tanto para as bebidas alcoólicas como para os produtos do tabaco e cigarros eletrónicos, incluindo os líquidos sem nicotina. A venda a menores é proibida e a fiscalização cabe à ASAE. Mantenha o valor em 18, a não ser que venda para outro país com um limiar mais alto.

### Âmbito de exibição: segmentar categorias ou produtos

Desde a versão 1.1.0, a janela já não tem de cobrir toda a loja. O âmbito de exibição configura-se em três modos:

- **Toda a loja**: o comportamento histórico e a predefinição. A janela aparece em todas as páginas do front-office
- **Categorias selecionadas**: a janela aparece nas páginas das categorias escolhidas e nas fichas dos produtos que lhes pertencem. As categorias marcam-se numa árvore com caixas de seleção, com um campo de filtro e um contador de seleção
- **Produtos selecionados**: a janela aparece apenas nas fichas dos produtos escolhidos. A pesquisa faz-se por nome ou por referência, e os produtos selecionados aparecem como etiquetas removíveis

No modo por categorias, a opção **Incluir as subcategorias** está ativa por predefinição. Se marcar a categoria CBD, as subcategorias Óleos, Flores e Resinas ficam cobertas sem as marcar uma a uma. A pertença é resolvida pelos nested sets do PrestaShop, numa única consulta SQL.

**Loja mista?** É o caso de uso típico: uma loja gourmet com uma secção de bebidas espirituosas, ou uma parafarmácia com alguns dispositivos reservados. Segmente a janela para as categorias sensíveis e o resto do catálogo permanece acessível sem fricção.

No modo por produtos, as páginas de listagem (categorias, pesquisa) não são bloqueadas: o visitante pode ver as miniaturas dos produtos em causa, e a janela só aparece ao abrir a ficha. Se quiser proteger uma secção inteira, incluindo as listagens, prefira o modo por categorias.

A decisão de exibição é tomada do lado do servidor, página a página, e reflete-se no comentário de diagnóstico através do valor `scope=all|categories|products`. Uma seleção vazia é recusada na gravação: o módulo não deixa guardar um modo segmentado sem nenhuma categoria ou nenhum produto escolhido.

### Separador Conteúdo

Cada idioma ativo no seu PrestaShop tem o seu bloco de textos. Os valores predefinidos vêm preenchidos em **FR, EN, ES e DE**. Em cada idioma pode configurar:

- **Título**: aparece em destaque no topo da janela
- **Mensagem**: texto explicativo principal, com as quebras de linha preservadas
- **Botão de confirmação**: designação do botão positivo (por predefinição, «Tenho 18 anos ou mais»)
- **Botão de recusa**: designação do botão negativo
- **Menção legal**: texto no fundo da janela
- **Mensagem em caso de recusa**: ecrã apresentado quando o utilizador recusa, antes do redirecionamento

O português não está entre os quatro idiomas pré-preenchidos: escreva todos estes textos antes de ativar o módulo, porque a janela é a primeira coisa que o visitante vê. Para a menção legal do álcool, a formulação corrente em Portugal é «Se for grávida, evite o consumo de álcool. Seja responsável, beba com moderação», e a venda a menores de 18 anos é proibida. No caso do tabaco e dos cigarros eletrónicos, a Lei n.º 37/2007 restringe a publicidade e a promoção: escreva a menção com prudência e faça-a validar.

**HTML**: o conteúdo é limpo na gravação (apenas texto simples). As quebras de linha são convertidas em etiquetas <br> na apresentação, por um filtro `nl2br` automático.

### Separador Aspeto

Personalize o visual da janela para que combine com a sua identidade gráfica:

- **Logótipo**: PNG, JPG, SVG ou WEBP, até 2 MB, apresentado no topo da janela
- **Cor de fundo**: cor do cartão principal (branco por predefinição)
- **Cor primária**: título e botão principal (preto #111111 por predefinição)
- **Cor do texto**: corpo da mensagem
- **Cor da sobreposição**: véu por trás da janela, que aceita os formatos CSS `rgba()` e hexadecimal (por predefinição, `rgba(15,15,20,0.85)`)
- **Desfocagem do fundo**: efeito de desfoque no plano de fundo

### Separador Comportamento

Controla a persistência da escolha e os casos de exclusão.

- **Duração do cookie**: em dias (90 por predefinição). Ponha `0` para um cookie de sessão, eliminado ao fechar o navegador
- **URL de redirecionamento em caso de recusa**: deixe vazio para mostrar apenas a mensagem de recusa, ou indique um URL externo
- **Exceção por IP**: lista de IP (uma por linha) para os quais a janela não aparece. É ideal para si e para a sua equipa durante os testes
- **Exceções por URL**: caminhos parciais excluídos. Vem preenchido com `/legal`, `/contact`, `/cgv`, `/mentions-legales` e `/politique-confidentialite`
- **Exceção para clientes com sessão iniciada**: se ativo, os clientes com sessão iniciada não veem a janela

As exceções por URL vêm com caminhos franceses, que não correspondem à sua loja portuguesa. Substitua-os pelos seus: `/termos-e-condicoes`, `/politica-de-privacidade`, `/contacto`, `/avisos-legais`. Sem isso, as suas páginas legais ficam atrás da janela bloqueante, o que é exatamente o contrário do que se pretende: essas páginas devem estar sempre acessíveis.

### Separador Modo médico

Este separador só se aplica se o **modo** estiver em _Médico_ e o **tipo de verificação** em _Declaração de profissão_.

- **Lista de profissões**: uma por linha. Por predefinição, traz médico, farmacêutico, enfermeiro, fisioterapeuta, dentista, veterinário e outro profissional de saúde. É personalizável conforme o seu público
- **Número profissional obrigatório**: se ativo, aparece um campo na janela. A validação é feita por uma expressão regular que aceita 9 a 11 dígitos. **O número não é guardado**, servindo apenas para a validação do lado do servidor

**Adaptação portuguesa indispensável.** O campo foi pensado para o RPPS e o ADELI franceses. Em Portugal, o equivalente é a cédula profissional emitida pela Ordem respetiva (Ordem dos Médicos, Ordem dos Farmacêuticos, Ordem dos Enfermeiros e outras), cujos formatos não coincidem com a regra de 9 a 11 dígitos: um número de cédula pode ser bem mais curto. Duas opções: desative a obrigatoriedade do número e fique-se pela declaração de honra da profissão, ou peça uma adaptação da expressão regular. Ative o campo tal como está e arrisca-se a bloquear profissionais legítimos.

**Conformidade jurídica.** A referência ao artigo L5122-9 do Código da Saúde Pública é francesa. Em Portugal, a publicidade de dispositivos médicos é regulada pelo Decreto-Lei n.º 145/2009 e pela legislação europeia aplicável, com o Infarmed como autoridade competente, e há dispositivos cuja publicidade é reservada a profissionais. **Este módulo não dispensa uma revisão jurídica do seu catálogo por um advogado.** A declaração de honra materializa a restrição de acesso; não a legitima por si só.

### Separador Registos e RGPD

Registo opcional e informações de conformidade.

- **Registar as recusas**: guarda cada recusa na tabela `ps_dfagegate_log`, com o IP em hash SHA-256 (nunca em claro), a data e o motivo
- **Retenção dos registos**: duração de conservação em dias (365 por predefinição). Ponha `0` para uma conservação ilimitada. As entradas mais antigas do que a duração configurada são purgadas automaticamente na abertura da página de configuração

Este separador mostra também um lembrete de RGPD:

- **Cookie depositado**: `dfagegate_ok`
- **Categoria**: estritamente necessário (conformidade legal de acesso)
- **Dados**: valor «1», duração configurável, SameSite=Lax e Secure em HTTPS

Desde a versão 1.1.0, este separador apresenta também as **estatísticas das recusas**: o total dos últimos 30 dias, a repartição por motivo e as 15 recusas mais recentes. Um botão **Purgar os registos**, com pedido de confirmação, esvazia a tabela num clique, por exemplo depois de uma auditoria.

## Configurar conforme o seu mercado

Seguem algumas configurações típicas, a título de inspiração.

### Loja de bebidas espirituosas ou vinhos

- Modo: **Padrão**
- Tipo de verificação: **Data de nascimento**
- Idade mínima: **18**
- URL de redirecionamento: uma página oficial de informação sobre consumo responsável
- Menção legal: a formulação portuguesa de consumo responsável, com a proibição de venda a menores de 18 anos

### Loja de vape e líquidos com nicotina

- Modo: **Padrão**
- Tipo de verificação: **Data de nascimento** (fortemente recomendado)
- Idade mínima: **18**
- Registar as recusas: **Sim** (útil numa inspeção da ASAE)

### Loja de armaria

- Modo: **Padrão**
- Tipo de verificação: **Data de nascimento** (obrigatório)
- Idade mínima: **18**
- Exceções por URL: acrescente as suas páginas de regulamentação e de licenças
- Registar as recusas: **Sim**

A venda de armas e munições em Portugal está sujeita à Lei n.º 5/2006 e exige licença e, em regra, registo da transação: a janela de idade é uma primeira barreira, não o cumprimento das obrigações de venda. Trate-a como complemento do seu procedimento de verificação, não como substituto.

### Loja gourmet com secção de bebidas espirituosas (loja mista)

- Modo: **Padrão**
- Tipo de verificação: **Botão sim/não**
- Idade mínima: **18**
- Âmbito de exibição: **Categorias selecionadas**, com a categoria das bebidas espirituosas e as suas subcategorias
- Resultado: quem compra azeite ou conservas navega sem fricção, e a janela só aparece na secção com restrição de idade

### Loja de material médico (dispositivos profissionais)

- Modo: **Médico**
- Tipo de verificação: **Declaração de profissão**
- Lista de profissões: adapte-a ao seu catálogo, com as designações portuguesas
- Número profissional obrigatório: ver o aviso acima sobre o formato da cédula
- Exceção para clientes com sessão iniciada: **Sim**, se já valida a profissão no registo

## Como funciona a verificação por data de nascimento

Ao contrário de um simples botão, a verificação por data de nascimento faz o cálculo **do lado do servidor**, e não no navegador. O percurso completo é este:

1. O visitante introduz o dia, o mês e o ano na janela
2. O JavaScript envia esses valores ao controlador AJAX `DfagegateAjaxModuleFrontController`
3. O PHP valida a data com `checkdate()` e calcula depois a idade com `DateTimeImmutable::diff()`
4. Se a idade for inferior ao limiar configurado, o servidor devolve uma resposta JSON com `success=false, denied=true` e a mensagem de erro
5. A janela mostra a mensagem de recusa e redireciona ao fim de 2 segundos
6. Se a idade for igual ou superior, o cookie `dfagegate_ok` é depositado e a janela fecha

**Porquê do lado do servidor?** Um controlo puramente em JavaScript é contornável pelas ferramentas de programador em menos de dez segundos. O cálculo no servidor garante que um utilizador abaixo da idade legal não acede ao site, mesmo com conhecimentos técnicos. É o que sustenta a sua posição numa inspeção.

Note que **a data de nascimento nunca é guardada**: é usada durante o cálculo e esquecida a seguir. Só fica a validação binária (aceite ou recusado), através do cookie.

## Como funciona o modo médico

O modo médico segue uma lógica parecida, mas com campos diferentes:

1. A janela mostra uma lista de profissões (configurável) e, eventualmente, um campo de número profissional
2. Existe uma caixa de **declaração de honra**, de preenchimento obrigatório
3. O controlador AJAX valida que a profissão foi selecionada
4. Se o número profissional for obrigatório, o servidor valida o formato através de uma expressão regular que aceita 9 a 11 dígitos consecutivos
5. Não há qualquer armazenamento: nem a profissão nem o número ficam na base de dados, e o cookie `dfagegate_ok` materializa apenas a passagem bem-sucedida

**Opção de conceção**: a abordagem é de conformidade mínima viável, ou seja, pede-se a declaração, valida-se formalmente, regista-se a recusa se a opção estiver ativa, e não se recolhe qualquer dado pessoal desnecessário. Uma verificação em tempo real contra um registo profissional é um desenvolvimento à parte. Em Portugal, essa verificação passaria pelos serviços das Ordens profissionais, e não por um registo nacional único.

## Multiloja

O módulo é **totalmente compatível com multiloja**. Todas as configurações (modo, tipo de verificação, textos multi-idioma, cores, exceções, âmbito de exibição) ficam guardadas por contexto de loja, através de `id_shop_group` e `id_shop`. Pode assim ter, no mesmo PrestaShop:

- Uma loja de **bebidas PT** em modo padrão com 18 anos e textos em português
- Uma loja de **vape UK** em modo padrão com 18 anos e textos em inglês
- Uma loja de **material médico DE** em modo médico e textos em alemão

Para configurar uma loja específica:

1. No seletor de contexto, no topo do back-office, escolha a loja pretendida
2. Abra a configuração do módulo
3. Altere os valores, que ficam guardados apenas para essa loja

Os **hooks são registados em todas as lojas** no momento da instalação, através de `Shop::getCompleteListOfShopsID()`, o que evita a armadilha clássica do módulo que só funciona na loja atual.

## Compatibilidade com temas personalizados

O módulo usa o hook padrão `displayBeforeBodyClosingTag` para injetar a janela imediatamente antes do fecho da etiqueta body. Este hook deveria ser universal no PrestaShop 1.7.5+.

Infelizmente, **alguns temas personalizados não chamam este hook** no seu layout. Para esse caso, o dfagegate traz um **recurso em JavaScript**:

1. O PHP prepara todo o HTML da janela e passa-o ao JS através de `Media::addJsDef`
2. No `DOMContentLoaded`, o script verifica se o elemento com o ID `dfagegate-modal` existe no DOM
3. Se existir, está tudo bem: o hook funcionou
4. Se não existir, o próprio script injeta a janela com `insertAdjacentHTML('beforeend', ...)`
5. Uma mensagem `console.info` confirma a ativação do recurso

**Resultado prático**: o módulo funciona em qualquer tema PrestaShop 1.7.5+, incluindo temas personalizados incompletos, **sem ter de alterar o layout**. Pode implementá-lo sem coordenação com a agência do tema.

## Diagnóstico e depuração

Uma vez ativo, o dfagegate acrescenta um **comentário HTML na etiqueta head** de cada página do front-office, na forma «dfagegate v1.1.0 enabled=1 scope=all should_display=1».

Esse comentário é o seu primeiro ponto de diagnóstico. Consulte o código-fonte de uma página do front-office (Ctrl+U ou Cmd+U) e procure «dfagegate».

| Comentário | Interpretação |
| --- | --- |
| Nenhum comentário | O hook `displayHeader` não está registado: confirme que o módulo está instalado e ativo |
| `enabled=0` | O interruptor «Ativar o módulo» está em Não, no separador Geral |
| `enabled=1 should_display=0` | Está ativa uma exceção: o seu IP está na lista, o URL atual corresponde a um caminho excluído, tem sessão iniciada com a exceção ativa, ou a página atual está fora do âmbito de exibição segmentado. Verifique o valor `scope=` do comentário |
| `enabled=1 should_display=1` | Está tudo bem do lado do servidor. Se a janela não aparecer, veja a consola do navegador, à procura de uma mensagem do recurso em JS ou de um erro |

### A janela continua a não aparecer

Lista de verificação rápida:

1. O comentário de diagnóstico está presente com `should_display=1`? Se não, corrija a configuração
2. Abra a loja em **navegação privada**. O cookie `dfagegate_ok` pode ter ficado de uma sessão anterior
3. Verifique o seu IP nas exceções do separador _Comportamento_
4. Se o âmbito de exibição estiver em categorias ou produtos selecionados, confirme que a página em que está pertence ao âmbito: o valor `scope=` do comentário indica o modo ativo
5. Abra a consola do navegador (F12) e procure `[dfagegate]`, à procura de mensagens de injeção ou de erro
6. Consulte os registos do PrestaShop em **Parâmetros avançados → Registos**, filtrando por «dfagegate»
7. **Limpe a cache do PrestaShop** depois de cada alteração de configuração, em _Parâmetros avançados → Desempenho → Limpar a cache_

### Testar com o modo de pré-visualização

Desde a versão 1.1.0, já não precisa de apagar o cookie para voltar a ver a janela. O botão **Testar a janela**, no separador _Geral_, abre a loja com o parâmetro `?dfagegate_preview=1` no URL. Nesse modo, a janela aparece mesmo que o cookie `dfagegate_ok` esteja presente, e nenhum cookie é depositado: pode repetir o teste as vezes que quiser, sem tocar na sua sessão de navegação.

Se o âmbito de exibição estiver segmentado, mantenha o parâmetro no URL ao navegar para uma página abrangida: a pré-visualização respeita o âmbito configurado.

### Repor o cookie do lado do navegador

Para voltar a testar a janela sem mudar de IP:

1. Abra as ferramentas de programador (F12)
2. Separador **Application** (Chrome) ou **Storage** (Firefox)
3. Secção **Cookies** → o seu domínio
4. Elimine a linha `dfagegate_ok`
5. Recarregue a página

## Conformidade com o RGPD

O módulo foi concebido para ser conforme ao RGPD por predefinição.

### O cookie `dfagegate_ok`

- **Tipo**: estritamente necessário ao cumprimento de uma obrigação legal de acesso
- **Base legal**: em Portugal, a Lei n.º 41/2004 dispensa de consentimento prévio o armazenamento estritamente necessário à prestação do serviço expressamente pedido pelo utilizador, o que abrange este caso
- **Valor**: binário (`1` significa confirmado)
- **Duração**: configurável (90 dias por predefinição), ou de sessão se puser 0
- **Atributos**: `SameSite=Lax`, `Secure` automático em HTTPS e `Path=/`

**Na prática**: não precisa de acrescentar este cookie à sua faixa de consentimento. Entra na mesma categoria do cookie de sessão do PrestaShop ou do cookie CSRF, ou seja, necessário ao funcionamento legal do site e, por isso, dispensado. Mencione-o na sua política de cookies, na secção dos cookies necessários.

### Os registos de recusa

Se ativar a opção _Registar as recusas_, cada recusa é guardada na tabela `ps_dfagegate_log` com:

- `id_shop`: loja em causa
- `reason`: motivo da recusa (`user_refused` ou `dob_under_age`)
- `age`: idade declarada, quando aplicável
- `profession`: profissão declarada, quando aplicável
- `ip_hash`: **SHA-256 do IP**, nunca o IP em claro
- `date_add`: data e hora

O hash SHA-256 torna o IP **não reversível**, mas permite eliminar duplicados nas tentativas, já que um mesmo IP produz sempre o mesmo hash. Inscreva este tratamento no seu registo de atividades e fixe-lhe uma duração de conservação, sob supervisão da CNPD.

Desde a versão 1.1.0, a retenção é automática: as entradas mais antigas do que a duração configurada no separador _Registos e RGPD_ (365 dias por predefinição) são purgadas na abertura da página de configuração. É uma aplicação direta do princípio de minimização do RGPD, sem tarefa cron nem intervenção manual. As estatísticas apresentadas no back-office baseiam-se nesses dados em hash, sem nunca expor um IP em claro.

### Os dados de verificação

- A **data de nascimento** passa por AJAX para o cálculo, mas **nunca é guardada**
- O **número profissional** é validado no servidor e depois **esquecido**, sem qualquer armazenamento
- Só a **validação binária** é conservada, através do cookie

## Estrutura técnica e integração

Para quem programa e queira ir mais longe ou integrar o módulo num fluxo próprio.

### Hooks utilizados

- `displayHeader`: injeta o comentário de diagnóstico
- `actionFrontControllerSetMedia`: regista o CSS e o JS, e passa ao JS a configuração e o HTML preparado da janela
- `displayBeforeBodyClosingTag`: apresenta a janela do lado do servidor (com recurso em JS se faltar no tema)

### Pontos de entrada AJAX

O controlador AJAX responde no URL `/module/dfagegate/ajax` e aceita duas ações:

- `action=confirm`: com os parâmetros próprios do tipo de verificação (nenhum no sim/não, day/month/year na data de nascimento, profession/rpps no modo médico)
- `action=refuse`: regista a recusa e devolve o URL de redirecionamento

As respostas vêm em JSON. Uma confirmação devolve `success=true`. Uma recusa por idade insuficiente devolve `success=false`, `denied=true` e a mensagem de erro adequada. Um erro de validação devolve `success=false` com a mensagem. Uma recusa do utilizador devolve `success=true` e `redirect_url` com o URL de redirecionamento configurado.

### Esquema da base de dados

É criada uma única tabela, `ps_dfagegate_log`. Contém as colunas `id_log` (chave primária com incremento automático), `id_shop`, `reason` (varchar 64), `age` (anulável), `profession` (varchar 128 anulável), `ip_hash` (char 64, para o SHA-256) e `date_add` (datetime). Dois índices secundários otimizam as consultas de relatório: `idx_shop_date` em (id_shop, date_add) e `idx_reason` em reason.

## Desinstalação

Há dois níveis de desinstalação:

### Desativar sem eliminar

**Módulos → Módulos instalados → DataFirefly Age Gate → Desativar**. A configuração é conservada, e a tabela de registos também. Pode reativar a qualquer momento sem voltar a configurar.

### Desinstalar por completo

**Módulos → Módulos instalados → DataFirefly Age Gate → Desinstalar**. Esta ação:

- Elimina a tabela `ps_dfagegate_log`
- Elimina todas as entradas de configuração (23 chaves simples e 6 chaves multi-idioma)
- Remove o registo dos hooks
- Retira o módulo do sistema

**Atenção**: a desinstalação é **irreversível**. Se quiser conservar o histórico dos registos de recusa, por exemplo para uma auditoria, exporte a tabela antes.

## Suporte e atualizações

Cada licença inclui:

- **12 meses de atualizações**: compatibilidade com o PrestaShop, correções e melhorias
- **Suporte técnico por e-mail**: resposta em 24 horas úteis, em francês e inglês
- **Reembolso em 30 dias**
- **Código-fonte não cifrado**: pode adaptar o módulo às suas necessidades

Para qualquer questão técnica ou comunicação de erro, contacte-nos a partir da sua conta DataFirefly. Indique a versão do PrestaShop, a versão do PHP, a versão do módulo (visível no topo do ecrã de configuração) e, se possível, o comentário de diagnóstico presente na etiqueta head da sua loja.
