Executando verificação de segurança...
1

Webhook do Mercado Pago no Next.js 16: o guia que a doc nao tem

No post anterior eu mostrei como criar pagamento Pix com Mercado Pago no Next.js. Mas criar pagamento e so metade do trabalho. A outra metade? Saber quando o cliente pagou.

E ai que entram os webhooks. A doc do Mercado Pago cobre webhooks genericamente, mas nao mostra como implementar num Next.js 16 com App Router. Esse guia preenche essa lacuna.

O que vamos construir

  1. Route Handler que recebe notificacoes do Mercado Pago
  2. Verificacao de assinatura HMAC-SHA256 (seguranca)
  3. Processamento do pagamento (consulta de status)
  4. Idempotencia (evitar processar duplicatas)
  5. Setup pra desenvolvimento local com ngrok

O fluxo

Cliente paga Pix → MP processa → POST no seu webhook → Valida assinatura → Consulta status → Atualiza banco

O Mercado Pago envia um POST com o ID do pagamento. Voce precisa consultar a API pra pegar os detalhes. O payload do webhook e minimo (so o ID), entao mesmo se alguem interceptar, nao tem dados sensiveis.

Route Handler basico

// app/api/webhooks/mercadopago/route.ts
import { NextRequest, NextResponse } from "next/server";

export async function POST(request: NextRequest) {
  const body = await request.json();
  const xSignature = request.headers.get("x-signature");
  const xRequestId = request.headers.get("x-request-id");

  if (\!xSignature || \!xRequestId || \!body.data?.id) {
    return NextResponse.json({ received: true });
  }

  // Validar assinatura HMAC (codigo completo no blog)
  const isValid = validateSignature(xSignature, xRequestId, body.data.id);
  if (\!isValid) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (body.type === "payment") {
    handlePaymentNotification(body.data.id).catch(console.error);
  }

  return NextResponse.json({ received: true });
}

As armadilhas que ninguem conta

Timeout de 22 segundos: O MP espera resposta rapida. Retorne 200 imediatamente e processe de forma assincrona. Se nao retornar em 22s, ele reenvia a notificacao a cada 15 minutos.

Retornar 200 mesmo com erro: Se a notificacao e valida mas seu processamento falhou, retorne 200 e trate o erro depois. Caso contrario recebe a mesma notificacao dezenas de vezes.

Idempotencia: O MP pode enviar a mesma notificacao mais de uma vez. Guarde o ID no banco e verifique antes de processar. Sem isso voce vai liberar acesso duplicado, enviar email duplicado, etc.

Comparacao de hash: Muita gente usa === pra comparar hashes. Funciona, mas e vulneravel a timing attacks. Use crypto.timingSafeEqual sempre.

Ambiente teste vs producao: URLs separadas. Se configurou URL de teste com credenciais de producao (ou vice-versa), as notificacoes nao chegam.

Post completo

O tutorial completo com validacao HMAC-SHA256, processamento de todos os status (approved, rejected, cancelled, refunded), idempotencia com banco de dados, e checklist de producao esta no blog: blog.zilvo.com.br/posts/webhook-mercado-pago-nextjs-16

Esse post faz parte de uma serie sobre integracao de pagamentos BR no Next.js 16.

Carregando publicação patrocinada...