Com a CPFHub.io, é possível criar um fluxo de onboarding em três passos que reduz de 8–10 campos para apenas 3–4 campos de preenchimento manual: o usuário informa o CPF, a API retorna nome completo, data de nascimento e gênero automaticamente, e o cadastro é concluído com o mínimo de atrito. Isso aumenta a taxa de conclusão e melhora a experiência do usuário em fintechs, e-commerce e plataformas de saúde.
Introdução
O onboarding é o momento mais crítico da jornada do usuário. Se o processo for longo, confuso ou cheio de fricção, a taxa de abandono dispara. No contexto brasileiro, onde a verificação de CPF é requisito para diversos serviços -- fintechs, e-commerce, seguradoras, plataformas de saúde -- o desafio é integrar essa verificação de forma fluida, sem que o usuário sinta que está preenchendo um formulário burocrático.
Arquitetura do fluxo de três passos
O fluxo é dividido em três etapas claras, cada uma com um objetivo específico:
Passo 1 -- Identificação
O usuário informa apenas o CPF. A API retorna nome, data de nascimento e gênero, que são preenchidos automaticamente nos campos seguintes.
Passo 2 -- Confirmação
O usuário confirma os dados retornados e complementa com informações adicionais como e-mail e telefone.
Passo 3 -- Finalização
O usuário define uma senha e aceita os termos de uso. O cadastro é concluído.
Esse fluxo reduz de 8-10 campos para apenas 3-4 campos de preenchimento manual, diminuindo significativamente a fricção.
Indicador de progresso
Um indicador visual de progresso é essencial para que o usuário saiba onde está no fluxo e quanto falta para concluir. Veja a implementação de um stepper simples.
import React from 'react';
const steps = ['Identificação', 'Confirmação', 'Finalização'];
function Stepper({ currentStep }) {
return (
<div style={{ display: 'flex', justifyContent: 'center', gap: 16, marginBottom: 32 }}>
{steps.map((label, index) => {
const isActive = index === currentStep;
const isCompleted = index < currentStep;
return (
<div key={label} style={{ textAlign: 'center' }}>
<div style={{
width: 40,
height: 40,
borderRadius: '50%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
margin: '0 auto 8px',
fontSize: '1rem',
fontWeight: 'bold',
background: isCompleted ? '#2ecc71' : isActive ? '#3498db' : '#ddd',
color: isCompleted || isActive ? '#fff' : '#666'
}}>
{isCompleted ? '\u2713' : index + 1}
</div>
<span style={{
fontSize: '0.85rem',
color: isActive ? '#3498db' : '#666'
}}>
{label}
</span>
</div>
);
})}
</div>
);
}
Passo 1 -- Identificação via CPF
No primeiro passo, o usuário digita apenas o CPF. Ao completar os 11 dígitos, o sistema valida localmente e, se válido, consulta a API automaticamente.
import React, { useState, useRef } from 'react';
function StepIdentificacao({ onNext }) {
const [cpf, setCpf] = useState('');
const [loading, setLoading] = useState(false);
const [erro, setErro] = useState('');
const controllerRef = useRef(null);
function mascararCPF(valor) {
const d = valor.replace(/\D/g, '').slice(0, 11);
let r = '';
for (let i = 0; i < d.length; i++) {
if (i === 3 || i === 6) r += '.';
if (i === 9) r += '-';
r += d[i];
}
return r;
}
function validarCPF(digits) {
if (digits.length !== 11 || /^(\d)\1{10}$/.test(digits)) return false;
let soma = 0;
for (let i = 0; i < 9; i++) soma += parseInt(digits[i]) * (10 - i);
let resto = (soma * 10) % 11;
if (resto === 10) resto = 0;
if (resto !== parseInt(digits[9])) return false;
soma = 0;
for (let i = 0; i < 10; i++) soma += parseInt(digits[i]) * (11 - i);
resto = (soma * 10) % 11;
if (resto === 10) resto = 0;
return resto === parseInt(digits[10]);
}
async function handleChange(e) {
const masked = mascararCPF(e.target.value);
setCpf(masked);
setErro('');
const digits = masked.replace(/\D/g, '');
if (digits.length === 11) {
if (!validarCPF(digits)) {
setErro('CPF invalido. Verifique os digitos.');
return;
}
setLoading(true);
if (controllerRef.current) controllerRef.current.abort();
controllerRef.current = new AbortController();
const timeoutId = setTimeout(() => controllerRef.current.abort(), 10000);
try {
const res = await fetch(`https://api.cpfhub.io/cpf/${digits}`, {
headers: {
'x-api-key': process.env.REACT_APP_CPFHUB_API_KEY,
'Accept': 'application/json'
},
signal: controllerRef.current.signal
});
clearTimeout(timeoutId);
const json = await res.json();
if (json.success) {
onNext({ cpf: digits, ...json.data });
} else {
setErro('CPF nao encontrado. Verifique e tente novamente.');
}
} catch (err) {
clearTimeout(timeoutId);
setErro(
err.name === 'AbortError'
? 'Tempo esgotado. Tente novamente.'
: 'Erro na consulta. Tente novamente.'
);
} finally {
setLoading(false);
}
}
}
return (
<div>
<h2>Qual e o seu CPF?</h2>
<p style={{ color: '#666', marginBottom: 16 }}>
Precisamos do seu CPF para preencher seus dados automaticamente.
</p>
<input
type="text"
inputMode="numeric"
placeholder="000.000.000-00"
value={cpf}
onChange={handleChange}
maxLength={14}
disabled={loading}
style={{
width: '100%', padding: '14px 16px', fontSize: '1.2rem',
border: `2px solid ${erro ? '#e74c3c' : '#ddd'}`,
borderRadius: 8, outline: 'none'
}}
/>
{loading && <p style={{ color: '#3498db', marginTop: 8 }}>Consultando...</p>}
{erro && <p style={{ color: '#e74c3c', marginTop: 8 }}>{erro}</p>}
</div>
);
}
Passo 2 -- Confirmação e complemento
Neste passo, os dados retornados pela API são exibidos pré-preenchidos. O usuário confirma as informações e adiciona e-mail e telefone.
function StepConfirmacao({ dados, onNext, onBack }) {
const [email, setEmail] = useState('');
const [telefone, setTelefone] = useState('');
const [erros, setErros] = useState({});
function handleSubmit(e) {
e.preventDefault();
const newErros = {};
if (!email.includes('@')) newErros.email = 'E-mail invalido.';
if (telefone.replace(/\D/g, '').length < 10) newErros.telefone = 'Telefone invalido.';
if (Object.keys(newErros).length > 0) {
setErros(newErros);
return;
}
onNext({ ...dados, email, telefone });
}
return (
<form onSubmit={handleSubmit}>
<h2>Confirme seus dados</h2>
<div style={{ background: '#f8f9fa', padding: 16, borderRadius: 8, marginBottom: 16 }}>
<p><strong>Nome:</strong> {dados.name}</p>
<p><strong>Data de nascimento:</strong> {dados.birthDate}</p>
<p><strong>Genero:</strong> {dados.gender === 'M' ? 'Masculino' : 'Feminino'}</p>
</div>
<label style={{ display: 'block', marginBottom: 4 }}>E-mail</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="seu@email.com"
style={{ width: '100%', padding: 12, marginBottom: 4, borderRadius: 8, border: '2px solid #ddd' }}
/>
{erros.email && <p style={{ color: '#e74c3c', fontSize: '0.85rem' }}>{erros.email}</p>}
<label style={{ display: 'block', marginBottom: 4, marginTop: 12 }}>Telefone</label>
<input
type="tel"
value={telefone}
onChange={(e) => setTelefone(e.target.value)}
placeholder="(11) 99999-9999"
style={{ width: '100%', padding: 12, marginBottom: 4, borderRadius: 8, border: '2px solid #ddd' }}
/>
{erros.telefone && <p style={{ color: '#e74c3c', fontSize: '0.85rem' }}>{erros.telefone}</p>}
<div style={{ display: 'flex', gap: 12, marginTop: 20 }}>
<button type="button" onClick={onBack} style={{ flex: 1, padding: 12, borderRadius: 8, border: '1px solid #ddd', background: '#fff', cursor: 'pointer' }}>
Voltar
</button>
<button type="submit" style={{ flex: 2, padding: 12, borderRadius: 8, border: 'none', background: '#3498db', color: '#fff', cursor: 'pointer', fontWeight: 'bold' }}>
Continuar
</button>
</div>
</form>
);
}
Passo 3 -- Finalização
No último passo, o usuário define uma senha e aceita os termos. Ao concluir, o cadastro é enviado ao backend.
function StepFinalizacao({ dados, onComplete, onBack }) {
const [senha, setSenha] = useState('');
const [confirmaSenha, setConfirmaSenha] = useState('');
const [aceitaTermos, setAceitaTermos] = useState(false);
const [erro, setErro] = useState('');
function handleSubmit(e) {
e.preventDefault();
if (senha.length < 8) { setErro('A senha deve ter pelo menos 8 caracteres.'); return; }
if (senha !== confirmaSenha) { setErro('As senhas nao coincidem.'); return; }
if (!aceitaTermos) { setErro('Voce precisa aceitar os termos de uso.'); return; }
onComplete({ ...dados, senha });
}
return (
<form onSubmit={handleSubmit}>
<h2>Crie sua conta</h2>
<label style={{ display: 'block', marginBottom: 4 }}>Senha</label>
<input
type="password"
value={senha}
onChange={(e) => { setSenha(e.target.value); setErro(''); }}
placeholder="Minimo 8 caracteres"
style={{ width: '100%', padding: 12, marginBottom: 12, borderRadius: 8, border: '2px solid #ddd' }}
/>
<label style={{ display: 'block', marginBottom: 4 }}>Confirmar senha</label>
<input
type="password"
value={confirmaSenha}
onChange={(e) => { setConfirmaSenha(e.target.value); setErro(''); }}
placeholder="Repita a senha"
style={{ width: '100%', padding: 12, marginBottom: 12, borderRadius: 8, border: '2px solid #ddd' }}
/>
<label style={{ display: 'flex', alignItems: 'center', gap: 8, cursor: 'pointer' }}>
<input type="checkbox" checked={aceitaTermos} onChange={(e) => setAceitaTermos(e.target.checked)} />
Li e aceito os termos de uso e a politica de privacidade.
</label>
{erro && <p style={{ color: '#e74c3c', marginTop: 8 }}>{erro}</p>}
<div style={{ display: 'flex', gap: 12, marginTop: 20 }}>
<button type="button" onClick={onBack} style={{ flex: 1, padding: 12, borderRadius: 8, border: '1px solid #ddd', background: '#fff', cursor: 'pointer' }}>
Voltar
</button>
<button type="submit" style={{ flex: 2, padding: 12, borderRadius: 8, border: 'none', background: '#2ecc71', color: '#fff', cursor: 'pointer', fontWeight: 'bold' }}>
Criar conta
</button>
</div>
</form>
);
}
Orquestrador do fluxo
O componente principal gerencia qual passo está ativo e passa os dados entre os passos.
function OnboardingFlow() {
const [step, setStep] = useState(0);
const [dados, setDados] = useState({});
return (
<div style={{ maxWidth: 480, margin: '40px auto', padding: 24 }}>
<Stepper currentStep={step} />
{step === 0 && (
<StepIdentificacao onNext={(d) => { setDados(d); setStep(1); }} />
)}
{step === 1 && (
<StepConfirmacao
dados={dados}
onNext={(d) => { setDados(d); setStep(2); }}
onBack={() => setStep(0)}
/>
)}
{step === 2 && (
<StepFinalizacao
dados={dados}
onComplete={(d) => { console.log('Cadastro completo:', d); }}
onBack={() => setStep(1)}
/>
)}
</div>
);
}
Métricas de sucesso do onboarding
Para avaliar a eficácia do fluxo, monitore as seguintes métricas:
- Taxa de conclusão -- percentual de usuários que iniciam o passo 1 e completam o passo 3. Alvo: acima de 70%.
- Tempo médio por passo -- tempo que o usuário leva em cada etapa. O passo 1 deve ser o mais rápido (menos de 10 segundos).
- Taxa de abandono por passo -- identifica onde os usuários desistem. Se o abandono é alto no passo 1, pode indicar problemas com a consulta de CPF.
- Taxa de erro de CPF -- percentual de CPFs inválidos inseridos. Se for alto, melhore as orientações visuais.
Dicas para aumentar a conversão
Explique por que precisa do CPF
Muitos usuários hesitam em informar o CPF. Adicione uma mensagem curta explicando o motivo: "Usamos seu CPF apenas para preencher seus dados automaticamente e agilizar o cadastro."
Ofereça alternativa
Sempre ofereça a opção de preencher os dados manualmente, caso o usuário prefira não informar o CPF nesse momento. Isso respeita a autonomia do usuário e evita abandonos.
Garantia de segurança
Inclua selos de segurança e uma nota sobre a LGPD próximos ao campo de CPF. A API da CPFHub.io opera em conformidade com a LGPD, garantindo que os dados do usuário sejam tratados com segurança e apenas para a finalidade declarada.
Perguntas frequentes
O que é necessário para implementar validação de CPF neste contexto?
A validação de CPF exige uma chamada à API com o número do documento e a chave de autenticação. A CPFHub.io retorna o status do CPF, nome do titular e data de nascimento em menos de 200ms, permitindo a verificação em tempo real durante o cadastro ou transação.
A API CPFHub.io funciona para todos os volumes de consulta?
Sim. O plano gratuito oferece 50 consultas por mês sem cartão de crédito — ideal para testes e projetos pequenos. Para volumes maiores, o plano Pro inclui 1.000 consultas mensais por R$149. Se o limite for ultrapassado, a API não bloqueia: cobra R$0,15 por consulta adicional.
Como garantir conformidade com a LGPD ao usar uma API de CPF?
Use o CPF apenas para a finalidade declarada ao titular, armazene apenas o necessário (não guarde o CPF cru se um token bastar), implemente controle de acesso aos logs de consulta e documente a base legal para o tratamento. A ANPD orienta que dados de identificação devem ser tratados com o princípio da necessidade.
Quanto tempo leva para integrar a API CPFHub.io?
A integração básica leva menos de 30 minutos: crie uma conta em cpfhub.io, gere a API key no painel e faça uma chamada GET para https://api.cpfhub.io/cpf/{CPF} com o header x-api-key. A documentação inclui exemplos em Python, Node.js, PHP, Java e outras linguagens.
Conclusão
Um fluxo de onboarding com verificação de CPF em três passos equilibra segurança, praticidade e experiência do usuário. Ao utilizar a API da CPFHub.io, o preenchimento automático de nome, data de nascimento e gênero elimina os campos mais tediosos do formulário — reduzindo o atrito e aumentando a taxa de conclusão.
Com tempo de resposta médio de aproximadamente 900ms, 99,9% de uptime e conformidade com a LGPD, a CPFHub.io é a escolha ideal para integrar verificação de CPF ao seu fluxo de onboarding.
Cadastre-se em cpfhub.io — 50 consultas mensais gratuitas, sem cartão de crédito — e comece hoje mesmo.
CPFHub.io
Pronto para integrar a API?
50 consultas gratuitas para testar agora. Sem cartão de crédito. Acesso imediato à documentação.
Sobre a redação
Redação CPFHub.io
Time editorial especializado em APIs de CPF, identidade digital e compliance no mercado brasileiro. Produzimos guias técnicos, análises regulatórias e tutoriais sobre LGPD e KYC para desenvolvedores e líderes de produto.



