Implementação do endpoint de callback exigido pela Meta Platform Policy para exclusão de dados de usuários.
O FastAd implementa o Data Deletion Callback URL conforme exigido pelaMeta Platform Policy. Este endpoint recebe solicitações de exclusão de dados quando um usuário remove o aplicativo FastAd de sua conta Facebook.
Endpoint URL:
https://fastad.com.br/api/meta/data-deletionPOSTapplication/x-www-form-urlencodedA Meta envia um payload codificado contendo:
signed_request=<signature>.<payload_base64>Onde o payload_base64 decodificado contém:
{
"user_id": "12345678901234567",
"algorithm": "HMAC-SHA256",
"issued_at": 1609459200
}Recepção da requisição
A Meta envia uma requisição POST com o parâmetro signed_request.
Separação da assinatura
O signed_request é dividido em duas partes separadas por ponto:signature e payload.
Verificação HMAC-SHA256
Calculamos HMAC-SHA256(payload, APP_SECRET) e comparamos com a assinatura fornecida para garantir autenticidade.
Segurança crítica
Se a assinatura não coincidir, a requisição é rejeitada com status 400.
Decodificação do payload
O payload Base64 é decodificado e parseado como JSON para extrair o user_id.
Busca no banco de dados
Localizamos todas as contas associadas ao facebookUserId fornecido.
Criação do registro de exclusão
Geramos um código de rastreamento único (UUID) e armazenamos o status da solicitação no banco de dados.
Processamento assíncrono
A exclusão é enfileirada para processamento em segundo plano (não bloqueia a resposta).
Resposta à Meta
Retornamos uma URL de confirmação com o código de rastreamento.
{
"url": "https://fastad.com.br/deletion-status?code=a3b2c1d4-e5f6-7890-abcd-ef1234567890",
"confirmation_code": "a3b2c1d4-e5f6-7890-abcd-ef1234567890"
}A Meta exibe o link de url para o usuário acompanhar o status da exclusão.
{
"error": "Invalid signature"
}{
"error": "User not found"
}Retornado quando o user_id não está associado a nenhuma conta.
{
"error": "Internal server error"
}Quando uma solicitação válida é processada, os seguintes dados são removidos:
Dados pessoais
Nome, e-mail, senha hash, avatar URL
Tokens de autenticação
Facebook Access Token, Refresh Token, ID do usuário no Facebook
Conexões com plataformas
Tokens de Meta Ads Manager e Google Ads (revogados e removidos)
Histórico de campanhas
Todos os anúncios criados através do FastAd
Configurações de conta
Preferências, notificações, planos de assinatura
Apenas registros de faturamento e notas fiscais são mantidos pelo prazo legal mínimo (5 anos), conforme exigido pela legislação tributária brasileira. Esses dados são anonimizados (não contêm tokens ou senhas) e não permitem acesso às plataformas de anúncios.
Exemplo simplificado da implementação do endpoint:
app/api/meta/data-deletion/route.jsimport crypto from 'crypto';
import { prisma } from '@/lib/prisma';
import { v4 as uuidv4 } from 'uuid';
export async function POST(request) {
try {
const formData = await request.formData();
const signedRequest = formData.get('signed_request');
if (!signedRequest) {
return Response.json(
{ error: 'Missing signed_request' },
{ status: 400 }
);
}
// Separar assinatura e payload
const [encodedSignature, encodedPayload] = signedRequest.split('.');
// Verificar assinatura HMAC-SHA256
const expectedSignature = crypto
.createHmac('sha256', process.env.META_APP_SECRET)
.update(encodedPayload)
.digest('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
if (encodedSignature !== expectedSignature) {
return Response.json(
{ error: 'Invalid signature' },
{ status: 400 }
);
}
// Decodificar payload
const payload = JSON.parse(
Buffer.from(encodedPayload, 'base64').toString('utf8')
);
const facebookUserId = payload.user_id;
// Buscar usuário no banco
const user = await prisma.user.findFirst({
where: { facebookUserId }
});
if (!user) {
return Response.json(
{ error: 'User not found' },
{ status: 404 }
);
}
// Criar registro de exclusão
const confirmationCode = uuidv4();
await prisma.deletionRequest.create({
data: {
userId: user.id,
confirmationCode,
status: 'pending',
source: 'meta_callback'
}
});
// Enfileirar exclusão assíncrona
await queueDeletionJob(user.id);
// Retornar URL de rastreamento
const confirmationUrl =
`https://fastad.com.br/deletion-status?code=${confirmationCode}`;
return Response.json({
url: confirmationUrl,
confirmation_code: confirmationCode
});
} catch (error) {
console.error('Meta callback error:', error);
return Response.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}Para configurar o callback no painel de desenvolvedores do Facebook/Meta:
Acesse developers.facebook.com/apps
Selecione seu aplicativo (FastAd)
Vá em App Settings → Basic
No campo "Data Deletion Request URL", insira: https://fastad.com.br/api/meta/data-deletion
Clique em Save Changes
Para testar o endpoint localmente ou em staging:
# Simular requisição da Meta
curl -X POST https://fastad.com.br/api/meta/data-deletion \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "signed_request=<signature>.<base64_payload>"
# Gerar payload de teste (Node.js)
const crypto = require('crypto');
const payload = JSON.stringify({
user_id: "123456789",
algorithm: "HMAC-SHA256",
issued_at: Math.floor(Date.now() / 1000)
});
const encodedPayload = Buffer.from(payload).toString('base64');
const signature = crypto
.createHmac('sha256', process.env.META_APP_SECRET)
.update(encodedPayload)
.digest('base64')
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
console.log(`${signature}.${encodedPayload}`);O endpoint registra as seguintes métricas:
Número de solicitações recebidas da Meta
Falhas de validação de assinatura (possíveis ataques)
Tempo de processamento médio
Taxa de sucesso/erro
Status das exclusões enfileiradas
Para dúvidas técnicas sobre a implementação do callback ou integração com a Meta API:
E-mail: dev@fastad.com.br
Documentação da API: docs.fastad.com.br