CodePráticov3.7.0
CNPJ 2026migração de sistemas

Como adaptar banco de dados, inputs e APIs para CNPJ alfanumérico

O CNPJ alfanumérico não exige apenas trocar uma regex. Se alguma parte do sistema trata CNPJ como número, remove letras, usa type="number" ou declara o identificador como inteiro em uma API, esse ponto precisa ser revisado.

Regra central: trate CNPJ como identificador textual, não como quantidade numérica. Os CNPJs existentes continuam válidos e as novas inscrições podem conter letras nas 12 primeiras posições.

Onde sistemas antigos costumam quebrar?

O impacto aparece em várias camadas. Faça uma busca no código e na estrutura do banco antes de começar a alterar telas isoladamente.

NUMBER
BIGINT
INTEGER
is_numeric(
ctype_digit(
intval(
parseInt(
Number(
type="number"
inputmode="numeric"
\d{14}
[0-9]{14}
preg_replace('/\D/'
cnpj: number
"type": "integer"

Nem toda ocorrência estará errada, mas essa busca ajuda a encontrar rapidamente pontos que assumem um CNPJ exclusivamente numérico.

1. Banco de dados: CNPJ deve ser texto

Se o CNPJ já está armazenado em CHAR, VARCHAR ou VARCHAR2 com tamanho suficiente, talvez você não precise alterar o tipo. Ainda assim, revise constraints, triggers, procedures, funções, índices funcionais e validações que permitam apenas números.

Se a coluna for numérica, não faça uma alteração de tipo às cegas em produção. Uma migração com coluna paralela é mais fácil de validar e reverter.

Exemplo seguro de migração no Oracle

ALTER TABLE CLIENTES
ADD CNPJ_NOVO VARCHAR2(14);

UPDATE CLIENTES
SET CNPJ_NOVO = LPAD(TO_CHAR(CNPJ), 14, '0')
WHERE CNPJ IS NOT NULL;

Depois da carga, valide quantidade de registros, duplicidades, valores nulos inesperados e relacionamentos antes de trocar a aplicação para a nova coluna.

Atenção aos zeros à esquerda: CNPJ é identificador. Se dados antigos foram guardados em campo numérico, confirme se os zeros iniciais foram preservados ou se precisarão ser recompostos na migração.

Uma sequência de migração mais segura é:

  1. adicionar a nova coluna textual;
  2. copiar e normalizar os valores antigos;
  3. executar validações e comparar resultados;
  4. ajustar aplicação, relatórios, procedures e integrações;
  5. criar ou recriar índices e constraints necessários;
  6. fazer o corte para a coluna nova;
  7. remover a coluna antiga somente depois da estabilização.

Armazene com ou sem máscara?

Para banco e integrações, o formato normalizado costuma ser mais simples:

00.000.000/E08G-12  // apresentação
00000000E08G12      // armazenamento normalizado

Isso mantém sempre 14 posições e evita que pontuação participe de índices, comparações e chaves. A máscara pode ser aplicada apenas na apresentação.

Padronize também as letras em maiúsculas antes de persistir. Isso evita inconsistências como e08g e E08G representando o mesmo identificador.

2. Inputs: não use mais campo exclusivamente numérico

Este HTML deixa de ser adequado para um campo de CNPJ:

<input
  type="number"
  inputmode="numeric"
  name="cnpj">

Use um campo textual:

<input
  type="text"
  name="cnpj"
  maxlength="18"
  autocomplete="off">

O tamanho 18 considera a apresentação mascarada AA.AAA.AAA/AAAA-DV. Se seu componente trabalha apenas com o valor normalizado, use 14 posições.

Angular / TypeScript

O CNPJ deve continuar como string em interfaces e formulários:

export interface Empresa {
  nome: string;
  cnpj: string;
}

Ao normalizar, retire apenas os separadores previstos e converta para maiúsculas:

export function normalizarCnpj(valor: string): string {
  return valor
    .trim()
    .toUpperCase()
    .replace(/[.\/\-\s]/g, '');
}

Para verificar somente a estrutura normalizada:

const CNPJ_FORMATO = /^[A-Z0-9]{12}[0-9]{2}$/;

export function temFormatoCnpj(valor: string): boolean {
  return CNPJ_FORMATO.test(normalizarCnpj(valor));
}

Se você usa uma biblioteca de máscara, confirme que a máscara permite letras e números nas 12 primeiras posições. Uma máscara baseada apenas em 0 ou dígitos continuará bloqueando CNPJs novos.

3. Backend: não sanitize apagando letras

Este padrão antigo não pode mais ser usado para normalizar um CNPJ:

$cnpj = preg_replace('/\D/', '', $cnpj);

Ele apaga exatamente as letras que agora podem fazer parte do identificador.

Em PHP, prefira remover somente a máscara conhecida:

function normalizarCnpj(string $cnpj): string
{
    return strtoupper(
        str_replace(['.', '/', '-', ' '], '', trim($cnpj))
    );
}

Depois, aplique validação de formato e, quando necessário, o cálculo dos dígitos verificadores. Veja a implementação completa em Como validar CNPJ numérico e alfanumérico em PHP.

4. APIs e JSON: declare CNPJ como string

Mesmo antes do formato alfanumérico, identificadores como CNPJ não deveriam ser modelados como número. Agora isso se torna obrigatório.

JSON correto

{
  "razaoSocial": "Empresa Exemplo",
  "cnpj": "00000000E08G12"
}

Evite

{
  "cnpj": 4252011000110
}

Além de não aceitar letras, um valor numérico pode perder zeros à esquerda e criar divergência entre sistemas.

OpenAPI / JSON Schema

cnpj:
  type: string
  minLength: 14
  maxLength: 14
  pattern: '^[A-Z0-9]{12}[0-9]{2}$'
  example: '00000000E08G12'

Essa expressão valida a estrutura, não os dígitos verificadores. O algoritmo de DV deve ficar na regra de negócio do backend.

5. DTOs, entidades e contratos internos

Procure declarações que transformem CNPJ em inteiro:

// ruim
public int $cnpj;

// ruim
cnpj: number;

// ruim
Long cnpj;

A representação deve ser textual em todas as camadas:

// PHP
public string $cnpj;

// TypeScript
cnpj: string;

O mesmo vale para filas, eventos, cache, importação/exportação, CSV, relatórios e mensagens entre microsserviços.

6. Integrações e sistemas legados

Uma integração pode falhar mesmo que sua aplicação principal esteja correta. Revise especialmente:

  • webservices que descrevem CNPJ como campo numérico;
  • arquivos de largura fixa;
  • XML/XSD e schemas de documentos fiscais;
  • ETLs e rotinas de importação;
  • stored procedures e jobs;
  • planilhas e exportações que convertem o identificador para número;
  • sistemas parceiros que rejeitam letras;
  • relatórios que formatam CNPJ com funções exclusivamente numéricas.

Quando a integração for baseada em um leiaute oficial, não invente uma regra local. Atualize para a versão oficial do schema ou manual correspondente.

7. Não quebre os CNPJs numéricos existentes

A mudança não substitui os números antigos. Os CNPJs já existentes permanecem válidos. Portanto, sua validação deve aceitar os dois cenários:

04.252.011/0001-10  // numérico existente
00.000.000/E08G-12  // alfanumérico

O erro mais comum em uma migração é corrigir o sistema para o formato novo e criar uma validação que, sem querer, rejeita dados antigos.

8. Monte testes de regressão antes do deploy

Inclua casos de frontend, backend, banco e integração. Um conjunto mínimo:

04.252.011/0001-10   // CNPJ numérico válido
00.000.000/E08G-12   // CNPJ alfanumérico oficial
12.ABC.345/01DE-35   // exemplo técnico de DV
12.ABC.345/01DE-36   // DV inválido
12.ABC.345/01D*-35   // caractere inválido
00.000.000/0000-00   // sequência inválida

Além da função de validação, teste cadastro, edição, pesquisa, filtros, ordenação, relatórios, exportação, APIs e rotinas batch.

Checklist de migração

  • campo do banco é textual e comporta 14 posições normalizadas;
  • constraints e triggers aceitam letras;
  • índices e chaves foram revisados;
  • backend não usa intval(), is_numeric() ou \D para CNPJ;
  • frontend não usa type="number" ou máscara somente numérica;
  • TypeScript/DTOs/entidades usam string;
  • JSON e OpenAPI descrevem CNPJ como string;
  • integrações externas foram testadas;
  • arquivos e relatórios preservam letras e zeros à esquerda;
  • formatos numérico antigo e alfanumérico foram testados;
  • o cálculo do DV está atualizado;
  • a implantação possui plano de rollback.

Leia o cluster completo sobre CNPJ alfanumérico

Fontes oficiais

Referências oficiais conferidas em 14/09/2026.