anúncios

terça-feira, 14 de abril de 2026

MUDANÇA NO CNPJ: O que você precisa fazer no seu projeto

A Receita Federal confirmou: a partir de julho de 2026, o CNPJ será alfanumérico (com letras e números). Novo formato: 14 caracteres sendo 12 primeiros alfanuméricos + 2 dígitos verificadores (DV) numéricos.

Isso vai quebrar muitos sistemas. Vamos aos impactos:

1. CNPJ como Integer no banco de dados

Problema: CNPJs novos terão letras (ex: 12AB3456C0001). Tipo INTEGER não suporta letras.

Solução: Migrar coluna para VARCHAR(18) ou CHAR(14), mantenham o tamanho fixo para compatibilidade com sistemas legados.

2. CNPJ como Primary Key

Problema: PKs inteiras não funcionam + índices unique baseados em Integer falharão para novos registros.

Solução:

  • Alterar tipo da PK para VARCHAR(18) ou CHAR(14)
  • Atualizar foreign keys em todas as tabelas relacionadas
  • Regenerar índices unique

3. Validação de DV (Módulo 11)

Problema: Algoritmo atual não reconhece letras.

Solução: Ver algoritmo em pseudocódigo abaixo.

4. Máscaras e formats existentes

Problema: XX.XXX.XXX/0001-XX pode não funcionar com letras.

Solução: Criar máscara flexível que aceite alfanumérico.

5. Integração com APIs e ERPs

Problema: Sistemas legados que recebem CNPJ como número quebrarão.

Solução: Revisar APIs, contratos, e integrações -> tipar como string, não integer.

Cronograma

  • Julho 2026: Primeiros CNPJs alfanuméricos emitidos
  • CNPJs atuais: Permanecem válidos (não precisam migrar)

Ação imediata

  • ✓ Audit no banco: identifique colunas CNPJ com tipo Integer
  • ✓ Planeje migração para VARCHAR/CHAR
  • ✓ Teste o novo algoritmo de validação
  • ✓ Revise integrações externas

Algoritmo de Validação do DV (Módulo 11)

O algoritmo a seguir funciona para CNPJs numéricos (atuais) e CNPJs alfanuméricos (novos).

Tabela de Conversão

Caractere Valor para cálculo
0-9 0-9 (valor numérico)
A 17
B 18
C 19
D 20
E 21
F 22
G 23
H 24
I 25
J 26
K 27
L 28
M 29
N 30
O 31
P 32
Q 33
R 34
S 35
T 36
U 37
V 38
W 39
X 40
Y 41
Z 42

Pseudocódigo

FUNÇÃO obterValorCaractere(caractere):
    SE caractere >= '0' E caractere <= '9':
        RETORNAR inteiro(caractere)
    FIM SE
    
    SE caractere >= 'A' E caractere <= 'Z':
        codigoASCII <- inteiro(caractere)
        RETORNAR codigoASCII - 48
    FIM SE
    
    RETORNAR -1  // Caractere inválido
FIM FUNÇÃO


FUNÇÃO calcularDV(cnpj, posicaoDV):
    // posicaoDV = 1 para primeiro DV, 2 para segundo DV
    
    SE posicaoDV == 1://Primeiros 12 caracteres do CNPJ
        pesos <- [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
        digitos <
    SENÃO://Primeiros 12 caracteres do CNPJ + primeiro DV
        pesos <- [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
        digitos <
    FIM SE
    
    soma <- 0
    PARA i DE 0 ATÉ comprimento(digitos) - 1:
        valor <- obterValorCaractere(digitos[i])
        soma <- soma + (valor * pesos[i])
    FIM PARA
    
    resto <- soma MOD 11
    
    SE resto <= 1:
        DV <- 0
    SENÃO:
        DV <- 11 - resto
    FIM SE
    
    RETORNAR DV
FIM FUNÇÃO


FUNÇÃO validarCNPJ(cnpj):
    // Remove máscara (pontos, barras, hífen)
    cnpjLimpo <- limparMascara(cnpj)
    
    SE comprimento(cnpjLimpo) != 14:
        RETORNAR FALSO
    FIM SE
    
    // Extrai os DVs informados no CNPJ
    dv1Informado <- inteiro(cnpjLimpo[12])
    dv2Informado <- inteiro(cnpjLimpo[13])
    
    // Calcula primeiro DV
    dv1Calculado <- calcularDV(cnpjLimpo, 1)
    
    SE dv1Informado != dv1Calculado:
        RETORNAR FALSO
    FIM SE
    
    // Calcula segundo DV
    dv2Calculado <- calcularDV(cnpjLimpo, 2)
    
    SE dv2Informado != dv2Calculado:
        RETORNAR FALSO
    FIM SE
    
    RETORNAR VERDADEIRO
FIM FUNÇÃO

Exemplo de Implementação em JavaScript

function obterValorCaractere(char) {
    if (char >= '0' && char <= '9') {
        return parseInt(char, 10);
    }
    const codigoASCII = char.charCodeAt(0);
    if (codigoASCII >= 65 && codigoASCII <= 90) {
        return codigoASCII - 48;
    }
    return -1;
}

function calcularDV(cnpj, posicaoDV) {
    const pesos = posicaoDV === 1 
        ? [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
        : [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];
    
    const digitos = posicaoDV === 1 
        ? cnpj.substring(0, 12) 
        : cnpj.substring(0, 12) + cnpj.charAt(12);
    
    let soma = 0;
    for (let i = 0; i < digitos.length; i++) {
        const valor = obterValorCaractere(digitos[i]);
        soma += valor * pesos[i];
    }
    
    const resto = soma % 11;
    return resto <= 1 ? 0 : 11 - resto;
}

function validarCNPJ(cnpj) {
    const cnpjLimpo = cnpj.replace(/[.\/-]/g, '');
    
    if (cnpjLimpo.length !== 14) {
        return false;
    }
    
    const dv1 = parseInt(cnpjLimpo[12], 10);
    const dv2 = parseInt(cnpjLimpo[13], 10);
    
    if (calcularDV(cnpjLimpo, 1) !== dv1) {
        return false;
    }
    
    if (calcularDV(cnpjLimpo, 2) !== dv2) {
        return false;
    }
    
    return true;
}

// Testes
// true (CNPJ atual válido)
console.log(validarCNPJ('83.847.133/0001-25')); 

// true (CNPJ novo fictício válido)
console.log(validarCNPJ('53.RRV.R8C/9PHH-34')); 

// false
console.log(validarCNPJ('12345678900013')); 

// false
console.log(validarCNPJ('77.888.364/0001-81')); 

// false
console.log(validarCNPJ('X3.VGJ.TBC/0001-43')); 

Referências

Instrução Normativa RFB nº 2.229/2024

Nota Técnica Conjunta CNPJ Alfanumérico 2025.001

Nota Técnica Conjunta COCAD/SUARA/RFB nº 49/2024

A mudança não é complexa, mas exige atenção. Quem esperar o dia pode enfrentar problemas de última hora.

Feito!

Nenhum comentário:

Postar um comentário