Try Live
Add Docs
Rankings
Pricing
Enterprise
Docs
Install
Install
Docs
Pricing
Enterprise
More...
More...
Try Live
Rankings
Add Docs
SPED NFe
https://github.com/nfephp-org/sped-nfe
Admin
A PHP library for generating, signing, and sending electronic invoices (NFe and NFCe) to Brazilian
...
Tokens:
234,000
Snippets:
1,813
Trust Score:
7.8
Update:
2 weeks ago
Context
Skills
Chat
Benchmark
71.2
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# SPED-NFe O **sped-nfe** (`nfephp-org/sped-nfe`) é uma biblioteca PHP para geração, assinatura e comunicação de Notas Fiscais Eletrônicas (NF-e, modelo 55) e Notas Fiscais de Consumidor Eletrônicas (NFC-e, modelo 65) com as SEFAZ autorizadoras de todos os estados brasileiros. A biblioteca cobre todo o ciclo de vida do documento fiscal eletrônico: desde a montagem do XML, passando pela assinatura digital com certificado A1/A3, até o envio e recebimento de respostas dos webservices SOAP da SEFAZ, incluindo todos os eventos (cancelamento, carta de correção, manifestação do destinatário, etc.). A biblioteca segue os padrões PSR-1, PSR-2 e PSR-4 e é compatível com PHP >= 7.4. Seu uso exige o Composer para instalação, e depende do pacote `nfephp-org/sped-common` para operações de certificado digital, assinatura XML e comunicação SOAP. As principais classes de trabalho são `Make` (montagem do XML da NF-e), `Tools` (comunicação com a SEFAZ) e `Complements` (protocolação e pós-processamento dos documentos). --- ## Instalação ```bash composer require nfephp-org/sped-nfe ``` --- ## Configuração da classe Tools A classe `Tools` recebe um JSON de configuração e um objeto `Certificate` carregado a partir de um arquivo PFX (certificado digital A1). ```php <?php require 'vendor/autoload.php'; use NFePHP\NFe\Tools; use NFePHP\Common\Certificate; // Monta o JSON de configuração $config = [ "atualizacao" => "2024-01-01 00:00:00", "tpAmb" => 2, // 1=Produção, 2=Homologação "razaosocial" => "Empresa Exemplo Ltda", "siglaUF" => "SP", // UF do emitente "cnpj" => "00716345000119", "schemes" => "PL_009_V4", // versão do schema SEFAZ "versao" => "4.00", "tokenIBPT" => "", "CSC" => "GPB0JBWLUR6HWFTVEAS6RJ69GPCROFPBBB8G", // obrigatório para NFCe "CSCid" => "000001", "aProxyConf" => [ "proxyIp" => "", "proxyPort" => "", "proxyUser" => "", "proxyPass" => "" ] ]; $configJson = json_encode($config); $pfxContent = file_get_contents('/caminho/para/certificado.pfx'); $certificate = Certificate::readPfx($pfxContent, 'senha_do_certificado'); // Instancia para NF-e (modelo 55) $tools = new Tools($configJson, $certificate); $tools->model('55'); // Para NFC-e use model('65') // $tools->model('65'); ``` --- ## Make — Montagem do XML da NF-e A classe `Make` constrói o XML da NF-e/NFC-e a partir de objetos `stdClass`. Cada tag obrigatória do leiaute SEFAZ possui um método dedicado. Ao final, `getXML()` retorna o XML sem assinatura. ```php <?php use NFePHP\NFe\Make; $make = new Make(); // --- infNFe (raiz obrigatória) --- $std = new stdClass(); $std->Id = ''; $std->versao = '4.00'; $make->taginfNFe($std); // --- ide (identificação da NF-e) --- $std = new stdClass(); $std->cUF = 35; // código IBGE da UF (SP=35) $std->cNF = '12345678'; // código numérico aleatório $std->natOp = 'VENDA DE MERCADORIA'; $std->mod = 55; // 55=NF-e, 65=NFC-e $std->serie = 1; $std->nNF = 1001; $std->dhEmi = (new \DateTime())->format('Y-m-d\TH:i:sP'); $std->dhSaiEnt = null; $std->tpNF = 1; // 0=Entrada, 1=Saída $std->idDest = 1; // 1=Operação interna $std->cMunFG = 3550308; // cód. IBGE município (São Paulo) $std->tpImp = 1; $std->tpEmis = 1; $std->cDV = 0; $std->tpAmb = 2; // 2=Homologação $std->finNFe = 1; $std->indFinal = 0; $std->indPres = 0; $std->procEmi = 0; $std->verProc = '1.0.0'; $std->dhCont = null; $std->xJust = null; $make->tagIde($std); // --- emit (emitente) --- $std = new stdClass(); $std->CNPJ = '00716345000119'; $std->xNome = 'Empresa Exemplo Ltda'; $std->xFant = 'Exemplo'; $std->IE = '111111111111'; $std->CRT = 1; // 1=Simples Nacional $make->tagemit($std); // --- enderEmit --- $std = new stdClass(); $std->xLgr = 'Rua das Flores'; $std->nro = '100'; $std->xCpl = null; $std->xBairro = 'Centro'; $std->cMun = 3550308; $std->xMun = 'São Paulo'; $std->UF = 'SP'; $std->CEP = '01001000'; $std->cPais = 1058; $std->xPais = 'BRASIL'; $std->fone = '1100000000'; $make->tagenderEmit($std); // --- dest (destinatário) --- $std = new stdClass(); $std->CNPJ = '12345678000195'; $std->xNome = 'Destinatário Exemplo Ltda'; $std->indIEDest = 1; $std->IE = '222222222222'; $std->email = 'dest@exemplo.com.br'; $make->tagdest($std); // --- enderDest --- $std = new stdClass(); $std->xLgr = 'Av. Brasil'; $std->nro = '200'; $std->xCpl = 'Sala 5'; $std->xBairro = 'Jardim'; $std->cMun = 3304557; $std->xMun = 'Rio de Janeiro'; $std->UF = 'RJ'; $std->CEP = '20040020'; $std->cPais = 1058; $std->xPais = 'BRASIL'; $std->fone = '2100000000'; $make->tagenderDest($std); // --- det / prod (item 1) --- $std = new stdClass(); $std->item = 1; $std->cProd = 'PROD001'; $std->cEAN = 'SEM GTIN'; $std->xProd = 'Produto de Exemplo'; $std->NCM = '84713019'; $std->CFOP = '6102'; $std->uCom = 'UN'; $std->qCom = 1.0000; $std->vUnCom = 100.00; $std->vProd = 100.00; $std->cEANTrib = 'SEM GTIN'; $std->uTrib = 'UN'; $std->qTrib = 1.0000; $std->vUnTrib = 100.00; $std->vFrete = null; $std->vSeg = null; $std->vDesc = null; $std->vOutro = null; $std->indTot = 1; $make->tagprod($std); // --- ICMS (CSOSN 400 – Simples Nacional) --- $std = new stdClass(); $std->item = 1; $std->orig = 0; $std->CSOSN = 400; $make->tagICMSSN($std); // --- PIS e COFINS (não tributado) --- $std = new stdClass(); $std->item = 1; $std->CST = '07'; $make->tagPISNT($std); $std = new stdClass(); $std->item = 1; $std->CST = '07'; $make->tagCOFINSNT($std); // --- pag (pagamento) --- $std = new stdClass(); $std->vTroco = null; $make->tagpag($std); $std = new stdClass(); $std->item = 1; $std->tPag = '01'; // 01=Dinheiro $std->vPag = 100.00; $std->indPag = 0; $make->tagdetPag($std); // Gera o XML (sem assinatura) $xml = $make->getXML(); // Verifica erros de montagem $erros = $make->getErrors(); if (!empty($erros)) { foreach ($erros as $erro) { echo "Erro: $erro\n"; } } echo $xml; // XML da NF-e pronto para assinar e enviar ``` --- ## Tools::sefazEnviaLote — Autorização de NF-e em lote Envia um lote de NF-e (modelo 55 ou NFC-e modelo 65) para autorização na SEFAZ. O parâmetro `$indSinc=1` ativa o modo síncrono (apenas um documento por vez). Retorna o XML de resposta SOAP da SEFAZ. ```php <?php use NFePHP\NFe\Tools; use NFePHP\NFe\Complements; use NFePHP\Common\Certificate; $tools = new Tools($configJson, Certificate::readPfx($pfxContent, 'senha')); $tools->model('55'); // $xmlAssinado = XML já assinado com Signer::sign(...) $xmlAssinado = file_get_contents('/tmp/nfe_assinada.xml'); try { // Envio assíncrono de lote com múltiplas NF-e $idLote = '000000001'; $response = $tools->sefazEnviaLote([$xmlAssinado], $idLote, 0); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if ($std->cStat == 103) { // Lote recebido com sucesso; consultar pelo recibo $recibo = $std->infRec->nRec; echo "Lote aceito. Recibo: $recibo\n"; // Aguarda processamento e consulta sleep(5); $retResponse = $tools->sefazConsultaRecibo($recibo); $retStd = (new \NFePHP\NFe\Common\Standardize($retResponse))->toStd(); foreach ($retStd->protNFe as $prot) { if ($prot->infProt->cStat == 100) { // NF-e autorizada — protocola o XML $xmlProtocolado = Complements::toAuthorize($tools->lastRequest, $retResponse); file_put_contents('/tmp/nfe_protocolada.xml', $xmlProtocolado); echo "NF-e autorizada: " . $prot->infProt->chNFe . "\n"; } } } elseif ($std->cStat == 104) { // Lote processado de forma síncrona $xmlProtocolado = Complements::toAuthorize($tools->lastRequest, $response); } else { echo "Rejeição: [{$std->cStat}] {$std->xMotivo}\n"; } } catch (\Exception $e) { echo "Erro: " . $e->getMessage() . "\n"; } ``` --- ## Tools::sefazConsultaRecibo — Consulta de recibo de lote Verifica o resultado do processamento de um lote enviado de forma assíncrona usando o número do recibo retornado pelo `sefazEnviaLote`. ```php <?php try { $recibo = '135170001136476'; $response = $tools->sefazConsultaRecibo($recibo); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); // cStat 104 = Lote processado if ($std->cStat == 104) { foreach ((array)$std->protNFe as $prot) { $cStat = $prot->infProt->cStat; $chNFe = $prot->infProt->chNFe; echo "NF-e $chNFe → cStat: $cStat\n"; // 100 = Autorizado o uso da NF-e } } } catch (\InvalidArgumentException $e) { echo "Parâmetro inválido: " . $e->getMessage() . "\n"; } ``` --- ## Tools::sefazConsultaChave — Consulta situação pela chave de acesso Consulta a situação atual de uma NF-e na SEFAZ a partir da chave de acesso de 44 dígitos. Retorna o protocolo de autorização ou rejeição. ```php <?php try { $chave = '35240100716345000119550010000010011000000105'; $response = $tools->sefazConsultaChave($chave); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if (isset($std->protNFe)) { $cStat = $std->protNFe->infProt->cStat; $nProt = $std->protNFe->infProt->nProt; $dhRecbto = $std->protNFe->infProt->dhRecbto; echo "Situação: $cStat | Protocolo: $nProt | Recebido em: $dhRecbto\n"; } else { echo "NF-e não encontrada ou rejeitada: {$std->xMotivo}\n"; } } catch (\InvalidArgumentException $e) { echo "Chave inválida: " . $e->getMessage() . "\n"; } ``` --- ## Tools::sefazStatus — Consulta status do serviço SEFAZ Verifica se o serviço da SEFAZ para a UF configurada está operacional. Pode ser chamado sem parâmetros para usar a UF do `config.json` ou passando uma UF específica. ```php <?php // Consulta status da UF do config.json $response = $tools->sefazStatus(); // Consulta status de uma UF específica (ignora contingência ativa) // $response = $tools->sefazStatus('RJ'); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); // cStat 107 = Serviço em Operação if ($std->cStat == 107) { echo "Serviço SEFAZ operacional: {$std->xMotivo}\n"; } else { echo "Serviço indisponível [{$std->cStat}]: {$std->xMotivo}\n"; } ``` --- ## Tools::sefazCancela — Cancelamento de NF-e Envia o evento de cancelamento de uma NF-e autorizada. A justificativa deve ter entre 15 e 255 caracteres e o protocolo de autorização é obrigatório. ```php <?php use NFePHP\NFe\Complements; try { $chave = '35240100716345000119550010000010011000000105'; $xJust = 'Cancelamento a pedido do cliente por desistência da compra'; $nProt = '135240001234567'; $response = $tools->sefazCancela($chave, $xJust, $nProt); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if ($std->cStat == 128) { $cStatEvt = $std->retEvento->infEvento->cStat; if (in_array($cStatEvt, [101, 135, 155])) { // Cancelamento autorizado — protocola e armazena $xmlProtocolado = Complements::toAuthorize($tools->lastRequest, $response); file_put_contents('/tmp/cancelamento_protocolado.xml', $xmlProtocolado); echo "NF-e cancelada com sucesso. cStat: $cStatEvt\n"; } else { echo "Cancelamento negado [{$cStatEvt}]: {$std->retEvento->infEvento->xMotivo}\n"; } } else { echo "Erro no lote de evento [{$std->cStat}]: {$std->xMotivo}\n"; } } catch (\InvalidArgumentException $e) { echo "Parâmetros inválidos: " . $e->getMessage() . "\n"; } ``` --- ## Tools::sefazCCe — Carta de Correção Eletrônica Envia uma Carta de Correção Eletrônica (CC-e) para corrigir informações em uma NF-e autorizada. Não é permitida a correção de dados que alteram o valor do imposto, dados do emitente/destinatário ou data de emissão. ```php <?php try { $chave = '35240100716345000119550010000010011000000105'; $xCorrecao = 'CORRIGIR DADOS DO TRANSPORTE: PLACA DO VEICULO DE AAA0000 PARA BBB1111'; $nSeqEvento = 1; // Incrementar a cada nova CC-e para a mesma NF-e $response = $tools->sefazCCe($chave, $xCorrecao, $nSeqEvento); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if ($std->cStat == 128) { $cStatEvt = $std->retEvento->infEvento->cStat; if ($cStatEvt == 135) { $xmlProtocolado = \NFePHP\NFe\Complements::toAuthorize($tools->lastRequest, $response); echo "CC-e registrada. Evento: $cStatEvt\n"; } else { echo "CC-e negada [{$cStatEvt}]: {$std->retEvento->infEvento->xMotivo}\n"; } } } catch (\InvalidArgumentException $e) { echo "Erro: " . $e->getMessage() . "\n"; } ``` --- ## Tools::sefazManifesta — Manifestação do Destinatário Registra a manifestação do destinatário (ciência, confirmação, desconhecimento ou operação não realizada) para NF-e recebidas. ```php <?php // Constantes de evento disponíveis em Tools::class // EVT_CIENCIA = 210210 // EVT_CONFIRMACAO = 210200 // EVT_DESCONHECIMENTO = 210220 // EVT_NAO_REALIZADA = 210240 $chave = '35240100716345000119550010000010011000000105'; // 1. Ciência da operação (obrigatório antes dos demais eventos) $response = $tools->sefazManifesta($chave, Tools::EVT_CIENCIA); // 2. Confirmação da operação $response = $tools->sefazManifesta($chave, Tools::EVT_CONFIRMACAO); // 3. Operação não realizada (requer justificativa) $xJust = 'Mercadoria recusada pois não corresponde ao pedido'; $response = $tools->sefazManifesta($chave, Tools::EVT_NAO_REALIZADA, $xJust); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if ($std->cStat == 128 && $std->retEvento->infEvento->cStat == 135) { echo "Manifestação registrada com sucesso.\n"; } ``` --- ## Tools::sefazDistDFe — Distribuição de DF-e Obtém documentos fiscais eletrônicos de interesse do contribuinte (NF-e recebidas, eventos) a partir do Ambiente Nacional da SEFAZ, usando NSU (Número Sequencial Único). ```php <?php // Busca a partir de um NSU (incrementar a cada consulta) $ultNSU = 0; // Inicia do zero na primeira execução; gravar o último NSU recebido $response = $tools->sefazDistDFe($ultNSU); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if (isset($std->loteDistDFeInt->docZip)) { $docs = is_array($std->loteDistDFeInt->docZip) ? $std->loteDistDFeInt->docZip : [$std->loteDistDFeInt->docZip]; foreach ($docs as $doc) { $xmlDecoded = gzdecode(base64_decode((string)$doc)); $schema = $doc->{'@attributes'}->schema ?? ''; echo "Schema: $schema\n"; // Armazenar $xmlDecoded conforme necessidade } // Gravar o último NSU para próxima consulta $ultimoNSU = $std->loteDistDFeInt->ultNSU; echo "Último NSU: $ultimoNSU\n"; } // Consulta um NSU específico // $response = $tools->sefazDistDFe(0, 123456); // Consulta por chave de acesso // $response = $tools->sefazDistDFe(0, 0, '35240100716345000119550010000010011000000105'); ``` --- ## Tools::sefazInutiliza — Inutilização de numeração Solicita à SEFAZ a inutilização de uma faixa de números de NF-e de uma série, quando esses números não foram utilizados e não serão mais emitidos. ```php <?php try { $nSerie = 1; $nIni = 50; // Número inicial da faixa a inutilizar $nFin = 55; // Número final da faixa a inutilizar $xJust = 'Inutilizacao de numeração por erro no sistema emissor'; $response = $tools->sefazInutiliza($nSerie, $nIni, $nFin, $xJust); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if ($std->cStat == 102) { // Inutilização homologada — protocola e armazena $xmlProtocolado = \NFePHP\NFe\Complements::toAuthorize($tools->lastRequest, $response); echo "Inutilização autorizada.\n"; } else { echo "Falha [{$std->cStat}]: {$std->xMotivo}\n"; } } catch (\InvalidArgumentException $e) { echo "Parâmetros inválidos: " . $e->getMessage() . "\n"; } ``` --- ## Tools::sefazCadastro — Consulta cadastro de contribuinte Consulta os dados cadastrais de um contribuinte (emitente/destinatário) em uma SEFAZ específica. Aceita CNPJ, CPF ou Inscrição Estadual como filtro. ```php <?php try { // Consulta por CNPJ $response = $tools->sefazCadastro('SP', '00716345000119'); // Consulta por IE // $response = $tools->sefazCadastro('SP', '', '111111111111'); // Consulta por CPF // $response = $tools->sefazCadastro('SP', '', '', '12345678901'); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); if ($std->cStat == 111 || $std->cStat == 112) { $infCad = $std->infCons->infCad; echo "Razão Social: {$infCad->xNome}\n"; echo "Situação: {$infCad->xSit}\n"; } } catch (\InvalidArgumentException $e) { echo "Erro: " . $e->getMessage() . "\n"; } ``` --- ## Tools::sefazCsc — Gestão do CSC para NFC-e Gerencia o Código de Segurança do Contribuinte (CSC/Token) necessário para emissão de NFC-e (modelo 65). Permite consultar CSC ativos (1), solicitar novo CSC (2) ou revogar o CSC ativo (3). ```php <?php // Tools deve estar configurada com model('65') $tools->model('65'); try { // 1 = Consultar CSC ativo $response = $tools->sefazCsc(1); // 2 = Solicitar novo CSC // $response = $tools->sefazCsc(2); // 3 = Revogar CSC ativo // $response = $tools->sefazCsc(3); $std = (new \NFePHP\NFe\Common\Standardize($response))->toStd(); echo "cStat: {$std->cStat} - {$std->xMotivo}\n"; } catch (\InvalidArgumentException | \RuntimeException $e) { echo "Erro: " . $e->getMessage() . "\n"; } ``` --- ## Complements::toAuthorize — Protocolação do XML Combina o XML da NF-e (ou evento) com o protocolo de autorização retornado pela SEFAZ, gerando o documento fiscal protocolado (`nfeProc`) pronto para armazenamento e envio ao destinatário. ```php <?php use NFePHP\NFe\Complements; // $requestXml = XML enviado à SEFAZ (tools->lastRequest ou o XML original) // $responseXml = XML de retorno da SEFAZ com o protocolo $xmlProtocolado = Complements::toAuthorize($requestXml, $responseXml); // O XML resultante contém a tag <nfeProc> com a NF-e + protocolo file_put_contents('/storage/nfe/' . $chave . '-nfeProc.xml', $xmlProtocolado); // Para eventos (cancelamento, CC-e, etc.) o resultado contém <procEventoNFe> // Para inutilização o resultado contém <procInutNFe> ``` --- ## Standardize — Conversão de XML de resposta A classe `Standardize` converte os XMLs de resposta da SEFAZ em `stdClass`, array associativo ou JSON, facilitando o acesso programático aos dados retornados. ```php <?php use NFePHP\NFe\Common\Standardize; $std = new Standardize($responseXml); // Identificar o tipo de documento XML $tipo = $std->whichIs(); // Ex: 'retEnviNFe', 'retConsSitNFe', 'retEnvEvento' // Converter para stdClass $obj = $std->toStd(); echo $obj->cStat . ' - ' . $obj->xMotivo . "\n"; // Converter para array associativo $arr = $std->toArray(); echo $arr['cStat'] . "\n"; // Converter para JSON $json = $std->toJson(); $data = json_decode($json, true); echo $data['cStat'] . "\n"; // Validar assinatura e existência de protocolo $valid = $std->validResponseXml($responseXml); ``` --- ## Contingência — Emissão em modo offline A classe `Contingency` gerencia os modos de contingência (SVC-AN, SVC-RS, FS-DA, EPEC, OFF-LINE para NFC-e). Ao ativar, a classe `Tools` ajusta e re-assina automaticamente os XMLs enviados. ```php <?php // Ativar contingência SVC-AN (código 6) para NF-e $contingenciaJson = $tools->contingency->activate('SP', 'Sistema SEFAZ SP indisponível'); // IMPORTANTE: salvar $contingenciaJson na base de dados para persistência // Em instâncias futuras da classe, recarregar o estado de contingência $tools->contingency->load($contingenciaJson); // O envio via sefazEnviaLote() irá automaticamente: // 1. Alterar <tpEmis> para o código do modo de contingência // 2. Inserir <dhCont> e <xJust> // 3. Re-assinar o XML (a chave da NF-e será alterada — gravar a nova chave) $xmlsAlterados = []; $response = $tools->sefazEnviaLote([$xmlOriginal], '001', 0, false, $xmlsAlterados); // $xmlsAlterados contém os XMLs modificados para o modo de contingência // Gravar as novas chaves de acesso foreach ($xmlsAlterados as $xmlMod) { $dom = new DOMDocument(); $dom->loadXML($xmlMod); $novaChave = substr($dom->getElementsByTagName('infNFe')->item(0)->getAttribute('Id'), 3); echo "Nova chave em contingência: $novaChave\n"; } // Desativar a contingência $tools->contingency->deactivate(); ``` --- ## Sumário O sped-nfe cobre todos os casos de uso operacionais de um emissor de documentos fiscais eletrônicos no Brasil: emissão de NF-e (modelo 55) e NFC-e (modelo 65) em ambiente de produção e homologação, envio síncrono e assíncrono, todos os eventos fiscais previstos pela legislação (cancelamento, carta de correção, manifestação do destinatário, EPEC, ator interessado, comprovante de entrega, insucesso de entrega, conciliação financeira), consulta de situação, inutilização de numeração, consulta de cadastro de contribuintes, distribuição de documentos fiscais eletrônicos (DF-e) e gerenciamento completo de contingências (SVC-AN, SVC-RS, FS-DA, EPEC e OFF-LINE). Toda a comunicação com a SEFAZ usa SOAP com certificado digital A1 (PFX), e os XMLs são gerados, assinados e validados contra os schemas XSD oficiais da SEFAZ antes do envio. Em termos de integração, a biblioteca é instalada via Composer e segue namespaces PSR-4 (`NFePHP\NFe\`). O fluxo padrão de integração com um sistema ERP ou PDV consiste em: (1) montar o JSON de configuração e carregar o certificado PFX, instanciando `Tools`; (2) usar `Make` para construir o XML da NF-e/NFC-e programaticamente a partir de dados do sistema; (3) assinar o XML com `Signer` do pacote sped-common; (4) enviar via `sefazEnviaLote` e processar a resposta; (5) protocolar com `Complements::toAuthorize` e armazenar o XML definitivo; (6) converter respostas da SEFAZ com `Standardize` para facilitar a extração de dados. Para impressão do DANFE, use o pacote complementar `nfephp-org/sped-da`; para envio de e-mail fiscal, use `nfephp-org/sped-mail`.