# UX de verificação de CPF em chatbots e interfaces conversacionais

> Aprenda a projetar fluxos de verificação de CPF em chatbots e interfaces conversacionais, com boas práticas de UX e exemplos de código.

**Publicado:** 26/01/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/ux-de-verificacao-de-cpf-em-chatbots-e-interfaces-conversacionais

---


Para criar uma boa UX de verificação de CPF em chatbots, extraia os dígitos de qualquer formato de texto livre, confirme o número com mascaramento parcial antes de consultar a API e limite as tentativas a três antes de escalar para atendimento humano — esse fluxo reduz abandono e protege a privacidade do usuário.

## Introdução

Chatbots e interfaces conversacionais são cada vez mais utilizados para atendimento ao cliente, vendas e onboarding. No Brasil, onde o CPF é requisito para inúmeras operações, é comum que o chatbot precise solicitar e verificar esse dado durante a conversa.

Coletar um CPF em uma interface conversacional é fundamentalmente diferente de um formulário web. Não há campo de input com máscara, não há validação visual em tempo real e o usuário pode responder de formas imprevisíveis. Projetar bem esse fluxo faz diferença direta na taxa de conclusão do onboarding.

---

## Desafios de coletar CPF em chatbots

### Formatos variados de resposta

O usuário pode responder o CPF de diversas formas:

- `12345678901` (apenas dígitos)
- `123.456.789-01` (formatado)
- `123 456 789 01` (com espaços)
- `meu cpf é 123.456.789-01` (com texto)
- `CPF: 123.456.789-01` (com prefixo)

O chatbot precisa extrair os dígitos de qualquer uma dessas variações.

### Privacidade em canais públicos

Em plataformas como WhatsApp e Telegram, a conversa pode ser vista por terceiros em dispositivos compartilhados. O chatbot deve tratar o CPF com cuidado, mascarando-o em confirmações.

### Fluxo não linear

Diferente de um formulário, o usuário pode mudar de assunto, fazer perguntas ou se confundir no meio do fluxo. O chatbot precisa lidar com interrupções de forma graciosa.

---

## Extração de CPF de texto livre

A primeira função essencial é extrair o CPF de qualquer formato de mensagem.

```javascript
function extrairCPF(mensagem) {
 // Remover tudo exceto digitos, pontos, tracos e espacos
 const limpo = mensagem.replace(/[^\d.\-\s]/g, '');

 // Tentar extrair 11 digitos consecutivos (com ou sem formatacao)
 const padroes = [
 /(\d{3})[.\s]?(\d{3})[.\s]?(\d{3})[-.\s]?(\d{2})/,
 /(\d{11})/
 ];

 for (const padrao of padroes) {
 const match = limpo.match(padrao);
 if (match) {
 const digits = match[0].replace(/\D/g, '');
 if (digits.length === 11) return digits;
 }
 }

 return null;
}

// Testes:
// extrairCPF('12345678901') => '12345678901'
// extrairCPF('123.456.789-01') => '12345678901'
// extrairCPF('meu cpf e 123.456.789-01') => '12345678901'
// extrairCPF('CPF: 123 456 789 01') => '12345678901'
// extrairCPF('ola, tudo bem?') => null
```

---

## Máquina de estados do fluxo conversacional

O fluxo de verificação de CPF no chatbot pode ser modelado como uma máquina de estados finitos.

```javascript
class FluxoCPF {
 constructor(apiKey) {
 this.apiKey = apiKey;
 this.estado = 'AGUARDANDO_CPF';
 this.tentativas = 0;
 this.maxTentativas = 3;
 this.cpfExtraido = null;
 this.dadosCPF = null;
 }

 async processarMensagem(mensagem) {
 switch (this.estado) {
 case 'AGUARDANDO_CPF':
 return this.handleAguardandoCPF(mensagem);

 case 'CONFIRMANDO_CPF':
 return this.handleConfirmandoCPF(mensagem);

 case 'CONCLUIDO':
 return { texto: 'Seu CPF ja foi verificado. Como posso ajudar?', fim: true };

 case 'FALHA':
 return { texto: 'Nao consegui verificar seu CPF. Deseja tentar novamente?', fim: false };

 default:
 return { texto: 'Desculpe, algo deu errado. Vamos comecar de novo.', fim: false };
 }
 }

 async handleAguardandoCPF(mensagem) {
 const cpf = extrairCPF(mensagem);

 if (!cpf) {
 this.tentativas++;
 if (this.tentativas >= this.maxTentativas) {
 this.estado = 'FALHA';
 return {
 texto: 'Nao consegui identificar um CPF na sua mensagem. ' +
 'Por favor, entre em contato com nosso atendimento humano.',
 fim: true
 };
 }
 return {
 texto: 'Nao encontrei um CPF na sua mensagem. ' +
 'Por favor, envie apenas os 11 digitos do seu CPF.',
 fim: false
 };
 }

 if (!validarDigitosCPF(cpf)) {
 return {
 texto: 'O CPF informado parece estar incorreto. ' +
 'Verifique os numeros e envie novamente.',
 fim: false
 };
 }

 this.cpfExtraido = cpf;
 const mascarado = `${cpf.slice(0, 3)}.***.***-${cpf.slice(9)}`;

 this.estado = 'CONFIRMANDO_CPF';
 return {
 texto: `Identifiquei o CPF ${mascarado}. Esta correto? Responda "sim" ou "nao".`,
 fim: false
 };
 }

 async handleConfirmandoCPF(mensagem) {
 const resposta = mensagem.toLowerCase().trim();

 if (resposta === 'nao' || resposta === 'não' || resposta === 'n') {
 this.estado = 'AGUARDANDO_CPF';
 this.cpfExtraido = null;
 this.tentativas = 0;
 return {
 texto: 'Sem problema. Por favor, envie o CPF correto.',
 fim: false
 };
 }

 if (resposta === 'sim' || resposta === 's' || resposta === 'yes') {
 return this.consultarAPI();
 }

 return {
 texto: 'Nao entendi. O CPF esta correto? Responda "sim" ou "nao".',
 fim: false
 };
 }

 async consultarAPI() {
 const controller = new AbortController();
 const timeoutId = setTimeout(() => controller.abort(), 10000);

 try {
 const res = await fetch(`https://api.cpfhub.io/cpf/${this.cpfExtraido}`, {
 headers: {
 'x-api-key': this.apiKey,
 'Accept': 'application/json'
 },
 signal: controller.signal
 });
 clearTimeout(timeoutId);
 const json = await res.json();

 if (json.success) {
 this.dadosCPF = json.data;
 this.estado = 'CONCLUIDO';
 const primeiroNome = json.data.name.split(' ')[0];
 return {
 texto: `CPF verificado com sucesso! Ola, ${primeiroNome}. Como posso ajudar?`,
 dados: json.data,
 fim: true
 };
 } else {
 this.estado = 'AGUARDANDO_CPF';
 return {
 texto: 'O CPF informado nao foi encontrado na base. ' +
 'Verifique os numeros e envie novamente.',
 fim: false
 };
 }
 } catch (err) {
 clearTimeout(timeoutId);
 this.estado = 'AGUARDANDO_CPF';
 return {
 texto: 'Estou com dificuldade para verificar seu CPF no momento. ' +
 'Pode tentar novamente em alguns instantes?',
 fim: false
 };
 }
 }
}

function validarDigitosCPF(cpf) {
 if (cpf.length !== 11 || /^(\d)\1{10}$/.test(cpf)) return false;
 let soma = 0;
 for (let i = 0; i < 9; i++) soma += parseInt(cpf[i]) * (10 - i);
 let resto = (soma * 10) % 11;
 if (resto === 10) resto = 0;
 if (resto !== parseInt(cpf[9])) return false;
 soma = 0;
 for (let i = 0; i < 10; i++) soma += parseInt(cpf[i]) * (11 - i);
 resto = (soma * 10) % 11;
 if (resto === 10) resto = 0;
 return resto === parseInt(cpf[10]);
}
```

---

## Interface de chat com widget de CPF

Para melhorar a experiência, o chatbot pode exibir um widget dedicado de input de CPF em vez de depender apenas de texto livre.

```html
<div class="chat-container" id="chatContainer">
 <div class="chat-messages" id="chatMessages"></div>

 <div class="chat-input-area" id="inputArea">
 <input type="text" id="chatInput" placeholder="Digite sua mensagem..." />
 <button onclick="enviarMensagem()">Enviar</button>
 </div>

 <div class="cpf-widget" id="cpfWidget" style="display: none;">
 <p>Digite seu CPF:</p>
 <input
 type="text"
 id="cpfWidgetInput"
 inputmode="numeric"
 placeholder="000.000.000-00"
 maxlength="14"
 />
 <button onclick="enviarCPFWidget()">Verificar</button>
 <button class="btn-secondary" onclick="fecharWidget()">Digitar no chat</button>
 </div>
</div>

<style>
 .chat-container {
 max-width: 420px;
 margin: 20px auto;
 border: 1px solid #ddd;
 border-radius: 12px;
 overflow: hidden;
 display: flex;
 flex-direction: column;
 height: 600px;
 }
 .chat-messages {
 flex: 1;
 padding: 16px;
 overflow-y: auto;
 background: #f8f9fa;
 }
 .msg {
 max-width: 80%;
 padding: 10px 14px;
 border-radius: 12px;
 margin-bottom: 8px;
 font-size: 0.95rem;
 line-height: 1.4;
 }
 .msg-bot {
 background: #fff;
 border: 1px solid #e0e0e0;
 align-self: flex-start;
 }
 .msg-user {
 background: #3498db;
 color: #fff;
 margin-left: auto;
 }
 .chat-input-area {
 display: flex;
 padding: 12px;
 border-top: 1px solid #ddd;
 gap: 8px;
 }
 .chat-input-area input {
 flex: 1;
 padding: 10px;
 border: 1px solid #ddd;
 border-radius: 8px;
 outline: none;
 }
 .chat-input-area button {
 padding: 10px 16px;
 background: #3498db;
 color: #fff;
 border: none;
 border-radius: 8px;
 cursor: pointer;
 }
 .cpf-widget {
 padding: 16px;
 background: #eef6ff;
 border-top: 1px solid #b3d4fc;
 text-align: center;
 }
 .cpf-widget input {
 display: block;
 width: 100%;
 padding: 12px;
 font-size: 1.2rem;
 text-align: center;
 letter-spacing: 2px;
 border: 2px solid #3498db;
 border-radius: 8px;
 margin: 8px 0;
 outline: none;
 }
 .cpf-widget button {
 padding: 10px 20px;
 border: none;
 border-radius: 8px;
 cursor: pointer;
 margin: 4px;
 }
 .cpf-widget button:first-of-type {
 background: #3498db;
 color: #fff;
 }
 .btn-secondary {
 background: transparent;
 color: #666;
 text-decoration: underline;
 }
</style>
```

---

## Boas práticas de UX conversacional para CPF

### 1. Solicite o CPF com contexto

Em vez de simplesmente perguntar "Qual é o seu CPF?", explique por que precisa do dado:

- "Para localizar seu pedido, preciso do seu CPF. Pode me informar?"
- "Vou verificar seu cadastro. Qual o CPF do titular?"

### 2. Confirme antes de consultar

Sempre confirme o CPF com o usuário antes de fazer a consulta na API. Exiba o CPF parcialmente mascarado para proteger a privacidade.

### 3. Limite as tentativas

Após 3 tentativas falhas, direcione para atendimento humano. Insistir além disso gera frustração e aumenta o abandono do fluxo.

### 4. Aceite voz em chatbots de voz

Para interfaces de voz (IVR, Alexa, Google Assistant), aceite o CPF dígito por dígito e repita para confirmação: "Entendi 1-2-3-4-5-6-7-8-9-0-1. Está correto?"

### 5. Não armazene no histórico

Em plataformas como WhatsApp Business, o CPF fica visível no histórico de conversas. Oriente o usuário a apagar a mensagem após a verificação ou use input widgets que não ficam no histórico. As [diretrizes de privacidade da ANPD](https://www.gov.br/anpd) recomendam minimizar a exposição de dados pessoais em canais de comunicação.

---

## Integração com WhatsApp Business API

Um exemplo simplificado de webhook para processar mensagens do WhatsApp com verificação de CPF.

```javascript
// webhook-whatsapp.js (Node.js/Express)
const express = require('express');
const app = express();
app.use(express.json());

const sessoes = new Map();

app.post('/webhook', async (req, res) => {
 const { from, body } = req.body.message;

 if (!sessoes.has(from)) {
 sessoes.set(from, new FluxoCPF(process.env.CPFHUB_API_KEY));
 }

 const fluxo = sessoes.get(from);
 const resultado = await fluxo.processarMensagem(body);

 // Enviar resposta via WhatsApp API
 await enviarMensagemWhatsApp(from, resultado.texto);

 if (resultado.fim) {
 // Limpar sessao apos 5 minutos
 setTimeout(() => sessoes.delete(from), 5 * 60 * 1000);
 }

 res.sendStatus(200);
});

async function enviarMensagemWhatsApp(para, texto) {
 const controller = new AbortController();
 const timeoutId = setTimeout(() => controller.abort(), 10000);

 try {
 await fetch('https://graph.facebook.com/v18.0/PHONE_ID/messages', {
 method: 'POST',
 headers: {
 'Authorization': `Bearer ${process.env.WHATSAPP_TOKEN}`,
 'Content-Type': 'application/json'
 },
 body: JSON.stringify({
 messaging_product: 'whatsapp',
 to: para,
 text: { body: texto }
 }),
 signal: controller.signal
 });
 clearTimeout(timeoutId);
 } catch (err) {
 clearTimeout(timeoutId);
 console.error('Erro ao enviar mensagem:', err);
 }
}

app.listen(3000);
```

---

## Métricas para chatbots com verificação de CPF

Monitore as seguintes métricas para avaliar a eficácia do fluxo:

- **Taxa de extração bem-sucedida** — percentual de mensagens em que o CPF foi identificado corretamente na primeira tentativa.
- **Número médio de turnos** — quantas mensagens são trocadas até a verificação ser concluída. O ideal é 3 (pedido + resposta + confirmação).
- **Taxa de fallback para atendimento humano** — quantos usuários não conseguem completar o fluxo e são encaminhados a um atendente.
- **Tempo total do fluxo** — desde a solicitação do CPF até a verificação concluída.

---

## Perguntas frequentes

### Como extrair o CPF de mensagens em formato livre no chatbot?

Use uma função que remove tudo exceto dígitos, pontos, traços e espaços da mensagem, depois tenta casar os 11 dígitos com um padrão regex. Isso cobre formatos com e sem pontuação, com prefixos como "CPF:" e até com texto ao redor. Se a extração falhar após 3 tentativas, escale para atendimento humano.

### Qual o impacto da latência da API na experiência conversacional?

A API CPFHub.io responde em aproximadamente 900ms. Para chatbots, isso é confortável: o bot pode exibir uma mensagem de "aguarde" enquanto a consulta é processada. Configure o timeout do seu servidor para 10 segundos — suficiente para acomodar variações de rede sem travar a sessão do usuário.

### Como lidar com o CPF do usuário em canais públicos como WhatsApp?

Exiba o CPF parcialmente mascarado na confirmação (ex: `123.***.***-01`), nunca repita o número completo em texto. Oriente o usuário a apagar a mensagem após a verificação. Para máxima privacidade, use widgets de input dedicados que não ficam no histórico de chat, quando a plataforma suportar.

### A verificação de CPF em chatbots é compatível com a LGPD?

Sim, desde que você informe ao usuário a finalidade da coleta antes de pedir o CPF, não armazene o dado além do necessário para a operação, e documente a base legal para o tratamento. O consentimento pode ser obtido no início do fluxo conversacional com uma mensagem clara antes de solicitar o número.

### Leia também

- [Como pedir CPF no checkout sem espantar o cliente](https://cpfhub.io/blog/como-pedir-cpf-no-checkout-sem-espantar-o-cliente)
- [UX de verificação de CPF em chatbots e interfaces conversacionais](https://cpfhub.io/blog/ux-de-verificacao-de-cpf-em-chatbots-e-interfaces-conversacionais)
- [Responsividade em formulários de CPF: desktop, tablet e mobile](https://cpfhub.io/blog/responsividade-em-formularios-de-cpf-desktop-tablet-e-mobile)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)

---

## Conclusão

A verificação de CPF em chatbots exige uma abordagem diferente da web tradicional. A extração de CPF de texto livre, a confirmação com mascaramento, o limite de tentativas e a escalação para atendimento humano são elementos essenciais para uma boa experiência conversacional — e para manter as taxas de conclusão do fluxo em níveis saudáveis.

A API da [**CPFHub.io**](https://www.cpfhub.io/) se encaixa diretamente nesse fluxo: responde em ~900ms, retorna nome e data de nascimento do titular e não bloqueia ao atingir o limite do plano — cobra apenas R$0,15 por consulta extra. Comece com 50 consultas gratuitas por mês, sem cartão de crédito, em [cpfhub.io](https://www.cpfhub.io/).

