Grupo Adrion
Sistemas · 12 min de leitura

CNPJ alfanumérico: FAQ + validador pronto pra 3 linguagens

T-26 dias pro CNPJ alfanumérico entrar em vigor. Regex, função DV completa e CHECK constraint em JS, Python e Postgres. FAQ responde as 5 dúvidas reais do dev.

Sumário do artigo · 9 seções
TL;DR

O CNPJ alfanumérico entra em vigor para novas inscrições em 31/07/2026. As 12 primeiras posições passam a aceitar letras [A-Z] e números [0-9]. Os 2 dígitos verificadores continuam só numéricos. CNPJs existentes não mudam — mas qualquer sistema que valida CNPJ como INT/BIGINT ou com regex numérico vai rejeitar CNPJ novo de cliente, fornecedor ou parceiro a partir de agosto. A adaptação por sistema cabe em 3 horas: 1h de auditoria, 1h de código, 1h de teste. Esse post entrega os snippets prontos.

Faltam 26 dias.

Se você está lendo isso hoje (25 de junho), o marco é 31 de julho de 2026. A partir dessa data, novas inscrições no CNPJ saem com letras nas primeiras 12 posições. O seu sistema que valida CNPJ como INT(14) ou com regex /^\d{14}$/ vai rejeitar qualquer CNPJ novo de cliente, fornecedor ou parceiro.

A boa notícia: atualizar pra CNPJ alfanumérico não é refactor — é trocar 1 regex e 1 função DV. A Receita Federal manteve compatibilidade total com CNPJs numéricos existentes. Quem deixou pra última hora ainda tem cerca de 3 horas de trabalho focado por sistema.

Esse post é pra dev solo, dev líder em PME ou fornecedor de sistema que precisa entregar a correção essa semana. Sem papo introdutório, direto no técnico.

O CNPJ alfanumérico entra em vigor para novas inscrições em 31/07/2026. As 12 primeiras posições passam a aceitar [A-Z0-9]. Os 2 dígitos verificadores continuam só [0-9]. CNPJs existentes não mudam. A adaptação por sistema cabe em 3 horas: 1h de auditoria, 1h de código, 1h de teste.

O que muda exatamente (e o que NÃO muda)

Estrutura do CNPJ:

PosiçãoAntes (hoje)Depois (31/07/26)
1 a 12Só dígitos [0-9]Letras + dígitos [A-Z0-9]
13 e 14 (DV)Só dígitos [0-9]Continua só [0-9]
Total de caracteres1414 (sem alteração)
Máscara XX.XXX.XXX/XXXX-DVSimSim (mantida)

O que NÃO muda:

  • CNPJs existentes (numéricos): permanecem válidos, sem migração
  • Estrutura de 14 caracteres: mantida
  • Máscara de exibição: XX.XXX.XXX/XXXX-DV
  • Dígitos verificadores nas posições 13-14: continuam numéricos
  • Lógica modular do cálculo de DV: mesma base, com conversão ASCII

O que MUDA no cálculo do DV:

Letras precisam ser convertidas pra valor numérico antes do cálculo modular. A fórmula é simples:

valor = código ASCII do caractere - 48

Exemplos concretos:

  • A → ASCII 65 → 65 - 48 = 17
  • B → ASCII 66 → 66 - 48 = 18
  • Z → ASCII 90 → 90 - 48 = 42
  • 0 → ASCII 48 → 48 - 48 = 0
  • 9 → ASCII 57 → 57 - 48 = 9

Dígitos numéricos continuam com valor igual ao dígito. Letras ganham valor a partir de 17. O resto do cálculo modular (mod 11, multiplicadores sequenciais) é idêntico ao CNPJ clássico.

A Receita Federal publicou o algoritmo oficial no Ato Declaratório Executivo Cofis nº 3/2024 — é a fonte canônica, consulte antes de implementar.

Validador em 3 linguagens — copie e cole

JavaScript

/**
 * Valida CNPJ alfanumérico (Instrução Normativa RFB nº 2.229/2024)
 * Aceita com ou sem formatação (pontos, barra, hífen)
 */
function validarCNPJ(cnpj) {
  // Remove formatação
  const raw = cnpj.replace(/[.\-\/]/g, '').toUpperCase();

  // Regex: 12 chars [A-Z0-9] + 2 dígitos
  if (!/^[A-Z0-9]{12}[0-9]{2}$/.test(raw)) return false;

  // Rejeita sequências inválidas (ex: '00000000000000')
  if (/^(.)\1+$/.test(raw)) return false;

  // Converte char pra valor numérico: ASCII - 48
  const toNum = (c) => c.charCodeAt(0) - 48;

  // Calcula dígito verificador
  function calcDV(str, tamanho) {
    const pesos = [];
    let peso = 2;
    for (let i = tamanho - 1; i >= 0; i--) {
      pesos[i] = peso;
      peso = peso === 9 ? 2 : peso + 1;
    }

    let soma = 0;
    for (let i = 0; i < tamanho; i++) {
      soma += toNum(str[i]) * pesos[i];
    }

    const resto = soma % 11;
    return resto < 2 ? 0 : 11 - resto;
  }

  const dv1 = calcDV(raw, 12);
  if (dv1 !== toNum(raw[12])) return false;

  const dv2 = calcDV(raw, 13);
  if (dv2 !== toNum(raw[13])) return false;

  return true;
}

// Testes
console.log(validarCNPJ('11222333000181'));    // true  (CNPJ numérico válido)
console.log(validarCNPJ('11.222.333/0001-81')); // true  (com formatação)
console.log(validarCNPJ('B3QNN1.57/0001-09')); // valida FORMATO alfanumérico — DV real usar exemplo oficial Receita
console.log(validarCNPJ('00000000000000'));     // false (sequência inválida)
console.log(validarCNPJ('11222333000100'));     // false (DV errado)

Python

import re

def validar_cnpj(cnpj: str) -> bool:
    """
    Valida CNPJ alfanumérico (IN RFB nº 2.229/2024).
    Aceita com ou sem formatação.
    """
    # Remove formatação
    raw = re.sub(r'[.\-/]', '', cnpj).upper()

    # Regex: 12 chars [A-Z0-9] + 2 dígitos
    if not re.match(r'^[A-Z0-9]{12}[0-9]{2}$', raw):
        return False

    # Rejeita sequências inválidas
    if len(set(raw)) == 1:
        return False

    def to_num(c: str) -> int:
        """Converte char pra valor: ASCII - 48"""
        return ord(c) - 48

    def calc_dv(s: str, tamanho: int) -> int:
        pesos = []
        peso = 2
        for _ in range(tamanho - 1, -1, -1):
            pesos.insert(0, peso)
            peso = 2 if peso == 9 else peso + 1

        soma = sum(to_num(s[i]) * pesos[i] for i in range(tamanho))
        resto = soma % 11
        return 0 if resto < 2 else 11 - resto

    if calc_dv(raw, 12) != to_num(raw[12]):
        return False

    if calc_dv(raw, 13) != to_num(raw[13]):
        return False

    return True


# Testes
assert validar_cnpj('11222333000181') is True      # numérico válido
assert validar_cnpj('11.222.333/0001-81') is True  # com formatação
assert validar_cnpj('B3QNN1570001-09') is False    # checar DV real
assert validar_cnpj('00000000000000') is False     # sequência inválida
print('Todos os testes passaram')

Postgres — CHECK constraint + tipo de coluna

-- 1. Tipo de coluna correto (migração se necessário)
-- NÃO usar: INT, NUMERIC, BIGINT
-- USAR: VARCHAR(14) ou CHAR(14)

-- Exemplo de migração se o campo era BIGINT:
ALTER TABLE clientes
  ALTER COLUMN cnpj TYPE VARCHAR(14) USING cnpj::TEXT;

-- 2. CHECK constraint que aceita alfanumérico
-- Valida formato (não valida DV — DV no banco é overkill; valide na aplicação)
ALTER TABLE clientes
  ADD CONSTRAINT chk_cnpj_formato
  CHECK (
    cnpj ~ '^[A-Z0-9]{12}[0-9]{2}$'
    AND cnpj NOT SIMILAR TO '(.)\1{13}'  -- rejeita '00000000000000' etc
  );

-- 3. Índice (performance mantida com VARCHAR)
CREATE INDEX IF NOT EXISTS idx_clientes_cnpj ON clientes (cnpj);

-- 4. Se tem máscara armazenada (ex: '11.222.333/0001-81'):
-- Constraint pra formato com máscara
ALTER TABLE clientes
  ADD CONSTRAINT chk_cnpj_mascara
  CHECK (
    cnpj ~ '^[A-Z0-9]{2}\.[A-Z0-9]{3}\.[A-Z0-9]{3}\/[A-Z0-9]{4}-[0-9]{2}$'
  );
-- (Escolha: armazenar com ou sem máscara — defina um padrão e mantenha)

Nota sobre o campo Postgres: a validação do DV deve ficar na camada de aplicação (JS/Python/backend), não no banco. CHECK constraint no banco valida formato — é suficiente pra integridade. DV via função PL/pgSQL é possível mas cria acoplamento desnecessário.

Os 5 lugares que costumam quebrar

Com o validador novo em mãos, vale auditar esses pontos antes de fazer deploy:

1. Campo no banco de dados

Como já mencionado: INT, NUMERIC, BIGINT → migrar pra VARCHAR(14). É o erro mais caro de resolver depois, porque envolve migração com downtime se não for planejada.

2. Regex de validação no frontend

Qualquer input com /^\d{14}$/ ou /^[0-9]{14}$/ vai rejeitar CNPJ alfanumérico silenciosamente. Trocar por /^[A-Z0-9]{12}[0-9]{2}$/ (após strip da máscara).

Máscaras de input tipo 9 (só dígitos) nas posições 1-12 também precisam virar * (qualquer char) ou tratamento específico.

3. Integrações com terceiros

Se o seu sistema manda CNPJ pra uma API de terceiro (ERP, gateway de pagamento, emissor de NF-e), verifique se essa API já aceita alfanumérico. A lista dos principais players BR (SEFAZ, Asaas, eNotas, Bling, Tiny) já publicou roteiro de atualização em 2026 — mas check individual nos documentos de cada fornecedor é mais seguro que assumir.

4. Importação de CSV/planilha

Upload de arquivo com lista de CNPJs costuma ter validação embutida na lógica de importação. Essa validação precisa ser atualizada junto com a do formulário.

5. Logs e exportações

Campo CNPJ em log, relatório, exportação contábil ou XML de NF-e. Se o campo estava formatado como número (sem zeros à esquerda), a migração pode ter quebrado formatação silenciosamente.

Plano de 3 horas por sistema

Esse cronograma assume sistema com arquitetura razoavelmente modular (validação centralizada, não espalhada em 40 arquivos).

Hora 1 — Auditoria

  • Buscar no código onde CNPJ é validado: grep -r "CNPJ\|cnpj\|[0-9]\{14\}" --include="*.js" --include="*.ts" --include="*.py"
  • Listar todos os campos CNPJ no banco de dados (SELECT column_name, data_type FROM information_schema.columns WHERE column_name ILIKE '%cnpj%')
  • Mapear integrações de terceiros que recebem CNPJ como campo

Hora 2 — Código

  • Trocar regex de validação pela função nova (snippets acima)
  • Migrar campo de banco de dados se necessário (script de migração + rollback)
  • Atualizar máscara de input no frontend
  • Atualizar validação de importação CSV

Hora 3 — Teste

  • Teste unitário com CNPJ numérico válido (não deve quebrar)
  • Teste unitário com CNPJ alfanumérico válido (deve aceitar)
  • Teste unitário com CNPJ inválido (deve rejeitar)
  • Teste de integração: cadastrar cliente, emitir documento, exportar relatório
  • Teste no ambiente de homologação SEFAZ se sistema emite NF-e

Para sistemas maiores ou com validação espalhada por várias camadas, o tempo sobe — 8-15 horas é realista. O plano de 3h serve pra sistema com validação centralizada e banco já em VARCHAR.

Por que T-26 dias ainda é tempo suficiente

Esse é o dado que alivia: a Receita Federal manteve CNPJs existentes intactos. Você não vai ver erro em produção no dia 31/07 por causa de CNPJ de cliente antigo. O problema começa quando o primeiro cliente novo chegar após julho com CNPJ alfanumérico — e isso pode ser dias, semanas ou meses depois.

Isso significa: atualizar agora é prudente. Não atualizar gera degradação progressiva, não crash imediato.

A urgência real está em sistemas com emissor de NF-e integrado: erro de schema no XML enviado à SEFAZ com CNPJ alfanumérico de destinatário vai rejeitar a nota. Esse ponto específico é bloqueante pra operação — vale priorizar.

O contexto mais amplo do CNPJ alfanumérico vai além dessa mudança técnica. O post CNPJ alfanumérico em julho 2026: o checklist da PME B2B cobre o lado de gestão: quais sistemas auditar, como perguntar pro fornecedor de SaaS, e o cronograma realista de preparação.

Se quiser entender como essa mudança se encaixa no contexto maior da Reforma Tributária, o post Reforma tributária, CBS/IBS e PME: como preparar seus sistemas agora fecha o quadro. CBS/IBS em agosto é a próxima onda — empresa que passou bem pelo CNPJ alfa está melhor posicionada.

E se você precisa decidir se vale adaptar o sistema atual ou reescrever a validação do zero, o exercício de mapeamento em Antes de pedir orçamento de sistema, mapeie a regra da Joana ajuda a estruturar o escopo antes de conversar com a casa de software.

CTA

Time sem fôlego pra fazer em 26 dias, ou sistema com arquitetura que complica a mudança (validação espalhada, campo INT no banco com volume alto de registros)? Manda “CNPJ alfa” no WhatsApp da Adrion — 15 minutos sem custo, sem compromisso. Em uns 20-25% dos casos a resposta é “você mesmo resolve com o snippet acima” — e isso a gente fala direto.


Lucas Américo dos Reis é fundador do Grupo Adrion. Atua em telecom corporativo e arquitetura de sistemas desde 2008 (GVT, Brasil Telecom, Oi, Claro, Embratel, Vivo). LinkedIn

Perguntas frequentes

O CNPJ alfanumérico vai substituir o CNPJ atual da minha empresa?

Não. Pela Instrução Normativa RFB nº 2.229/2024, empresas já cadastradas mantêm o CNPJ numérico atual sem alteração. A regra alfanumérica vale para novos cadastros a partir de 31/07/2026. O impacto no sistema não é migrar o CNPJ próprio — é garantir que o sistema aceite CNPJ com letras quando um cliente, fornecedor ou parceiro novo chegar com esse formato.

Como calcular o dígito verificador do CNPJ alfanumérico?

O cálculo usa a mesma lógica modular do CNPJ numérico, mas letras precisam ser convertidas antes. A conversão é: valor = código ASCII do caractere menos 48. Exemplo: A (ASCII 65) vira 17, B (ASCII 66) vira 18, Z (ASCII 90) vira 42. Os dígitos 0-9 permanecem eles mesmos (0=48-48=0, 9=57-48=9). O cálculo modular (mod 11) depois é idêntico ao CNPJ clássico. A Receita Federal publicou o algoritmo oficial no Ato Declaratório Executivo Cofis nº 3/2024.

Preciso mudar a coluna do banco de dados pra VARCHAR?

Sim, se o campo CNPJ estiver como INT, NUMERIC ou BIGINT — migrate obrigatório pra VARCHAR(14) ou CHAR(14). Campo numérico simplesmente não consegue armazenar letra. Sistema que armazena como VARCHAR já está preparado no banco; a mudança restante é na validação e nos relatórios. Para sistemas legados com campo numérico, a migração de schema costuma levar entre 2 e 8 horas dependendo do volume de dados e dos índices envolvidos.

O CNPJ alfanumérico tem máscara diferente?

A máscara de exibição segue o mesmo padrão: XX.XXX.XXX/XXXX-DV, com 14 caracteres totais. O que muda é que as posições 1 a 12 podem conter letras maiúsculas [A-Z] além de números. Máscaras de input frontend que usam /\d/ ou [0-9] pra cada posição precisam ser atualizadas pra /[A-Z0-9]/ nas primeiras 12 posições. O separador de formatação (ponto, barra, hífen) não muda.

Sistemas antigos que não atualizarem vão parar de funcionar?

Não param de funcionar — mas vão rejeitar ou truncar CNPJ alfanumérico de clientes novos. O efeito prático: cadastro de nova empresa no sistema falha silenciosamente ou com erro de validação, NF-e emitida pra destinatário com CNPJ alfa retorna erro de schema na SEFAZ, importação de CSV com CNPJ novo quebra o upload. Não é crash total — é degradação progressiva conforme clientes com CNPJ novo aparecem no sistema a partir de agosto/2026.