laravel-nfe maintained by voopenp
voopenp/laravel-nfe
Emissão de NF-e (modelo 55) e NFC-e (modelo 65) direto na SEFAZ para aplicações Laravel, usando sped-nfe.
- Montagem e validação do XML (layout 4.00), assinatura com certificado A1 e envio síncrono, com reconsulta de recibo quando a SEFAZ demora.
- Numeração por modelo + série + ambiente segura sob concorrência, reaproveitando números de notas rejeitadas/erro da mesma referência.
- Rateio de desconto entre os itens com fechamento exato dos totais.
- Cancelamento (evento) e reconsulta de status pela chave.
- Histórico no model
NfeNota(rascunho/autorizada/processando/rejeitada/cancelada/erro). - DANFE/DANFCE em PDF via Blade + dompdf, com QR code da NFC-e embutido (sped-da conflita com tc-lib-barcode 2.x).
Escopo: venda presencial a consumidor final, pagamento à vista, sem frete, PIS/COFINS CST 49 sem valor. ICMS por CSOSN (CRT 1/4) ou CST com alíquota simples (CRT 2/3).
Instalação
composer require voopenp/laravel-nfe
php artisan vendor:publish --tag=nfe-migrations
php artisan migrate
O service provider é registrado por auto-discovery. Em aplicações multi-tenant (ex.: stancl/tenancy), mova a migration publicada para o diretório de migrations do tenant.
Config e views são publicáveis com as tags nfe-config e nfe-views.
Uso
1. Implemente o NfeConfigProvider
Único ponto obrigatório: diz ao pacote quem emite, com qual certificado e em qual ambiente.
use Voope\Nfe\Contracts\NfeConfigProvider;
use Voope\Nfe\Data\{Emitente, CertificadoA1, Csc};
use Voope\Nfe\Exceptions\NfeException;
class MeuNfeProvider implements NfeConfigProvider
{
public function habilitado(): bool
{
return true;
}
public function ambiente(): int
{
return 2; // 1 produção, 2 homologação
}
public function emitente(): Emitente
{
return new Emitente(
razaoSocial: 'EMPRESA LTDA',
cnpj: '00000000000000',
ie: '0000000000',
crt: 1, // 1 Simples, 2 sublimite, 3 normal, 4 MEI
codigoMunicipio: '4314902', // IBGE, 7 dígitos
logradouro: 'Rua Tal',
numero: '100',
bairro: 'Centro',
cidade: 'Porto Alegre',
cep: '90000000',
fone: '5133330000',
email: 'fiscal@empresa.com.br',
);
}
public function certificado(): CertificadoA1
{
$raw = file_get_contents($caminhoDoPfx);
if ($raw === false) {
throw new NfeException('Certificado digital não encontrado.');
}
return new CertificadoA1($raw, $senha);
}
public function certificadoConfigurado(): bool
{
return $caminhoDoPfx !== '' && $senha !== '';
}
public function csc(): ?Csc
{
return $id && $token ? new Csc($id, $token) : null; // exigido só para NFC-e
}
public function serie(int $modelo): int
{
return 1;
}
}
Registre no container:
$this->app->bind(NfeConfigProvider::class, MeuNfeProvider::class);
2. Emita a partir do seu domínio
use Voope\Nfe\NfeService;
use Voope\Nfe\Data\{Nota, Item, Pagamento, Destinatario};
$nota = app(NfeService::class)->emitir(new Nota(
modelo: 65,
itens: [
new Item(
descricao: 'Produto X',
quantidade: 2,
valorUnitario: 49.90,
codigo: 'SKU-1',
ncm: '93062100',
csosn: '102',
),
],
pagamento: new Pagamento(tPag: '17'), // tpIntegra=2 automático p/ cartão e pix
destinatario: new Destinatario(cpfCnpj: '00000000000', nome: 'Fulano'),
desconto: 5.00,
referencia: $venda->id, // vínculo livre com o seu domínio
));
$nota->status; // autorizada / rejeitada / processando / erro
$nota->chave;
$nota->danfe_path; // PDF no disco configurado
Cancelamento, reconsulta e checklist
app(NfeService::class)->cancelar($nota, 'Justificativa com no mínimo 15 caracteres');
app(NfeService::class)->consultar($nota);
// para telas de configuração; nunca lança exceção
app(NfeService::class)->checklist();
// ['cert' => true, 'cnpj' => true, ..., 'baseOk' => true, 'nfceOk' => false, 'emProducao' => false]
Utilitário de QR code (data URI PNG): Voope\Nfe\Support\QrCode::dataUri($texto).
Configuração (config/nfe.php)
| chave | uso |
|---|---|
ver_proc |
nome do aplicativo emissor gravado na tag verProc |
token_ibpt |
token IBPT opcional |
resp_tec.* |
responsável técnico (NT2018.005); vazio usa o emitente |
storage.disk / storage.path |
onde os PDFs são gravados ({path}/{modelo}/{chave}.pdf) |
table |
tabela do histórico (nfe_notas) |
views.danfe / views.danfce |
views usadas nos PDFs |
schemes / versao |
pacote de schemas e versão do layout |
Requisitos
- PHP >= 8.1 com ext-openssl e ext-soap (exigência do sped-nfe)
- Laravel 10, 11 ou 12
- Certificado digital A1 (.pfx)
Licença
AGPL-3.0-or-later. Quem usar este pacote num sistema acessado pela rede precisa disponibilizar o código-fonte completo do sistema aos usuários.