Pular para o conteúdo principal

Consulta cadastral de CPF e de CNPJ

Sete módulos consultam a fonte cadastral a partir do documento já validado: cpf_status (situação na Receita e óbito), cpf_contacts (telefones e e-mails), cpf_addresses, cpf_companies (empresas no nome do titular), cnpj_registration, cnpj_realtime (cadastro em tempo real, com CNAE, porte e quadro societário) e cnpj_shareholdings (o QSA detalhado, com percentual de cada sócio). Todos exigem Documento, Face Match e Liveness no mesmo flow, e a razão é a de sempre: o CPF ou CNPJ consultado vem do documento apresentado por quem está vivo na frente da câmera, nunca de um número digitado. Sem esse portão, a plataforma viraria uma ferramenta de consulta cadastral de terceiros.
Aqui o data é o dossiê da fonte, e não um objeto desenhado por nós. Tiramos exatamente três campos, que são de conta e não do titular (pacoteUsado, saldo e consultaID), e o resto passa como a fonte mandou. Isso é decisão de produto, não descuido: remapear campo de fonte externa cria um contrato nosso que envelhece calado quando a fonte muda. A consequência para você é direta: o conjunto de chaves varia por pacote e por consulta, e pode ganhar campo sem release nosso. Os exemplos abaixo são a forma observada, não uma lista fechada. Leia por chave, com valor ausente tratado como ausente, e nunca escreva um parser estrito sobre estes quatro blocos.
Duas armadilhas de leitura, e as duas já custaram integração alheia. A primeira: status não é a situação cadastral do titular, é o indicador de sucesso da chamada à fonte (1 quer dizer “a consulta deu certo”). A situação cadastral é situacao, e ela vem como texto no CPF ("Regular", "Titular Falecido") e como objeto no CNPJ ({ "id": 2, "nome": "Ativa", … }). A segunda: as datas do dossiê vêm no formato brasileiro DD/MM/AAAA, e não em ISO, com uma exceção que é justamente onde você não espera (veja data_entrada logo abaixo). A chave data se comporta de dois jeitos diferentes, e vale saber qual é qual. Nos quatro tiers de CPF a chave sempre existe e vem null quando não houve enriquecimento (fonte fora, documento não encontrado, ou o portão de identidade não liberou). Nos três tiers de CNPJ a chave é omitida quando não há nem dossiê nem screening de sócios. Um parser que assume “data sempre presente” erra no CNPJ; um que assume “data ausente significa nada consta” erra nos dois.
Manutenção programada da fonte oficial. Quando um órgão anuncia uma parada programada de um serviço que estes módulos consultam, a página de status mostra a janela prevista antes de ela começar, com o horário, e tira a janela do ar sozinha quando ela termina. Durante a janela, as consultas que dependem daquela fonte seguem o caminho de fonte fora do ar mostrado acima. Consulta cadastral fora, aprovação segura. Quando a consulta cadastral de um flow não responde na análise e uma checagem da decisão depende do dado dela, a verificação que seria aprovada vai para revisão humana com decision_reason: "registration_source_unavailable". Recusa e bloqueio não mudam. Para o titular o código é manual_review, e reprocessar a verificação no painel refaz só a consulta que faltou. A consulta é refeita sozinha. Quando a fonte não responde, a consulta cadastral é refeita sozinha por tempo limitado depois da decisão, sem nova ação sua nem do titular. Se a fonte voltar nesse tempo, chega um webhook novo da mesma verificação, com revision, trazendo o dado no check e sem cobrança a mais. Se não voltar, o check segue pending com gov_unavailable, e o reprocesso pelo painel continua disponível. Nos tiers de CNPJ o dossiê vem aninhado em company, e ao lado dele pode viajar partner_screening, que é o screening do quadro societário descrito na próxima seção. Os três tiers entregam conjuntos bem diferentes: cnpj_registration é o cadastro básico pela base pública mensal da Receita, com o mês de referência da base em reference_month (a última base mensal carregada por inteiro: enquanto a atualização do mês seguinte roda, ou se ela parar no meio, um cadastro pode já vir da base seguinte, nunca de uma anterior) e a opção pelo Simples Nacional e pelo MEI (sem CNAE, sem porte e sem sócios; empresa aberta depois do retrato do mês sai pendente, nunca inexistente), cnpj_realtime é o mais completo (acrescenta natureza jurídica, CNAE, porte, Simples Nacional, regimes tributários e o QSA) e cnpj_shareholdings é o mais magro de todos, porque o produto dele é uma coisa só: o percentual de cada sócio.
O mesmo campo do sócio muda de tipo entre dois tiers. qualificacao_socio é um objeto { "id": 49, "descricao": "Sócio-Administrador" } em cnpj_realtime e cnpj_partners, e uma string crua em cnpj_shareholdings. E data_entrada vem em ISO ("2015-06-01") no primeiro caso e no formato brasileiro ("14/11/2018") no segundo. Um parser único sobre “o sócio” quebra quando você ligar o segundo tier. Isso é a fonte falando, não nós: os dois pacotes são produtos diferentes dela.
Quadro societário grande é o caso em que o corpo do webhook estoura o teto. Quando o corpo passa de 256 KB, a primeira coisa que podamos é justamente company.socios, e o corte é declarado: o par truncated mais truncated_fields no topo diz exatamente o que saiu, como explicado em Webhooks. A decisão nunca é podada, e o detalhe completo continua no painel. Em sandbox nada é consultado e o dossiê vem pronto, escolhido pelo sufixo do documento: 03 devolve a situação suspensa ou inapta e 99 o documento inexistente. Só no sandbox o dossiê carrega a chave "mock": true, que produção nunca emite: se você ramificar por ela, o código quebra na virada de ambiente.