Chave da NFSe e Cálculo do Digito Verificador

Estrutura da Chave de Acesso da NFS-e (49 dígitos + Dígito Verificador)

A geração da chave de acesso da NFS-e Nacional segue uma estrutura padronizada de 49 dígitos fixos, composta por informações como município, ambiente, tipo de inscrição, CPF/CNPJ, número da nota, ano, mês e código complementar. Sobre esses 49 dígitos aplica-se um dígito verificador (DV) calculado pelo módulo 11 adaptado, garantindo a integridade da chave.

Nesse exemplo essa chave é montada de forma determinística utilizando o sprintf no PHP, que assegura o preenchimento com zeros à esquerda e o comprimento correto de cada campo.

Além disso, o cálculo do DV segue a lógica de multiplicadores cíclicos de 2 a 9, aplicados sequencialmente a todos os dígitos, reforçando a validação e evitando inconsistências.

:pushpin: Estrutura da chave (49 dígitos) + Digito Verificador

Cód.Mun. (7) +
Amb.Ger. (1) +
Tipo Insc. Federal (1) +
CPF/CNPJ (14) +
Nº NFS-e (13) +
Ano (2) +
Mês (2) +
Código (9) +
DV (1)

:pushpin: Como o sprintf monta

$cMun    = 3550308;   // São Paulo
$ambGer  = 2;         // Nacional
$tIncr   = 2;         // Jurídica
$cnpj    = 12345678000195;
$numero  = 123;
$ano     = 25;        // 2025
$mes     = 9;
$codigo  = 456789;  // Pode ser gerado randômico 


$format = "%07d%01d%01d%014d%013d%02d%02d%09d";

$key = sprintf($format,
            $cMun,
            $ambGer,
            $tIncr,
            $cnpj,
            $numero,
            $ano,
            $mes,
            $codigo
        );

Explicação do sprintf:

%07d → número com 7 dígitos, completado à esquerda com zeros (→ $cMun)

%01d → número com 1 dígito (→ $ambGer)

%01d → número com 1 dígito (→ $tIncr)

%014d → número com 14 dígitos, zero à esquerda (→ $cnpj ou CPF)

%013d → número com 13 dígitos (→ $numero da NFS-e)

%02d → número com 2 dígitos (→ $ano, ex: 25 para 2025)

%02d → número com 2 dígitos (→ $mes, ex: 09)

%09d → número com 9 dígitos (→ $codigo, 456789)

:magnifying_glass_tilted_right: Diferenças em relação ao Módulo 11 “clássico”

  1. Multiplicadores fixos [2–9] em sequência cíclica

    • No módulo 11 tradicional, a regra mais comum é multiplicar da direita para a esquerda usando pesos de 2 até 9, reiniciando em 2 depois do 9.

    • Aqui também se usa [2,3,4,5,6,7,8,9], mas o loop está programado de uma forma específica: um for interno de 8 passos que sempre recomeça a sequência, até consumir os 49 dígitos.

    ➝ Isso garante que todos os 49 caracteres sejam multiplicados em ciclos exatos de 2 a 9.

public function digitoVerificador(string $key): string
{
        if (strlen($key) != 49) {
            return '';
        }
        $multipliers = [2, 3, 4, 5, 6, 7, 8, 9];
        $iCount = 48;
        $weightedSum = 0;
        while ($iCount >= 0) {
            for ($mCount = 0; $mCount < 8 && $iCount >= 0; $mCount++) {
                $sub = (int)$key[$iCount];
                $weightedSum += $sub * $multipliers[$mCount];
                $iCount--;
            }
        }
        $vdigit = 11 - ($weightedSum % 11);
        if ($vdigit > 9) {
            $vdigit = 0;
        }
        return (string)$vdigit;
}