# Como implementar webhooks para notificações assincronas de consultas de CPF

> Aprenda a implementar webhooks para receber notificações assincronas de consultas de CPF e desacoplar seus fluxos de validação.

**Publicado:** 17/06/2025
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/implementar-webhooks-notificacoes-assincronas-consultas-cpf

---


Para implementar webhooks em consultas de CPF, sua aplicação cria um endpoint HTTP que recebe notificações automáticas quando o resultado de uma consulta fica pronto — sem precisar fazer polling. O fluxo envolve uma fila de mensagens (Redis, RabbitMQ ou SQS), um worker que chama a API CPFHub.io e um mecanismo de assinatura HMAC para garantir autenticidade das notificações.

## Introdução

Em muitos fluxos de negócio, a validação de CPF não precisa ser sincrona. Processos como análise de crédito, onboarding em lote ou verificação de beneficiarios podem se beneficiar de um modelo assincrono, onde a sua aplicação dispara a consulta e recebe o resultado via webhook quando ele estiver pronto.

---

## O que são webhooks

Webhooks são callbacks HTTP que permitem que um serviço envie dados automaticamente para a sua aplicação quando um evento ocorre. Em vez de fazer polling (verificar repetidamente se algo mudou), sua aplicação recebe uma notificação proativa.

* **Polling** -- Sua aplicação pergunta: "Ja tem resultado?" repetidamente.

* **Webhook** -- O serviço avisa: "O resultado esta pronto" enviando uma requisição POST para o seu endpoint.

---

## Arquitetura do sistema

O fluxo assincrono com webhooks funciona da seguinte forma:

1. Sua aplicação recebe um pedido de validação de CPF.
2. Em vez de chamar a API e esperar, enfileira a consulta em uma fila (Redis, RabbitMQ, SQS).
3. Um worker consome a fila, faz a chamada a API da CPFHub.io e armazena o resultado.
4. O worker envia o resultado para o endpoint de webhook da aplicação solicitante.
5. A aplicação processa a notificação e atualiza o status.

---

## Criando o endpoint de webhook (Express)

O primeiro passo e criar um endpoint na sua aplicação para receber as notificações:

```javascript
const express = require('express');
const crypto = require('crypto');
const app = express();

app.use(express.json());

const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

function verificarAssinatura(payload, assinatura) {
 const hash = crypto
 .createHmac('sha256', WEBHOOK_SECRET)
 .update(JSON.stringify(payload))
 .digest('hex');
 return crypto.timingSafeEqual(
 Buffer.from(hash),
 Buffer.from(assinatura)
 );
}

app.post('/webhooks/cpf-resultado', (req, res) => {
 const assinatura = req.headers['x-webhook-signature'];

 if (!assinatura || !verificarAssinatura(req.body, assinatura)) {
 return res.status(401).json({ error: 'Assinatura invalida' });
 }

 const { cpf, resultado, requestId } = req.body;
 console.log(`Resultado recebido para CPF ${cpf}: ${JSON.stringify(resultado)}`);

 // Processar o resultado (atualizar banco, notificar usuario, etc.)
 // processarResultado(cpf, resultado, requestId);

 res.status(200).json({ received: true });
});

app.listen(3000, () => console.log('Webhook listener na porta 3000'));
```

---

## Criando o worker que consulta a API

O worker consome a fila e faz a consulta real:

```python
import requests
import json
import hashlib
import hmac
import os
import redis
import time

CPFHUB_API_KEY = os.environ['CPFHUB_API_KEY']
WEBHOOK_URL = os.environ['WEBHOOK_URL']
WEBHOOK_SECRET = os.environ['WEBHOOK_SECRET']

r = redis.Redis(host='localhost', port=6379, db=0)

def consultar_cpf(cpf):
 url = f'https://api.cpfhub.io/cpf/{cpf}'
 headers = {
 'x-api-key': CPFHUB_API_KEY,
 'Accept': 'application/json'
 }
 response = requests.get(url, headers=headers, timeout=15)
 return response.json()

def enviar_webhook(payload):
 body = json.dumps(payload)
 assinatura = hmac.new(
 WEBHOOK_SECRET.encode(),
 body.encode(),
 hashlib.sha256
 ).hexdigest()

 requests.post(
 WEBHOOK_URL,
 data=body,
 headers={
 'Content-Type': 'application/json',
 'x-webhook-signature': assinatura
 },
 timeout=10
 )

def processar_fila():
 while True:
 item = r.brpop('fila:consulta_cpf', timeout=5)
 if item:
 dados = json.loads(item[1])
 cpf = dados['cpf']
 request_id = dados['requestId']

 resultado = consultar_cpf(cpf)

 enviar_webhook({
 'cpf': cpf,
 'resultado': resultado,
 'requestId': request_id
 })
 time.sleep(0.1)

if __name__ == '__main__':
 processar_fila()
```

---

## Enfileirando consultas

Quando sua aplicação recebe um pedido de validação, ela enfileira em vez de processar diretamente:

```python
import redis
import json
import uuid

r = redis.Redis(host='localhost', port=6379, db=0)

def solicitar_validacao(cpf):
 request_id = str(uuid.uuid4())
 r.lpush('fila:consulta_cpf', json.dumps({
 'cpf': cpf,
 'requestId': request_id
 }))
 return request_id
```

O `requestId` permite rastrear a consulta do inicio ao fim.

---

## Boas práticas para webhooks

### Idempotencia

Sua aplicação pode receber a mesma notificação mais de uma vez. Use o `requestId` para garantir que o processamento ocorra apenas uma vez:

```javascript
const processados = new Set();

app.post('/webhooks/cpf-resultado', (req, res) => {
 const { requestId } = req.body;

 if (processados.has(requestId)) {
 return res.status(200).json({ received: true, duplicate: true });
 }

 processados.add(requestId);
 // processar resultado...
 res.status(200).json({ received: true });
});
```

### Retentativas com backoff exponencial

Se o webhook falhar, implemente retentativas com intervalos crescentes:

* 1a tentativa -- imediata.
* 2a tentativa -- apos 5 segundos.
* 3a tentativa -- apos 30 segundos.
* 4a tentativa -- apos 2 minutos.
* 5a tentativa -- apos 10 minutos.

### Validação de assinatura

Sempre valide a assinatura do webhook para garantir que a notificação vem de uma fonte confiável, conforme mostrado no exemplo acima.

### Resposta rápida

O endpoint de webhook deve responder com status 200 o mais rápido possível. Processe o payload de forma assincrona para evitar timeouts.

---

## Quando usar webhooks vs. consulta sincrona

| Cenário | Abordagem recomendada |
| --- | --- |
| Checkout em tempo real | Sincrona |
| Onboarding interativo | Sincrona |
| Validação em lote | Assincrona (webhook) |
| Análise de crédito em background | Assincrona (webhook) |
| Atualização cadastral periódica | Assincrona (webhook) |

---

## Perguntas frequentes

### O que é necessário para receber notificações via webhook em consultas de CPF?
Você precisa de um endpoint HTTP acessível publicamente que aceite requisições POST, uma fila de mensagens para desacoplar as consultas (Redis ou similar) e um worker que chame a API CPFHub.io. Implemente validação de assinatura HMAC-SHA256 para garantir que apenas notificações legítimas sejam processadas.

### Como garantir que o mesmo webhook não seja processado duas vezes?
Use o campo `requestId` retornado em cada consulta para implementar idempotencia. Armazene os IDs já processados em um Set em memória ou no banco de dados e, ao receber um webhook, verifique se o `requestId` já foi visto antes de executar qualquer ação.

### Qual fila de mensagens é mais indicada para esse padrão?
Depende da sua infraestrutura. Redis com o módulo de filas simples atende bem volumes até alguns milhares de consultas por hora. Para volumes maiores ou garantias de entrega mais robustas, considere RabbitMQ ou AWS SQS. A [OWASP](https://owasp.org) documenta boas práticas de segurança para sistemas de mensageria que processam dados pessoais.

### Quantas tentativas de reenvio devo configurar no worker?
Cinco tentativas com backoff exponencial cobrem a maioria dos cenários de indisponibilidade temporária: imediata, 5s, 30s, 2min e 10min. Após a quinta falha, mova o item para uma dead-letter queue e gere um alerta para investigação manual.

### Leia também

- [Diferença entre validação de CPF e consulta de CPF: quando usar cada uma](https://cpfhub.io/blog/diferenca-entre-validacao-de-cpf-e-consulta-de-cpf-quando-usar-cada-uma)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [SLA de API de CPF: níveis de disponibilidade e o que exigir do seu provedor](https://cpfhub.io/blog/sla-api-cpf-niveis-disponibilidade)
- [Como validar CPF no frontend com React e API REST](https://cpfhub.io/blog/como-validar-cpf-no-frontend-com-react-e-api-rest)

---

## Conclusão

Implementar webhooks para consultas de CPF permite desacoplar seus fluxos, melhorar a experiência do usuário e processar grandes volumes de forma eficiente. Com uma fila de mensagens, um worker dedicado e um endpoint de webhook seguro, você cria uma arquitetura resiliente e escalável.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito.

