PHP code example of mendesalexandre / php-nfse-nacional

1. Go to this page and download the library: Download mendesalexandre/php-nfse-nacional library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

mendesalexandre / php-nfse-nacional example snippets


use PhpNfseNacional\NFSe;
use PhpNfseNacional\Config;
use PhpNfseNacional\Certificate\Certificate;
use PhpNfseNacional\DTO\{Prestador, Tomador, Endereco, Servico, Valores, Identificacao};
use PhpNfseNacional\Enums\{Ambiente, RegimeEspecialTributacao};

// 1. Carregue o certificado A1
$cert = Certificate::fromPfxFile('/path/cert.pfx', 'senha-do-pfx');

// 2. Configure o prestador (singleton, uma vez na app)
$prestador = new Prestador(
    cnpj: '12345678000195',
    inscricaoMunicipal: '12345',
    razaoSocial: 'EMPRESA XYZ',
    endereco: new Endereco(
        logradouro: 'RUA EXEMPLO',
        numero: '100',
        bairro: 'CENTRO',
        cep: '01310100',
        codigoMunicipioIbge: '3550308',
        uf: 'MT',
    ),
    regimeEspecial: RegimeEspecialTributacao::NotarioOuRegistrador,
);

$config = new Config(
    prestador: $prestador,
    ambiente: Ambiente::Homologacao,
);

// 3. Crie o SDK
$nfse = NFSe::create($config, $cert);

// 4. Emita uma NFS-e
$resposta = $nfse->emitir(
    identificacao: new Identificacao(numeroDps: 1, serie: '1'),
    tomador: new Tomador(
        documento: '12345678901',
        nome: 'Cliente Exemplo',
        endereco: new Endereco(
            logradouro: 'Rua A',
            numero: '100',
            bairro: 'Centro',
            cep: '01310100',
            codigoMunicipioIbge: '3550308',
            uf: 'MT',
        ),
    ),
    servico: new Servico(
        discriminacao: 'Certidão de matrícula',
        codigoMunicipioPrestacao: '3550308',
    ),
    valores: new Valores(
        valorServicos: 100.00,
        deducoesReducoes: 20.00,
        aliquotaIssqnPercentual: 4.00,
    ),
);

echo "Chave: " . $resposta->chaveAcesso;
echo "Número: " . $resposta->numeroNfse;

use PhpNfseNacional\DTO\MotivoCancelamento;

$resposta = $nfse->cancelar(
    chaveAcesso: '35012345200001234567890123456789012345678123456789',
    motivo: MotivoCancelamento::ErroEmissao,
    justificativa: 'Valor da NFS-e divergente do recibo',
);

use PhpNfseNacional\DTO\Valores;
use PhpNfseNacional\Enums\{SituacaoSimplesNacional, MotivoDispensaIssqn};

$prestador = new Prestador(
    /* ... */
    simplesNacional: SituacaoSimplesNacional::MEI,
    inscricaoMunicipal: null, // MEI normalmente sem IM cadastrada
);

$valores = new Valores(
    valorServicos: 800.00,
    deducoesReducoes: 0.00,
    aliquotaIssqnPercentual: 0.00,
    motivoDispensaIssqn: MotivoDispensaIssqn::OptanteSimplesNacional,
    // emite <indTotTrib>0</indTotTrib> em vez de <pTotTrib>
);

use PhpNfseNacional\DTO\{Tomador, EnderecoExterior};

$tomador = new Tomador(
    documento: '12345678901',       // ou NIF estrangeiro (futuro)
    nome: 'JOHN DOE',
    endereco: new EnderecoExterior(
        logradouro: '5th Avenue',
        numero: '350',
        bairro: 'Manhattan',
        codigoPaisIso: 'US',            // 2 letras ISO
        codigoEnderecamentoPostal: '10118',
        cidade: 'New York',
        estadoProvinciaRegiao: 'NY',
    ),
);
// DpsBuilder detecta o tipo e emite <endExt> em vez de <endNac>

use PhpNfseNacional\Enums\TipoRetencaoIssqn;

$valores = new Valores(
    valorServicos: 1000.00,
    deducoesReducoes: 0.00,
    aliquotaIssqnPercentual: 4.00,
    tipoRetencaoIssqn: TipoRetencaoIssqn::RetidoPeloTomador, // tomador retém ISSQN
    // alternativas: NaoRetido (default), RetidoPeloIntermediario
);

use PhpNfseNacional\Enums\{TipoTributacaoIssqn, TipoImunidadeIssqn};

$valores = new Valores(
    valorServicos: 100.00,
    deducoesReducoes: 0.00,
    aliquotaIssqnPercentual: 0.00,
    tributacaoIssqn: TipoTributacaoIssqn::Imunidade,
    imunidade: TipoImunidadeIssqn::TemplosQualquerCulto,
);

use PhpNfseNacional\DTO\BeneficioMunicipal;

$valores = new Valores(
    valorServicos: 100.00,
    deducoesReducoes: 0.00,
    aliquotaIssqnPercentual: 4.00,
    beneficioMunicipal: new BeneficioMunicipal(
        nBM: '35503080100001',     // ID parametrizado pelo município
        percentualReducaoBc: 50.00, // ou valorReducaoBc — choice no schema
    ),
);

use PhpNfseNacional\Enums\{ListaServicosNacional, ListaNbs};

$servico = new Servico(
    discriminacao: 'Análise e desenvolvimento de sistemas',
    codigoMunicipioPrestacao: '3550308',
    cTribNac: ListaServicosNacional::S010101,  // ou string '010101'
    cNBS:     ListaNbs::N101011100,             // ou string '101011100'
);

echo $servico->cTribNac;                                 // '010101'
echo ListaServicosNacional::S010101->descricao();        // 'Análise e desenvolvimento...'

use PhpNfseNacional\DTO\Intermediario;

$intermediario = new Intermediario(
    documento: '12345678000195',
    nome: 'MARKETPLACE EXEMPLO LTDA',
    endereco: $endereco,        // Endereco nacional OU EnderecoExterior — opcional
    inscricaoMunicipal: '987654',
    email: '[email protected]',
);

$nfse->emitir(
    identificacao: $id,
    tomador: $tomador,
    servico: $servico,
    valores: $valores,
    intermediario: $intermediario,
);

use PhpNfseNacional\DTO\InformacoesComplementares;

$servico = new Servico(
    discriminacao: 'Serviço prestado',
    codigoMunicipioPrestacao: '...',
    infoCompl: new InformacoesComplementares(
        xInfComp: 'Pedido #12345 - pagamento à vista - cliente VIP',
    ),
);

use PhpNfseNacional\DTO\DocumentoDeducao;
use PhpNfseNacional\Enums\TipoDeducaoReducao;

$deducao = new DocumentoDeducao(
    tipo: TipoDeducaoReducao::Materiais,
    dataEmissaoDocumento: new DateTimeImmutable('2026-05-01'),
    valorDedutivel: 5000.00,
    valorDeducao: 4500.00,
    chaveNfe: '35012345...',  // ou chaveNfse / numeroDocumento
);

$valores = new Valores(
    valorServicos: 10000.00,
    deducoesReducoes: 0.00,           // ZERO! choice no schema
    aliquotaIssqnPercentual: 4.00,
    documentosDeducao: [$deducao],
);

use PhpNfseNacional\DTO\TributacaoPisCofins;
use PhpNfseNacional\Enums\{CstPisCofins, TipoRetencaoPisCofins};

$valores = new Valores(
    valorServicos: 1000.00,
    deducoesReducoes: 0.00,
    aliquotaIssqnPercentual: 4.00,
    tributacaoPisCofins: new TributacaoPisCofins(
        cst: CstPisCofins::OperacaoTributavelAliquotaBasica,
        valorBaseCalculo: 1000.00,
        aliquotaPis: 0.65,
        aliquotaCofins: 3.00,
        valorPis: 6.50,
        valorCofins: 30.00,
        tipoRetencao: TipoRetencaoPisCofins::Retido,
    ),
    valorRetidoIrrf: 15.00,
    valorRetidoCp: 11.00,
    valorRetidoCsll: 10.00,
);

$idDps = 'DPS35503082212345678000195000010000000001285AB';

if ($nfse->verificarDps($idDps)) {
    echo "DPS já existe no SEFIN — não emite de novo\n";
} else {
    $resposta = $nfse->emitir(...);
}

// Persiste o último NSU pra sincronização incremental
$ultimoNsuConhecido = (int) $cache->get('dfe_ultimo_nsu', 0);

$resp = $nfse->sincronizarDfe($ultimoNsuConhecido);

foreach ($resp->itens as $item) {
    echo "NSU {$item->nsu}: {$item->tipoDocumento} chave={$item->chaveAcesso}\n";
}

$cache->set('dfe_ultimo_nsu', $resp->ultimoNsu);

use PhpNfseNacional\DTO\MotivoCancelamento;

use PhpNfseNacional\DTO\MotivoSubstituicao;

$resposta = $nfse->substituir(
    chaveOriginal:   '35503082212345678000195000000000005712345678901234',
    chaveSubstituta: '35503082212345678000195000000000005812345678901235',
    motivo:          MotivoSubstituicao::DesenquadramentoSimples,
);

use PhpNfseNacional\Dps\EventoNfse;
use PhpNfseNacional\Dps\EventoBuilder;

final class MeuEventoCustomizado implements EventoNfse
{
    public function chaveAcesso(): string { return '...'; }
    public function codigoTipoEvento(): string { return '101102'; } // ex: substituição
    public function nSequencial(): int { return 1; }
    public function descricao(): string { return 'Substituição de NFS-e'; }
    public function camposGrupo(): array { return ['campoX' => 'valor']; }
}

$xml = (new EventoBuilder($config))->build(new MeuEventoCustomizado());
$xmlAssinado = $signer->sign($xml, 'infPedReg');
$resposta = $client->postXml($endpoints->cancelarNfse($chave), $xmlAssinado);

use PhpNfseNacional\Certificate\Signer;
Signer::habilitarLegacyProviderRuntime();
bash
composer