Webhooks de Integração

Receba notificações em tempo real quando eventos acontecem no MeNotifica.


O que são Webhooks?

Webhooks são chamadas HTTP automáticas que o MeNotifica envia para uma URL que você configura. Quando um evento acontece (por exemplo, um pagamento é confirmado), enviamos um POST com os dados do evento em JSON para a sua URL.

Isso permite que seu sistema reaja automaticamente: liberar acesso em uma portaria, renovar um plano, confirmar uma matrícula, ou qualquer outra ação.

Fluxo simplificado: Participante paga → Mercado Pago confirma → MeNotifica valida → POST para sua URL → Seu sistema reage.

Eventos Disponíveis

EventoDescriçãoQuando dispara
payment.confirmedPagamento confirmadoQuando o Mercado Pago confirma que o valor foi recebido
payment.refundedEstorno totalQuando o valor total é devolvido ao pagador
payment.partial_refundEstorno parcialQuando parte do valor é devolvida
payment.overduePagamento atrasadoQuando o pagamento passa da data de vencimento
payment.failedPagamento falhouQuando o pagamento é recusado pelo processador
participant.acceptedParticipante aceitouQuando o participante aceita o convite (WhatsApp ou link)
participant.declinedParticipante recusouQuando o participante recusa o convite
case.createdCase criadoQuando um novo case (cobrança) é criado
case.completedCase completadoQuando o case é marcado como completo
case.cancelledCase canceladoQuando o case é cancelado
pingTesteEnviado manualmente pelo botão "Enviar Ping"

Formato do Payload

Todos os webhooks enviam um POST com Content-Type: application/json. O payload segue esta estrutura:

{
  "event": "payment.confirmed",
  "timestamp": "2026-03-26T14:30:00+00:00",
  "webhook_id": "uuid-unico-da-entrega",
  "data": {
    "payment_id": "uuid-do-pagamento",
    "case_id": "uuid-do-case",
    "case_title": "Condomínio Março 2026",
    "case_type": "rateio",
    "participant": {
      "id": "uuid-do-participante",
      "name": "Maria Silva",
      "email": "maria@email.com",
      "phone": "11987654321",
      "external_id": "APT-301"
    },
    "amount_brl": 150.00,
    "reference_month": "2026-03",
    "paid_at": "2026-03-26T14:28:00+00:00",
    "payment_method": "pix"
  }
}

Headers enviados

HeaderDescrição
X-MeNotifica-SignatureAssinatura HMAC-SHA256 do payload (sha256=hex)
X-MeNotifica-EventNome do evento (ex: payment.confirmed)
X-MeNotifica-DeliveryID único desta entrega
User-AgentMeNotifica-Webhook/1.0

Campo external_id

O campo participant.external_id é um identificador livre que você pode configurar ao cadastrar participantes. Use-o para mapear o participante no seu sistema externo: número do apartamento, matrícula, ID de sócio, etc.

Validação de Segurança (HMAC-SHA256)

Cada webhook inclui um header X-MeNotifica-Signature com a assinatura HMAC-SHA256 do corpo da requisição, usando o secret que você recebe ao configurar o webhook.

Sempre valide a assinatura antes de processar o webhook para garantir que veio do MeNotifica.

Python Node.js PHP
import hmac
import hashlib

def verify_webhook(payload_body: bytes, signature_header: str, secret: str) -> bool:
    """Valida a assinatura do webhook MeNotifica."""
    # Header format: "sha256=abc123..."
    expected = hmac.new(
        secret.encode(),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    received = signature_header.removeprefix("sha256=")
    return hmac.compare_digest(expected, received)

# Exemplo com Flask:
@app.route("/webhook", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-MeNotifica-Signature", "")
    if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
        return "Invalid signature", 401

    data = request.json
    event = data["event"]

    if event == "payment.confirmed":
        participant = data["data"]["participant"]
        # Liberar acesso para participant["external_id"]
        liberar_acesso(participant["external_id"])

    return "OK", 200
const crypto = require('crypto');

function verifyWebhook(payloadBody, signatureHeader, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payloadBody)
    .digest('hex');
  const received = signatureHeader.replace('sha256=', '');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(received)
  );
}

// Exemplo com Express:
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-menotifica-signature'] || '';
  if (!verifyWebhook(req.body, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const data = JSON.parse(req.body);
  if (data.event === 'payment.confirmed') {
    const externalId = data.data.participant.external_id;
    // Liberar acesso para externalId
    liberarAcesso(externalId);
  }

  res.status(200).send('OK');
});
<?php
function verifyWebhook(string $payloadBody, string $signatureHeader, string $secret): bool {
    $expected = hash_hmac('sha256', $payloadBody, $secret);
    $received = str_replace('sha256=', '', $signatureHeader);
    return hash_equals($expected, $received);
}

// Exemplo:
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_MENOTIFICA_SIGNATURE'] ?? '';

if (!verifyWebhook($payload, $signature, $webhookSecret)) {
    http_response_code(401);
    exit('Invalid signature');
}

$data = json_decode($payload, true);

if ($data['event'] === 'payment.confirmed') {
    $externalId = $data['data']['participant']['external_id'];
    // Liberar acesso para $externalId
    liberarAcesso($externalId);
}

http_response_code(200);
echo 'OK';

Política de Retry

Se o seu endpoint retornar um erro (status 4xx/5xx) ou não responder em 10 segundos, o MeNotifica faz até 4 tentativas com backoff crescente:

TentativaQuando
1Imediato
2+1 minuto
3+5 minutos
4+30 minutos

Após 4 tentativas falharem, a entrega é marcada como Falhou e aparece no log de entregas na tela de Integrações.

Importante: Seu endpoint deve responder com status 2xx (200, 201, 204) dentro de 10 segundos. Se precisar de mais tempo para processar, retorne 200 imediatamente e processe em background.

Troubleshooting

O ping funciona mas os eventos reais não chegam

Verifique se os eventos desejados estão marcados na configuração. Cada evento precisa ser selecionado individualmente.

Recebo "Invalid signature" no meu servidor

  • Certifique-se de usar o corpo bruto da requisição (bytes), não o JSON parseado
  • Verifique se o secret está correto (copie novamente da tela de Integrações)
  • O header é X-MeNotifica-Signature (com o prefixo sha256=)

As entregas estão falhando com timeout

  • Seu endpoint deve responder em até 10 segundos
  • Se o processamento é demorado, retorne 200 primeiro e processe depois
  • Verifique se o firewall/proxy permite conexões de IPs externos

O webhook parou de funcionar

  • Verifique se o webhook está marcado como Ativo na configuração
  • Se regenerou o secret, atualize-o também no seu servidor
  • Use o botão Enviar Ping para testar a conectividade

Como uso o external_id?

Ao cadastrar participantes em um case, preencha o campo "ID Externo" com o identificador do seu sistema (ex: "APT-301", "MAT-4521"). Este valor é enviado em todos os webhooks relacionados ao participante.


MeNotifica — Documentação de Webhooks v1.0