PS PrestaShop Iniciante

Eliminação de conta RGPD: guia completo

Instalar, configurar e utilizar a eliminação de conta conforme ao RGPD, com confirmação por e-mail, anonimização que respeita a obrigação contabilística e anulação de subscrição no Mailchimp, Brevo e Mailjet para PrestaShop 8 e 9.

Atualizado Versão do módulo 1.0.2

Visão geral

O módulo Eliminação de Conta RGPD dá aos seus clientes a possibilidade de exercerem o direito ao apagamento (artigo 17.º do RGPD) diretamente a partir da área de cliente, sem qualquer intervenção manual da sua parte. Um pedido desencadeia uma cascata: confirmação por e-mail com token criptográfico, anonimização ou eliminação da conta do lado da loja, anulação automática da subscrição no Mailchimp, no Brevo e no Mailjet, e escrita de uma prova de tratamento num registo de auditoria.

Para quem? Qualquer comerciante em PrestaShop 8 ou 9 que trate dados pessoais de cidadãos europeus e queira evitar a gestão manual dos pedidos de eliminação ao abrigo do RGPD. O módulo é entregue em francês, inglês, espanhol e alemão.

O português não está incluído no pacote. Como a página de eliminação e o e-mail de confirmação são vistos pelo cliente num momento sensível, traduza as cadeias em Internacional > Traduções e crie a pasta mails/pt antes de ativar o bloco na área de cliente.

Instalação

  1. Inicie sessão no back-office do PrestaShop.
  2. Vá a Módulos → Gestor de módulos, clique em Carregar um módulo e coloque o ZIP dfaccountdelete-1.0.2.zip.
  3. O módulo é instalado e ativado automaticamente. Clique em Configurar.

A instalação cria duas tabelas: ps_dfad_log (registo RGPD) e ps_dfad_token (tokens de confirmação por e-mail). Regista o módulo no hook displayCustomerAccount, que acrescenta um bloco «Eliminar a minha conta» na área de cliente.

Se tiver muitos templates personalizados, confirme depois da instalação que o bloco «Eliminar a minha conta» aparece mesmo em A minha conta, do lado da loja. O hook displayCustomerAccount tem de ser suportado pelo seu tema, o que acontece no tema nativo Classic e na maioria dos temas comerciais.

Configuração geral

O ecrã de configuração está dividido em quatro painéis: Parâmetros gerais, Mailchimp, Brevo e Mailjet. Cada painel é gravado de forma independente.

Modo de eliminação

Escolha entre dois modos:

  • Anonimizar (recomendado): os dados pessoais do cliente (nome, apelido, e-mail, telefone, moradas, data de nascimento) são substituídos por valores anónimos. As encomendas ficam intactas, para respeitar a obrigação de conservação dos documentos durante 10 anos, prevista no artigo 123.º do CIRC e no artigo 52.º do CIVA.
  • Eliminar totalmente, se possível: a conta é totalmente apagada se não existir qualquer encomenda. Se existirem encomendas, o módulo passa automaticamente ao modo de anonimização, para não quebrar o histórico legal.

Mesmo em modo «Eliminar totalmente», não pode eliminar uma conta que tenha feito encomendas. É uma obrigação legal portuguesa e europeia: os documentos de suporte da contabilidade têm de ser conservados 10 anos. O módulo trata desta passagem automaticamente e regista no registo RGPD o modo realmente aplicado. O direito ao apagamento do artigo 17.º do RGPD prevê precisamente esta exceção quando o tratamento é necessário para o cumprimento de uma obrigação legal.

Confirmação por e-mail obrigatória

Ativa por predefinição (fortemente recomendada). O cliente tem de clicar numa ligação recebida por e-mail para validar o pedido. Isto impede qualquer eliminação acidental ou provocada por terceiros que tenham acedido a uma sessão aberta.

Validade do token

Em horas. 24 horas por predefinição. Passado esse período, a ligação do e-mail expira e o pedido é automaticamente anulado.

Registos

Ativos por predefinição. O módulo escreve em ps_dfad_log cada pedido apenas com dados pseudonimizados: hash SHA-256 do e-mail, hash SHA-256 do IP, identificador do cliente, modo aplicado, estado, fornecedores contactados, user agent, identificador da loja e data e hora. Não é conservado qualquer dado pessoal em claro.

A tabela ps_dfad_log não é eliminada na desinstalação do módulo. É intencional: constitui a prova do tratamento em caso de fiscalização pela CNPD. Para a eliminar manualmente, execute DROP TABLE ps_dfad_log; depois da desinstalação.

E-mail do administrador notificado

Endereço que receberá uma notificação (apenas o hash do e-mail, nunca o e-mail em claro) a cada eliminação efetiva. Por predefinição, o e-mail da loja.

Configuração dos fornecedores de newsletter

O módulo suporta de origem três plataformas de newsletter. Cada fornecedor está desativado por predefinição. Ative apenas os que utiliza.

Mailchimp

Preencha:

  • Chave API: formato xxxxxxxxxxxx-us21. O sufixo (-us21, -eu1, entre outros) é o datacenter do Mailchimp. O módulo deteta-o automaticamente.
  • List ID (Audience ID): identificador da sua audiência principal. Encontra-o no Mailchimp em Audience → Settings → Audience name and defaults.
  • Eliminação permanente: ativa por predefinição. Usa o endpoint POST /lists/{list_id}/members/{hash}/actions/delete-permanent, que corresponde ao verdadeiro direito ao esquecimento do RGPD: o e-mail é definitivamente eliminado e o Mailchimp recusará qualquer futura subscrição com esse endereço. Se preferir um simples arquivo (permitindo que o endereço se volte a inscrever mais tarde), desative esta opção.

Clique em Testar a ligação para validar a sua configuração. Se estiver tudo correto, verá o nome da sua audiência.

Brevo (ex-Sendinblue)

Preencha:

  • Chave API v3: formato xkeysib-xxxxxx. Encontra-a no Brevo em A minha conta → SMTP e API → Chaves API.
  • List ID (opcional): se estiver preenchido, retira o contacto apenas dessa lista. Se ficar vazio, elimina o contacto por completo (recomendado para o RGPD).

Endpoint utilizado: DELETE /v3/contacts/{email} para eliminação total, ou POST /v3/contacts/lists/{id}/contacts/remove para retirada de uma lista.

Mailjet

O Mailjet usa autenticação Basic com duas chaves. Preencha:

  • API Key
  • API Secret
  • Contact List ID (opcional): se estiver preenchido, anula a subscrição apenas dessa lista. Se ficar vazio, elimina o contacto através do endpoint oficial de RGPD do Mailjet.

O fluxo de eliminação do Mailjet tem duas etapas: procura do identificador do contacto através de GET /v3/REST/contact/{email} e depois DELETE /v4/contacts/{id} no endpoint de RGPD. O módulo trata desta mecânica automaticamente.

Se uma plataforma devolver 404 na eliminação, o módulo considera que é um sucesso (o contacto já não existe, idempotência). Não verá qualquer erro nos registos.

Anonimizar ou eliminar: o que escolher?

O RGPD impõe o direito ao apagamento, mas a legislação fiscal portuguesa impõe a conservação dos documentos contabilísticos durante 10 anos (artigo 123.º do CIRC e artigo 52.º do CIVA). As duas obrigações conciliam-se através da anonimização, que é a abordagem habitualmente seguida.

Modo de anonimização

O módulo substitui em ps_customer:

  • firstnameAnonymized
  • lastnameCustomer
  • emailanon-{id_customer}-{hash}@anonymized.local
  • passwd → hash aleatório (o cliente deixa de poder iniciar sessão)
  • birthday → NULL
  • note, website, ip_registration_newsletter → vazio
  • active → 0, deleted → 1

Nas moradas:

  • As moradas não usadas por encomendas são eliminadas por completo.
  • As moradas usadas por encomendas são anonimizadas (firstname, lastname, address1, postcode, city, phone, entre outros, substituídos por valores neutros) e marcadas com deleted = 1.

Se guarda o NIF do cliente num campo personalizado da morada ou da conta, verifique que também ele é anonimizado: é um dado pessoal e identificador direto. O módulo trata os campos padrão do PrestaShop, não os campos acrescentados por outros módulos.

Modo de eliminação total

Se o cliente não fez qualquer encomenda: eliminação completa das moradas e depois chamada a Customer::delete(). Caso contrário: passagem automática ao modo de anonimização. Não existe opção que permita forçar a eliminação de uma conta com encomendas, o que é intencional por razões legais.

Fluxo completo de um pedido

  1. O cliente vai a A minha conta e clica no bloco «Eliminar a minha conta».
  2. Chega a uma página de confirmação com um painel de aviso, um campo «Palavra-passe» e uma caixa «Compreendo que esta ação é irreversível».
  3. Introduz a palavra-passe e assinala a caixa. O módulo verifica a palavra-passe através da classe PrestaShop/Core/Crypto/Hashing.
  4. Se a confirmação por e-mail estiver ativa, o módulo gera um token aleatório de 32 bytes (random_bytes(32)), converte-o em hexadecimal de 64 caracteres, guarda o respetivo hash SHA-256 em ps_dfad_token e envia um e-mail com o token em claro dentro de um URL.
  5. O cliente recebe o e-mail e clica na ligação. O módulo obtém o token do URL, calcula o seu SHA-256 e verifica que existe na tabela, que não expirou e que ainda não foi consumido.
  6. O token é marcado como consumido (consumed_at = NOW()), para evitar qualquer reutilização.
  7. Em cada fornecedor ativo (Mailchimp, Brevo, Mailjet), o módulo chama a API de eliminação e regista o resultado (código HTTP, mensagem) no registo.
  8. O módulo limpa as tabelas do PrestaShop: ps_emailsubscription, ps_newsletter, ps_cart, ps_cart_product, ps_wishlist, ps_compare, ps_customer_thread, ps_customer_message e ps_guest.
  9. Consoante o modo e a existência de encomendas, a conta é anonimizada ou eliminada.
  10. É inserida uma linha em ps_dfad_log com o estado done, o modo realmente aplicado e a lista dos resultados dos fornecedores.
  11. É enviado um e-mail de notificação ao administrador configurado (apenas o hash do e-mail).
  12. O cliente é desautenticado e reencaminhado para uma página de confirmação.

O RGPD prevê que o pedido seja tratado sem demora injustificada e, no máximo, no prazo de um mês. Aqui o tratamento é imediato assim que o cliente confirma, o que cumpre folgadamente o prazo. Guarde ainda assim o registo, que é a sua prova perante a CNPD.

Registo de tratamento RGPD

O ecrã de configuração mostra os 30 últimos pedidos, com:

  • ID do pedido
  • Hash do e-mail truncado (os 12 primeiros caracteres do SHA-256)
  • Modo aplicado (anonymize / delete)
  • Estado (awaiting_confirm, done)
  • Lista dos fornecedores e o respetivo código de retorno, por exemplo mailchimp:OK(200) | brevo:OK(204) | mailjet:OK(200)
  • Data e hora UTC

A tabela completa contém ainda: hash SHA-256 do IP, user agent truncado a 250 caracteres, identificador da loja e notas internas (existência ou não de encomendas).

Para exportar o registo completo em caso de fiscalização, pode consultar diretamente a base de dados: SELECT * FROM ps_dfad_log ORDER BY created_at DESC;. Nunca aparece qualquer dado em claro neste registo.

Testar antes de colocar em produção

Procedimento recomendado antes de ativar o módulo numa loja de produção:

  1. Teste das ligações aos fornecedores: no back-office do módulo, clique em Testar a ligação em cada plataforma ativa. Deve ver uma mensagem verde com o nome da sua audiência ou conta. Em caso de erro, é apresentada a mensagem HTTP exata devolvida pela API.
  2. Teste do fluxo completo numa conta de teste:
    • Crie uma conta de cliente com um endereço de e-mail real que controle.
    • Inscreva-a na sua newsletter do Mailchimp, do Brevo ou do Mailjet manualmente, ou através do formulário da sua loja.
    • Confirme que aparece mesmo em cada plataforma.
    • Inicie sessão nessa conta do lado da loja e lance o procedimento de eliminação.
    • Confirme através do e-mail recebido.
    • Confirme em ps_customer que a conta ficou anonimizada.
    • Confirme em cada plataforma de newsletter que o e-mail desapareceu.
    • Verifique a entrada em ps_dfad_log.
  3. Teste do caso «cliente com encomenda»: crie uma conta, faça uma encomenda de teste (1 €) e lance depois a eliminação em modo «Eliminar totalmente». Confirme que o módulo passou mesmo à anonimização e que a encomenda está intacta, mas com uma morada anónima.

Estender: acrescentar um novo fornecedor

A arquitetura segue um padrão Strategy. Acrescentar o Sendgrid, o Mailerlite, o HubSpot, o ActiveCampaign ou qualquer outra plataforma exige apenas a criação de uma classe.

Crie classes/Provider/SendgridProvider.php:

class DfAccountDelete_SendgridProvider extends DfAccountDelete_AbstractProvider
{
    public function getKey() { return 'sendgrid'; }

    public function isEnabled()
    {
        return (bool) Configuration::get('DFAD_SG_ENABLED')
            && Configuration::get('DFAD_SG_API_KEY');
    }

    public function deleteSubscriber($email)
    {
        $headers = ['Authorization: Bearer ' . Configuration::get('DFAD_SG_API_KEY')];
        $url = 'https://api.sendgrid.com/v3/marketing/contacts?emails=' . rawurlencode($email);
        $res = $this->http('DELETE', $url, $headers);
        return ['ok' => $res['ok'], 'status' => $res['status'], 'message' => $res['message']];
    }

    public function testConnection()
    {
        $headers = ['Authorization: Bearer ' . Configuration::get('DFAD_SG_API_KEY')];
        $res = $this->http('GET', 'https://api.sendgrid.com/v3/scopes', $headers);
        return ['ok' => $res['ok'], 'status' => $res['status'], 'message' => $res['message']];
    }
}

Referencie a classe em DfAccountDeleteService::getProviders():

public function getProviders()
{
    return [
        new DfAccountDelete_MailchimpProvider(),
        new DfAccountDelete_BrevoProvider(),
        new DfAccountDelete_MailjetProvider(),
        new DfAccountDelete_SendgridProvider(), // novo
    ];
}

E carregue a classe no início de dfaccountdelete.php com um require_once. O resto (painel de configuração no back-office, botão de teste, integração no fluxo de eliminação) deve ser programado de forma semelhante aos fornecedores existentes.

Perguntas frequentes e resolução de problemas

O cliente diz não ter recebido o e-mail de confirmação

Verifique: (1) se a configuração de SMTP do PrestaShop funciona (está a enviar outros e-mails transacionais, como as confirmações de encomenda?); (2) se o e-mail não foi para o spam; (3) se o prazo de expiração já não foi atingido. O cliente pode relançar o procedimento a partir da conta, e o novo token invalida automaticamente os anteriores.

Uma plataforma de newsletter devolve um erro 401

A chave de API é inválida ou expirou. Volte a gerá-la na plataforma em causa e atualize-a na configuração do módulo. Use o botão Testar a ligação para validar de imediato.

Aparece o erro SQL «LIMIT 1 LIMIT 1»

Está numa versão anterior à 1.0.1. Atualize para a última versão: esse erro foi corrigido na 1.0.1.

A conta não parece anonimizada: o nome, o apelido e o e-mail originais continuam visíveis

Está numa versão anterior à 1.0.2. A validação interna do PrestaShop em Validate::isCustomerName() recusava o antigo valor de lastname, que continha o caractere # e algarismos, o que fazia falhar silenciosamente a atualização. Atualize para a 1.0.2: a atualização automática repara também as contas mal anonimizadas nas versões anteriores.

Como eliminar o registo RGPD na desinstalação?

A tabela ps_dfad_log é propositadamente conservada na desinstalação (prova do tratamento). Para a eliminar manualmente depois da desinstalação: DROP TABLE ps_dfad_log; DROP TABLE ps_dfad_token;.

O módulo é compatível com o meu módulo de RGPD existente (gdpr, psgdpr)?

Sim, os dois módulos podem coexistir. O módulo oficial do PrestaShop psgdpr serve sobretudo para a exportação dos dados e a gestão dos consentimentos; o dfaccountdelete serve para a eliminação efetiva das contas, com integração da newsletter. Não entram em conflito.

O cliente pode desistir depois de clicar no botão?

Sim, enquanto não clicar na ligação do e-mail de confirmação. O token expira automaticamente ao fim do período configurado (24 horas por predefinição). Durante essa janela, a conta mantém-se plenamente ativa. Se não fizer nada, o pedido é anulado.

Como acrescentar o bloco de eliminação fora de A minha conta?

Pode criar uma ligação direta para {shop_url}/{lang}/module/dfaccountdelete/delete a partir de qualquer página (rodapé, página de condições gerais, entre outras). Se o visitante não tiver sessão iniciada, é reencaminhado para a página de início de sessão e regressa à página de eliminação depois de se autenticar.

Um bom lugar para essa ligação é a sua política de privacidade, na secção dedicada aos direitos do titular dos dados: dá ao cliente uma via direta e demonstra que o direito é efetivamente exercível.

Versões e registo de alterações

1.0.2, correção crítica

  • Correção: anonymizeCustomer() usava Customer::update(), que passa por Validate::isCustomerName(). Essa validação proíbe algarismos e o caractere # em firstname e lastname, o que fazia falhar silenciosamente a anonimização do registo ps_customer. Substituído por um UPDATE em SQL direto, que contorna a validação.
  • A atualização upgrade-1.0.2.php repara retroativamente as contas tratadas pelas versões anteriores que tinham ficado por anonimizar.

1.0.1, correção

  • Correção: tableExists() usava Db::getValue(), que acrescenta automaticamente LIMIT 1. A consulta SHOW TABLES LIKE 'xxx' LIMIT 1 é SQL inválido em MariaDB. Substituído por executeS().

1.0.0, versão inicial

  • Compatibilidade com PrestaShop 8.0 a 9.x
  • Modo de anonimização e modo de eliminação total
  • Confirmação por e-mail com token SHA-256
  • Integrações com Mailchimp, Brevo e Mailjet
  • Registo de tratamento RGPD
  • Interface e modelos de e-mail em FR, EN, ES e DE
Esta página foi útil?

Ainda com dúvidas? Contacte o suporte