PHP code example of devsitarget / sdk-sefin-nfse-php

1. Go to this page and download the library: Download devsitarget/sdk-sefin-nfse-php 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/ */

    

devsitarget / sdk-sefin-nfse-php example snippets




declare(strict_types=1);

use SefinSdk\Config\CertificateConfig;
use SefinSdk\Config\Environment;
use SefinSdk\Sefin;
use SefinSdk\Dto\NfseSubmissionRequest;

: __DIR__ . '/certs/client.key',
        privateKeyPassword: 'senha-do-certificado'
    )
);

$response = $sdk->submitNfse(
    NfseSubmissionRequest::fromXml(file_get_contents(__DIR__ . '/examples/dps.xml'))
);

echo $response->chaveAcesso;



declare(strict_types=1);

use SefinSdk\Config\CertificateConfig;
use SefinSdk\Config\Environment;
use SefinSdk\Sefin;

$sdk = new Sefin(
    Environment::restrictedProduction(),
    new CertificateConfig(
        certificatePath: __DIR__ . '/certs/client.pem',
        privateKeyPath: __DIR__ . '/certs/client.key',
        privateKeyPassword: 'senha-do-certificado'
    )
);

$payload = [
    'infDPS' => [
        'tpAmb' => 2,
        'dhEmi' => '2026-01-15T10:00:00-03:00',
        'verAplic' => 'SEU_SISTEMA_1.0.0',
        'serie' => '1',
        'nDPS' => '1000',
        'dCompet' => '2026-01-15',
        'tpEmit' => 1,
        'cLocEmi' => '3550308',
        'prest' => [
            'CNPJ' => '12345678000190',
            'email' => '[email protected]',
            'regTrib' => ['opSimpNac' => 1, 'regEspTrib' => 0],
        ],
        'toma' => [
            'CPF' => '12345678901',
            'xNome' => 'Fulano de Tal',
            'end' => [
                'endNac' => ['cMun' => '3550308', 'CEP' => '01001000'],
                'xLgr' => 'RUA EXEMPLO',
                'nro' => '100',
                'xCpl' => 'SALA 10',
                'xBairro' => 'CENTRO',
            ],
            'fone' => '11999990000',
            'email' => '[email protected]',
        ],
        'serv' => [
            'locPrest' => ['cLocPrestacao' => '3550308'],
            'cServ' => [
                'cTribNac' => '080201',
                'cTribMun' => '001',
                'xDescServ' => "Serviço de exemplo.\n\nValores e descrição fictícios para demonstração.",
            ],
        ],
        'valores' => [
            'vServPrest' => ['vServ' => '100.00'],
            'trib' => [
                'tribMun' => ['tribISSQN' => 1, 'tpRetISSQN' => 1],
                'totTrib' => [
                    'vTotTrib' => ['vTotTribFed' => '0.00', 'vTotTribEst' => '0.00', 'vTotTribMun' => '0.00'],
                ],
            ],
        ],
    ],
];

$response = $sdk->submitNfseFromArray($payload);

echo $response->chaveAcesso;

'serv' => [
    'locPrest' => ['cLocPrestacao' => '3304557'],
    'cServ' => [
        'cTribNac' => '120801',
        'cTribMun' => '001',
        'xDescServ' => 'INSCRIÇÃO PARA O 58° CONGRESSO BRASILEIRO DE PATOLOGIA CLÍNICA',
    ],
    'atvEvento' => [
        'xNome' => '58° CONGRESSO BRASILEIRO DE PATOLOGIA CLÍNICA',
        'dtIni' => '2026-09-01',
        'dtFim' => '2026-09-05',

        // Opção A: código do evento na Administração Tributária Municipal
        // 'idAtvEvt' => 'CODIGO-DO-EVENTO',

        // Opção B: endereço do evento (mutuamente exclusivo com idAtvEvt)
        'end' => [
            'CEP' => '20040020',
            'xLgr' => 'Av. Churchill',
            'nro' => '94',
            'xBairro' => 'Centro',
        ],
    ],
],

$payload = [
    'infDPS' => [
        // ... campos normais (tpAmb, dhEmi, serie, nDPS, etc.) ...

        'subst' => [
            'chSubstda' => '31062002250516724000160000000000002126046985535602', // chave da NFS-e a ser substituída
            'cMotivo'   => '1',  // 1 = Desenquadramento de NFS-e do Simples Nacional
                                 // 2 = Enquadramento de NFS-e no Simples Nacional
                                 // 3 = Inclusão Retroativa de Imunidade/Isenção
                                 // 4 = Exclusão Retroativa de Imunidade/Isenção
                                 // 5 = Rejeição de NFS-e pelo tomador/intermediário
                                 // 99 = Outros (xMotivo obrigatório)
            // 'xMotivo' => 'Descrição do motivo', // obrigatório apenas quando cMotivo = 99
        ],

        'prest' => [ /* ... */ ],
        // ...
    ],
];

$response = $sdk->submitNfseFromArray($payload);



declare(strict_types=1);

use SefinSdk\Support\DanfsePdfGenerator;

DanfsePdfGenerator())->generateFromXml($xml);

header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="danfse.pdf"');
echo $pdf;



declare(strict_types=1);

use SefinSdk\Config\CertificateConfig;
use SefinSdk\Config\Environment;
use SefinSdk\Sefin;

erts/client.pem',
        privateKeyPath:  __DIR__ . '/certs/client.key',
        privateKeyPassword: 'senha-do-certificado'
    )
);

$chaveAcesso = '31062002250516724000160000000000002126046985535602';

// GET /nfse/{chaveAcesso}/eventos
$response = $sdk->getEventsByAccessKey($chaveAcesso);

echo "Processado em: " . $response->dataHoraProcessamento->format('d/m/Y H:i:s') . PHP_EOL;
echo "Total de eventos: " . count($response->eventos) . PHP_EOL;

foreach ($response->eventos as $evento) {
    // decodedXml() descompacta o gzip+base64 e retorna o XML do evento
    echo $evento->decodedXml();
}



declare(strict_types=1);

use SefinSdk\Config\CertificateConfig;
use SefinSdk\Config\Environment;
use SefinSdk\Sefin;

erts/client.pem',
        privateKeyPath:  __DIR__ . '/certs/client.key',
        privateKeyPassword: 'senha-do-certificado' // null se a chave não for protegida por senha
    )
);

// Chave de acesso da NFS-e que você quer cancelar (50 caracteres).
$chaveAcesso = '31062002250516724000160000000000002126046985535602';

$response = $sdk->cancelNfse(
    chaveAcesso: $chaveAcesso,
    params: [
        'cMotivo' => '1',
        // Códigos aceitos:
        //   1 = Erro na emissão
        //   2 = Serviço não prestado
        //   9 = Outros → neste caso, 'xMotivo' passa a ser obrigatório (15-255 chars)

        // 'xMotivo' => 'Descrição detalhada do motivo do cancelamento.', // obrigatório quando cMotivo = 9
    ]
);

// O XML do evento registrado e autorizado pela SEFIN (descompactado):
echo $response->decodedXml();



declare(strict_types=1);

use SefinSdk\Config\CertificateConfig;
use SefinSdk\Config\Environment;
use SefinSdk\Dto\RegisterEventRequest;
use SefinSdk\Sefin;
use SefinSdk\Support\EventXmlFactory;
use SefinSdk\Support\EventXmlSigner;

4000160000000000002126046985535602';
$certPath      = __DIR__ . '/certs/client.pem';
$keyPath       = __DIR__ . '/certs/client.key';
$keyPassword   = 'senha-do-certificado'; // null se a chave não for protegida por senha

// ─── 2. Montar o XML de pedido de cancelamento ──────────────────────────────

$eventXml = EventXmlFactory::forCancellation([
    'tpAmb'      => '2',                              // 1=Produção, 2=Homologação
    'verAplic'   => 'meu-sistema/1.0',
    'dhEvento'   => '2026-07-07T09:30:00-03:00',
    'CNPJAutor'  => '12345678000190',                 // ou CPFAutor
    'chNFSe'     => $chaveAcesso,
    'cMotivo'    => '1',                              // 1, 2 ou 9
    // 'xMotivo' => 'Descrição do motivo...',         // obrigatório quando cMotivo = 9 (15-255 chars)
]);

// Neste ponto $eventXml é um XML não assinado, por exemplo:
//
// <pedRegEvento versao="1.00" xmlns="http://www.sped.fazenda.gov.br/nfse">
//   <infPedReg Id="PRE31062002250516724000160000000000002126046985535602101101">
//     <tpAmb>2</tpAmb>
//     <verAplic>meu-sistema/1.0</verAplic>
//     <dhEvento>2026-07-07T09:30:00-03:00</dhEvento>
//     <CNPJAutor>12345678000190</CNPJAutor>
//     <chNFSe>31062002250516724000160000000000002126046985535602</chNFSe>
//     <e101101>
//       <xDesc>Cancelamento de NFS-e</xDesc>
//       <cMotivo>1</cMotivo>
//       <xMotivo>Erro na emissão da NFS-e.</xMotivo>
//     </e101101>
//   </infPedReg>
// </pedRegEvento>

// ─── 3. Assinar o XML com o certificado do emitente ─────────────────────────

// Lê os arquivos de certificado e chave privada.
$certPem = file_get_contents($certPath);
$keyPem  = file_get_contents($keyPath);

// Assina o elemento <infPedReg> com RSA-SHA1 (padrão SEFIN).
// A assinatura é inserida como filho direto de <pedRegEvento>.
$eventXmlSigned = EventXmlSigner::signInfPedReg(
    eventXml:          $eventXml,
    privateKeyPem:     $keyPem,
    certificatePem:    $certPem,
    privateKeyPassword: $keyPassword // null se a chave não for protegida por senha
);

// ─── 4. Empacotar e enviar para a SEFIN ─────────────────────────────────────

// RegisterEventRequest comprime o XML em gzip+base64 conforme o contrato da API.
$request = RegisterEventRequest::fromXml($eventXmlSigned);

$sdk = new Sefin(
    Environment::restrictedProduction(),
    new CertificateConfig($certPath, $keyPath, $keyPassword)
);

// Envia para POST /nfse/{chaveAcesso}/eventos
$response = $sdk->registerEvent($chaveAcesso, $request);

// ─── 5. Tratar a resposta ───────────────────────────────────────────────────

echo "Evento registrado em: " . $response->dataHoraProcessamento->format('d/m/Y H:i:s') . PHP_EOL;
echo "XML do evento autorizado:" . PHP_EOL;
echo $response->decodedXml();