
Banner bonito, botão de aceitar funcionando, e o registro do aceite mora num cookie no navegador do visitante. Ele limpa o cache e a prova evapora. Numa cobrança da ANPD, aceite sem registro do seu lado é aceite que não existe.
O que resolve é uma tabela sua, no MySQL, gravada no instante em que o visitante clica:
-- troque wp_ pelo prefixo real do wp-config.php
CREATE TABLE wp_consentimento_lgpd (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
visitante_id CHAR(36) NOT NULL,
ip_hash CHAR(64) NOT NULL,
versao_texto VARCHAR(20) NOT NULL,
categorias VARCHAR(120) NOT NULL,
acao ENUM('aceitou','recusou','alterou') NOT NULL,
criado_em DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_visitante (visitante_id),
KEY idx_criado (criado_em)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;add_action('rest_api_init', function () {
register_rest_route('lgpd/v1', '/consentimento', [
'methods' => WP_REST_Server::CREATABLE,
'permission_callback' => '__return_true',
'callback' => function (WP_REST_Request $req) {
global $wpdb;
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
$ok = $wpdb->insert($wpdb->prefix . 'consentimento_lgpd', [
'visitante_id' => sanitize_text_field((string) $req['visitante_id']),
'ip_hash' => hash_hmac('sha256', $ip, wp_salt('auth')),
'versao_texto' => '2026-03',
'categorias' => sanitize_text_field((string) $req['categorias']),
'acao' => 'aceitou',
]);
return ['ok' => (bool) $ok];
},
]);
});A rota é aberta de propósito, então qualquer um enfia linha na tabela: ponha um limite por IP no nginx antes de publicar.
Guardar o IP cru é coletar dado pessoal para provar que você coleta pouco dado pessoal. O hash com sal do próprio site resolve os dois lados: dá para conferir um IP específico depois e a tabela sozinha não entrega ninguém. Só não troque os salts do wp-config, porque o wp_salt('auth') muda junto e os hashes antigos param de bater. E atrás de proxy ou Cloudflare o REMOTE_ADDR é o do proxy, pegue o IP do cabeçalho que ele assina.
A coluna versao_texto é a que salva a pele: você vai reescrever a política de privacidade e, sem ela, o log só diz que a pessoa aceitou alguma coisa. Some uma rotina de expurgo do que passou de cinco anos, com WHERE na data e dump feito antes.
Antes de subir, chame /wp-json/lgpd/v1/consentimento com curl -X POST e confira se a linha chegou. Endpoint de consentimento que falha calado é o pior tipo de bug.
Uma função curta em PHP 8.3 que transforma Camiseta Preta Tamanho GG em camiseta-preta-tamanho-gg, sem depender do locale do servidor.
A classe do comando existe e o bin/magento list ignora ela. Falta o registro no di.xml: aqui vai a classe…
Como traduzir duas mil linhas do pt_BR.csv do Magento 2 lendo com fgetcsv e regravando com fputcsv, sem encostar na…
Produto variável respondendo "Desculpe, este produto não está disponível" mesmo com a variação ativa: limpe os transients do WooCommerce e…
O site responde 503 com "Momentaneamente indisponível para manutenção programada" depois de um update interrompido. Apague o .maintenance e feche…
Troque o intervalo R$ 49,00 – R$ 129,00 do produto variável por A partir de R$ 49,00 com o filtro…