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, é 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 — 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.
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 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.
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 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 e comece a segmentar com dados reais 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.



