# Como usar validação de CPF para segmentar clientes por perfil de risco

> Aprenda a usar validação de CPF via API para criar perfis de risco de clientes em e-commerce e tomar decisões antifraude inteligentes.

**Publicado:** 04/04/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-usar-validacao-de-cpf-para-segmentar-clientes-por-perfil-de-risco

---


Para segmentar clientes por perfil de risco usando CPF, consulte a API de validação no momento do cadastro ou da compra, cruzando nome, data de nascimento e histórico comportamental interno. A combinação desses dados permite classificar cada cliente em níveis de confiança (verde, amarelo, laranja, vermelho) e aplicar políticas diferenciadas de checkout e limite de crédito sem prejudicar clientes legítimos.

No e-commerce, nem todos os clientes representam o mesmo nível de risco. Um cliente recorrente que compra há anos e nunca contestou um pedido é fundamentalmente diferente de uma conta nova que faz uma compra de alto valor na primeira interação. Tratar todos da mesma forma — aplicando o mesmo nível de verificação a todos — resulta em excesso de fricção para bons clientes e segurança insuficiente para os suspeitos.

A segmentação por perfil de risco resolve esse dilema. Usando o CPF como chave, combinado com dados da API da [**CPFHub.io**](https://www.cpfhub.io/), é possível construir um score dinâmico que adapta o nível de verificação ao histórico e ao contexto de cada transação.

---

## Os pilares da segmentação de risco

### Dados de identidade

Os dados retornados pela API da [**CPFHub.io**](https://www.cpfhub.io/) — nome completo, data de nascimento e gênero — formam a base da verificação de identidade. A correspondência entre o nome informado pelo cliente e o nome cadastrado no CPF é o primeiro filtro de confiança.

### Histórico comportamental

O comportamento passado do cliente na plataforma é o preditor mais forte de risco futuro. Frequência de compras, valores, método de pagamento, taxa de devolução e histórico de disputas compõem um perfil comportamental rico.

### Dados contextuais

Cada transação traz informações contextuais: dispositivo utilizado, localização geográfica, horário da compra, endereço de entrega. Esses dados, cruzados com o perfil do CPF, revelam anomalias.

---

## Níveis de risco

O sistema opera com quatro níveis de risco, cada um com políticas específicas.

### Nível verde — confiável

Clientes com CPF verificado, histórico longo na plataforma, sem disputas, padrão de compra consistente. Políticas: checkout simplificado, limites de crédito elevados, prioridade na entrega.

### Nível amarelo — atenção

Clientes com CPF verificado mas pouco histórico, ou com histórico misto (algumas devoluções, compras irregulares). Políticas: checkout padrão, limites de crédito moderados, monitoramento de transações.

### Nível laranja — alerta

Clientes com inconsistências nos dados, histórico recente de disputas, ou padrões atípicos de compra. Políticas: verificação adicional em compras acima de um limite, restrição em métodos de pagamento, revisão manual para pedidos de alto valor.

### Nível vermelho — alto risco

Clientes com CPF não verificado ou com múltiplas inconsistências, histórico de chargebacks ou proximidade com CPFs banidos. Políticas: checkout restrito (apenas métodos pré-pagos), limites baixos, revisão manual obrigatória.

---

## Implementação em Python

O exemplo a seguir demonstra um motor de segmentação de risco baseado em CPF.

```python
import requests
import re
from datetime import datetime, timedelta
from typing import Optional
from dataclasses import dataclass, field
import json

CPFHUB_API_URL = "https://api.cpfhub.io/cpf"
CPFHUB_API_KEY = "SUA_CHAVE_DE_API"
REQUEST_TIMEOUT = 10 # segundos

@dataclass
class PerfilRisco:
 cpf: str
 nome: str
 nivel: str # VERDE, AMARELO, LARANJA, VERMELHO
 score: float # 0 a 100
 fatores_positivos: list = field(default_factory=list)
 fatores_negativos: list = field(default_factory=list)
 politicas: dict = field(default_factory=dict)
 calculado_em: str = ""

# Simulação de histórico interno
historicos = {
 "12345678909": {
 "total_compras": 47,
 "total_gasto": 23500.00,
 "membro_desde": "2022-03-15",
 "disputas": 0,
 "chargebacks": 0,
 "devolucoes": 2,
 "ultima_compra": "2026-04-01",
 "metodo_pagamento_principal": "CARTAO_CREDITO",
 "enderecos_distintos": 2,
 "dispositivos_distintos": 3,
 },
 "98765432100": {
 "total_compras": 1,
 "total_gasto": 3499.00,
 "membro_desde": "2026-04-03",
 "disputas": 0,
 "chargebacks": 0,
 "devolucoes": 0,
 "ultima_compra": "2026-04-03",
 "metodo_pagamento_principal": "PIX",
 "enderecos_distintos": 1,
 "dispositivos_distintos": 1,
 },
}

def consultar_cpf(cpf: str) -> Optional[dict]:
 """Consulta CPF na API CPFHub.io."""
 cpf_limpo = re.sub(r"\D", "", cpf)

 try:
 response = requests.get(
 f"{CPFHUB_API_URL}/{cpf_limpo}",
 headers={
 "x-api-key": CPFHUB_API_KEY,
 "Accept": "application/json",
 },
 timeout=REQUEST_TIMEOUT,
 )
 response.raise_for_status()
 dados = response.json()

 if dados.get("success"):
 return dados["data"]
 return None

 except requests.exceptions.Timeout:
 raise Exception("Timeout na consulta de CPF")
 except requests.exceptions.HTTPError as e:
 status = e.response.status_code
 if status == 404:
 return None
 if status == 401:
 raise Exception("API key inválida")
 raise Exception(f"Erro HTTP {status}")
 except requests.exceptions.RequestException:
 raise Exception("Erro de conexão")

def calcular_score_identidade(dados_cpf: dict, nome_informado: str) -> dict:
 """Calcula o score de identidade baseado nos dados da API."""

 score = 0
 fatores_pos = []
 fatores_neg = []

 # CPF encontrado na API
 if dados_cpf:
 score += 30
 fatores_pos.append("CPF válido e encontrado na base (+30)")

 # Correspondência de nome
 import unicodedata
 nome_api = unicodedata.normalize("NFKD", dados_cpf.get("name", ""))
 nome_api = nome_api.encode("ASCII", "ignore").decode("ASCII").upper()
 nome_info = unicodedata.normalize("NFKD", nome_informado)
 nome_info = nome_info.encode("ASCII", "ignore").decode("ASCII").upper()

 partes_api = nome_api.split()
 partes_info = nome_info.split()

 if partes_api and partes_info:
 if partes_api[0] == partes_info[0]:
 score += 10
 fatores_pos.append("Primeiro nome corresponde ao CPF (+10)")
 else:
 score -= 20
 fatores_neg.append("Primeiro nome difere do CPF (-20)")

 if partes_api[-1] == partes_info[-1]:
 score += 10
 fatores_pos.append("Último nome corresponde ao CPF (+10)")
 else:
 score -= 10
 fatores_neg.append("Último nome difere do CPF (-10)")

 # Idade
 ano_nasc = dados_cpf.get("year", 0)
 if ano_nasc:
 idade = datetime.now().year - ano_nasc
 if 25 <= idade <= 60:
 score += 5
 fatores_pos.append(f"Faixa etária comum ({idade} anos) (+5)")
 elif idade < 18:
 score -= 30
 fatores_neg.append(f"Menor de idade ({idade} anos) (-30)")
 else:
 score -= 40
 fatores_neg.append("CPF não encontrado na base (-40)")

 return {
 "score": score,
 "fatores_positivos": fatores_pos,
 "fatores_negativos": fatores_neg,
 }

def calcular_score_comportamental(historico: dict) -> dict:
 """Calcula o score baseado no histórico na plataforma."""

 score = 0
 fatores_pos = []
 fatores_neg = []

 if not historico:
 fatores_neg.append("Sem histórico na plataforma (0)")
 return {
 "score": score,
 "fatores_positivos": fatores_pos,
 "fatores_negativos": fatores_neg,
 }

 # Antiguidade da conta
 membro_desde = datetime.fromisoformat(historico["membro_desde"])
 dias_membro = (datetime.now() - membro_desde).days

 if dias_membro > 365:
 score += 20
 fatores_pos.append(f"Cliente há mais de 1 ano ({dias_membro} dias) (+20)")
 elif dias_membro > 180:
 score += 10
 fatores_pos.append(f"Cliente há mais de 6 meses (+10)")
 elif dias_membro < 7:
 score -= 10
 fatores_neg.append(f"Conta criada há menos de 7 dias (-10)")

 # Volume de compras
 total_compras = historico.get("total_compras", 0)
 if total_compras >= 20:
 score += 15
 fatores_pos.append(f"Cliente frequente ({total_compras} compras) (+15)")
 elif total_compras >= 5:
 score += 8
 fatores_pos.append(f"Cliente ativo ({total_compras} compras) (+8)")

 # Disputas e chargebacks
 disputas = historico.get("disputas", 0)
 chargebacks = historico.get("chargebacks", 0)

 if chargebacks > 0:
 score -= chargebacks * 25
 fatores_neg.append(f"{chargebacks} chargeback(s) (-{chargebacks * 25})")

 if disputas > 0 and total_compras > 0:
 taxa_disputa = disputas / total_compras
 if taxa_disputa > 0.1:
 score -= 20
 fatores_neg.append(f"Taxa de disputa alta ({taxa_disputa:.0%}) (-20)")
 elif taxa_disputa > 0.05:
 score -= 10
 fatores_neg.append(f"Taxa de disputa moderada ({taxa_disputa:.0%}) (-10)")
 elif disputas == 0 and total_compras >= 5:
 score += 10
 fatores_pos.append("Zero disputas com 5+ compras (+10)")

 # Devoluções
 devolucoes = historico.get("devolucoes", 0)
 if devolucoes > 0 and total_compras > 0:
 taxa_devolucao = devolucoes / total_compras
 if taxa_devolucao > 0.2:
 score -= 10
 fatores_neg.append(f"Taxa de devolução alta ({taxa_devolucao:.0%}) (-10)")

 # Endereços e dispositivos
 enderecos = historico.get("enderecos_distintos", 1)
 if enderecos > 5:
 score -= 10
 fatores_neg.append(f"Muitos endereços distintos ({enderecos}) (-10)")

 return {
 "score": score,
 "fatores_positivos": fatores_pos,
 "fatores_negativos": fatores_neg,
 }

def classificar_risco(score_total: float) -> dict:
 """Classifica o nível de risco e define políticas."""

 if score_total >= 70:
 return {
 "nivel": "VERDE",
 "descricao": "Cliente confiável",
 "politicas": {
 "checkout": "SIMPLIFICADO",
 "limiteCredito": 5000,
 "revisaoManual": False,
 "metodosPagamento": ["CARTAO", "PIX", "BOLETO", "CREDITO_LOJA"],
 "prioridadeEntrega": True,
 },
 }
 elif score_total >= 40:
 return {
 "nivel": "AMARELO",
 "descricao": "Atenção moderada",
 "politicas": {
 "checkout": "PADRAO",
 "limiteCredito": 1000,
 "revisaoManual": False,
 "metodosPagamento": ["CARTAO", "PIX", "BOLETO"],
 "prioridadeEntrega": False,
 },
 }
 elif score_total >= 20:
 return {
 "nivel": "LARANJA",
 "descricao": "Alerta — verificação adicional recomendada",
 "politicas": {
 "checkout": "REFORÇADO",
 "limiteCredito": 200,
 "revisaoManual": True,
 "revisaoAcimaDe": 500,
 "metodosPagamento": ["CARTAO", "PIX"],
 "prioridadeEntrega": False,
 },
 }
 else:
 return {
 "nivel": "VERMELHO",
 "descricao": "Alto risco — restrições aplicadas",
 "politicas": {
 "checkout": "RESTRITO",
 "limiteCredito": 0,
 "revisaoManual": True,
 "revisaoAcimaDe": 100,
 "metodosPagamento": ["PIX"],
 "prioridadeEntrega": False,
 },
 }

def segmentar_cliente(
 cpf: str,
 nome_informado: str,
 dados_transacao: dict = None,
) -> dict:
 """Segmenta um cliente por perfil de risco."""

 cpf_limpo = re.sub(r"\D", "", cpf)

 # Consulta CPF na API
 dados_cpf = None
 try:
 dados_cpf = consultar_cpf(cpf_limpo)
 except Exception as e:
 return {
 "erro": f"Falha na consulta de CPF: {str(e)}",
 "nivel_default": "LARANJA",
 }

 # Score de identidade
 identidade = calcular_score_identidade(dados_cpf, nome_informado)

 # Score comportamental
 historico = historicos.get(cpf_limpo, None)
 comportamento = calcular_score_comportamental(historico)

 # Score contextual (baseado na transação atual)
 score_contextual = 0
 fatores_ctx_pos = []
 fatores_ctx_neg = []

 if dados_transacao:
 valor = dados_transacao.get("valor", 0)

 # Valor muito acima da média
 if historico:
 media = historico.get("total_gasto", 0) / max(
 historico.get("total_compras", 1), 1
 )
 if valor > media * 3 and media > 0:
 score_contextual -= 15
 fatores_ctx_neg.append(
 f"Valor ({valor:.2f}) muito acima da média ({media:.2f}) (-15)"
 )
 elif valor > 1000:
 score_contextual -= 10
 fatores_ctx_neg.append(
 f"Primeira compra com valor alto (R$ {valor:.2f}) (-10)"
 )

 # Score total (normalizado para 0-100)
 score_bruto = (
 identidade["score"]
 + comportamento["score"]
 + score_contextual
 )
 score_total = max(0, min(100, score_bruto + 50)) # Centraliza em 50

 # Classificação
 classificacao = classificar_risco(score_total)

 # Monta perfil completo
 perfil = PerfilRisco(
 cpf=cpf_limpo[:3] + ".***.***-" + cpf_limpo[-2:],
 nome=dados_cpf.get("name", nome_informado) if dados_cpf else nome_informado,
 nivel=classificacao["nivel"],
 score=score_total,
 fatores_positivos=(
 identidade["fatores_positivos"]
 + comportamento["fatores_positivos"]
 + fatores_ctx_pos
 ),
 fatores_negativos=(
 identidade["fatores_negativos"]
 + comportamento["fatores_negativos"]
 + fatores_ctx_neg
 ),
 politicas=classificacao["politicas"],
 calculado_em=datetime.now().isoformat(),
 )

 return {
 "perfil": {
 "cpf": perfil.cpf,
 "nome": perfil.nome,
 "nivel": perfil.nivel,
 "descricao": classificacao["descricao"],
 "score": perfil.score,
 },
 "analise": {
 "fatoresPositivos": perfil.fatores_positivos,
 "fatoresNegativos": perfil.fatores_negativos,
 },
 "politicas": perfil.politicas,
 "calculadoEm": perfil.calculado_em,
 }

# Exemplo de uso
if __name__ == "__main__":
 # Cliente antigo e confiável
 print("--- Cliente Confiável ---")
 r1 = segmentar_cliente(
 cpf="123.456.789-09",
 nome_informado="João da Silva",
 dados_transacao={"valor": 350.00},
 )
 print(json.dumps(r1, indent=2, ensure_ascii=False))

 # Cliente novo com compra alta
 print("\n--- Cliente Novo ---")
 r2 = segmentar_cliente(
 cpf="987.654.321-00",
 nome_informado="Pedro Santos",
 dados_transacao={"valor": 3499.00},
 )
 print(json.dumps(r2, indent=2, ensure_ascii=False))
```

---

## Aplicação das políticas por nível

Cada nível de risco aciona políticas específicas que equilibram segurança e experiência do usuário.

### Checkout diferenciado

Clientes verdes passam por um checkout simplificado, com menos etapas e menos verificações. Clientes vermelhos enfrentam um checkout mais rigoroso, com verificação adicional de identidade e restrição de métodos de pagamento.

### Limites dinâmicos

Limites de crédito, valores máximos por pedido e quantidade máxima de itens variam conforme o nível de risco. Isso permite que clientes confiáveis operem com liberdade enquanto clientes de alto risco são automaticamente limitados.

### Revisão manual seletiva

Em vez de revisar manualmente todos os pedidos acima de um valor fixo, a revisão manual é acionada apenas para clientes com nível de risco laranja ou vermelho. Isso reduz drasticamente o volume de revisões sem comprometer a segurança.

---

## Evolução dinâmica do perfil

O perfil de risco não é estático. Ele evolui conforme o comportamento do cliente muda ao longo do tempo.

Um cliente novo começa naturalmente com score mais baixo (amarelo ou laranja) devido à falta de histórico. À medida que realiza compras sem problemas, acumula fatores positivos e migra para níveis mais favoráveis. Por outro lado, um cliente que começa como verde pode migrar para amarelo ou laranja após uma disputa ou chargeback.

Essa evolução dinâmica garante que o sistema se adapta continuamente à realidade, sem intervenção manual.

---

## Métricas de eficácia

Para avaliar se a segmentação está funcionando, monitore as métricas por nível de risco.

A **taxa de fraude por nível** deve mostrar que clientes verdes têm taxa de fraude significativamente menor que vermelhos. Se não houver diferença, o modelo precisa ser recalibrado. A **taxa de falso positivo** por nível indica quantos clientes legítimos estão sendo classificados incorretamente como alto risco. A **taxa de conversão por nível** revela o impacto das políticas restritivas nas vendas — o objetivo é que clientes verdes tenham alta conversão enquanto vermelhos têm conversão menor mas com fraude controlada.

A [FEBRABAN](https://portal.febraban.org.br) recomenda que sistemas antifraude no varejo digital revisem seus modelos de scoring ao menos trimestralmente, ajustando pesos conforme a sazonalidade e os padrões de fraude mais recentes.

---

## Perguntas frequentes

### Quais dados da API de CPF são usados na segmentação por perfil de risco?

A API retorna nome completo, data de nascimento e gênero. Na segmentação, o dado mais relevante é o nome: a correspondência entre o nome informado no cadastro e o nome no CPF é o primeiro filtro de confiança. A data de nascimento serve para detectar inconsistências de idade (ex: menor de 18 anos em compras que exigem maioridade).

### Como o sistema distingue um cliente novo legítimo de um fraudador?

Clientes novos sem histórico recebem score neutro e são classificados como amarelo por padrão. O que eleva o alerta para laranja ou vermelho são inconsistências combinadas: nome diferente do CPF, valor de compra muito acima da média do produto, endereço de entrega em cidade diferente do IP e método de pagamento de alto risco (ex: cartão pré-pago). Nenhum fator isolado define o nível — é a combinação que importa.

### Com que frequência devo recalcular o perfil de risco de cada cliente?

O score deve ser recalculado a cada transação, pois o contexto muda (valor, horário, dispositivo). O histórico comportamental pode ser atualizado diariamente em batch. Perfis com chargeback ou disputa aberta devem ser reclassificados imediatamente, sem aguardar o ciclo de atualização.

### A CPFHub.io bloqueia consultas quando o limite do plano é atingido?

Não. A API nunca bloqueia. Quando o limite mensal do plano é atingido, cada consulta adicional é cobrada a R$0,15 — o serviço continua operando normalmente. Isso é especialmente importante em modelos de segmentação em tempo real, onde uma consulta bloqueada pode forçar uma decisão sem dados de identidade.

### Leia também

- [Golpe do CPF clonado em compras online: como detectar e prevenir](https://cpfhub.io/blog/golpe-cpf-clonado-compras-online-detectar-prevenir)
- [KYC no Brasil: quais setores são obrigados a validar CPF por lei](https://cpfhub.io/blog/kyc-no-brasil-quais-setores-sao-obrigados-a-validar-cpf-por-lei)
- [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)
- [Onboarding digital em fintechs: como validar CPF em menos de 30 segundos](https://cpfhub.io/blog/onboarding-digital-em-fintechs-como-validar-cpf-em-menos-de-30-segundos)

---

## Conclusão

A segmentação de clientes por perfil de risco baseada em CPF é uma estratégia que equilibra segurança e experiência do usuário de forma inteligente. Em vez de aplicar políticas uniformes que frustram clientes bons e ainda assim deixam passar fraudadores, o sistema adapta a verificação ao nível de confiança de cada cliente — com base em dados reais de identidade e comportamento.

A API da [**CPFHub.io**](https://www.cpfhub.io/) fornece os dados de identidade necessários em ~900ms, sem bloquear o fluxo de compra. Com o plano gratuito (50 consultas/mês, sem cartão), você já consegue prototipar o motor de segmentação completo antes de ir para produção.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) e comece a segmentar com dados reais hoje mesmo.

