O que são os webhooks do comerciante
Os webhooks do comerciante são notificações HTTP enviadas pela ClearPago ao seu endpoint sempre que um evento relevante ocorre em uma transação. São a principal forma de saber que um pagamento foi confirmado, que um envio foi liquidado ou que uma devolução foi processada.
Você precisa:
- Expor um endpoint
POST público via HTTPS.
- Registrar a URL na plataforma com os eventos desejados.
- Implementar verificação de assinatura e idempotência.
Eventos suportados
| Evento | Quando dispara |
|---|
pix_cash_in | Cash-in atinge PAID ou FAILED. |
pix_cash_out | Cash-out atinge CONFIRMED ou FAILED. |
pix_cash_in_reversal | Refund-in atinge CONFIRMED ou FAILED. |
pix_cash_out_reversal | Cash-out previamente CONFIRMED é REVERSED. |
Registrar um webhook
curl -X POST https://api.clearpago.com.br/webhook \
-H "Authorization: Bearer <seu_api_token>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://seu-sistema.com/webhooks/pix",
"events": [
"pix_cash_in",
"pix_cash_out",
"pix_cash_in_reversal",
"pix_cash_out_reversal"
]
}'
TODO: confirmar o formato exato do corpo do POST /webhook com a spec OpenAPI interna — o exemplo acima é baseado nas convenções da plataforma.
Listar webhooks registrados
curl https://api.clearpago.com.br/webhook \
-H "Authorization: Bearer <seu_api_token>"
Use para verificar se a URL correta está cadastrada antes de trocar de ambiente ou domínio.
Remover um webhook
curl -X DELETE https://api.clearpago.com.br/webhook/{webhook_id} \
-H "Authorization: Bearer <seu_api_token>"
Obtenha o webhook_id da listagem (GET /webhook).
Implementar o endpoint receptor
Estrutura mínima
Seu endpoint deve:
- Aceitar
POST com Content-Type: application/json.
- Ler o corpo bruto (raw body) para validar a assinatura.
- Verificar a
Digital-Signature antes de qualquer lógica.
- Responder
200 (ou 204) em menos de 5 segundos.
- Executar a lógica de negócio de forma assíncrona (fila, worker, etc.) se necessário.
Exemplo de handler (Node.js — estrutura)
app.post('/webhooks/pix', async (req, res) => {
const rawBody = req.rawBody; // buffer bruto, antes do parse JSON
const signature = req.headers['digital-signature'];
// 1. Verificar assinatura
const isValid = verifyEcdsaSignature(publicKey, rawBody, signature);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// 2. Responder 2xx imediatamente
res.status(200).send();
// 3. Processar de forma assíncrona
await queue.push({ body: req.body });
});
Raw body é essencial. A assinatura é calculada sobre o corpo antes do parse JSON. Middlewares que modificam o buffer (ex.: express.json() sem salvar o raw) podem invalidar a verificação.
Idempotência no handler
Armazene uma tabela de eventos processados com chave composta:
| Evento | Chave de idempotência recomendada |
|---|
pix_cash_in | event_type + event.id + event.status |
pix_cash_out | event_type + event.id + event.status |
pix_cash_in_reversal | event_type + event.transaction_id + event.end_to_end_id |
pix_cash_out_reversal | event_type + event.id + event.status |
Para pix_cash_in_reversal, use transaction_id + end_to_end_id do estorno (não apenas event.id, que aponta para o cash-in original) para evitar colisão entre devoluções parciais.
Segurança do endpoint
- Use HTTPS com certificado válido (não autoassinado).
- Não exponha o endpoint na internet sem autenticação por assinatura.
- Registre logs de cada requisição recebida com
X-Correlation-ID e timestamp.
- Retorne
401 ou 400 se a assinatura for inválida; nunca processe sem verificar.
Se o seu endpoint retornar 5xx ou não responder no tempo esperado, a plataforma realiza retentativas com backoff exponencial. Isso reforça a necessidade de handlers idempotentes.
Referências