PHPackages                             nfe/nfe - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. nfe/nfe

ActiveLibrary[API Development](/categories/api)

nfe/nfe
=======

NFe.io PHP Library

2.5(8y ago)42126.6k—7.2%19[3 issues](https://github.com/nfe/client-php/issues)[1 PRs](https://github.com/nfe/client-php/pulls)MITPHPPHP &gt;=5.4CI passing

Since Jun 9Pushed yesterday10 watchersCompare

[ Source](https://github.com/nfe/client-php)[ Packagist](https://packagist.org/packages/nfe/nfe)[ Docs](https://nfe.io)[ RSS](/packages/nfe-nfe/feed)WikiDiscussions master Synced yesterday

READMEChangelog (3)Dependencies (1)Versions (14)Used By (0)

SDK PHP da NFE.io
=================

[](#sdk-php-da-nfeio)

[![Licença](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)[![Versão PHP](https://camo.githubusercontent.com/19664a7f1b542f0cd67af4ceb3db6caa144c5f2df09922bc3c32c72d80b69d22/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e322d373837434235)](composer.json)[![Última versão estável](https://camo.githubusercontent.com/0aba1b122347a95ff112d43ed7ad3b577b454d1d4f5b1e7627381d76eb6be74c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6e66652f6e66652e737667)](https://packagist.org/packages/nfe/nfe)

SDK PHP oficial da API [NFE.io](https://nfe.io). PHP 8.2+ moderno, zero dependências em runtime, projetado em paridade com o [SDK Node.js](https://github.com/nfe/client-nodejs).

Status
------

[](#status)

LinhaConstraint Composer (`nfe/nfe`)Situaçãov3`^3.0` (atualmente `v3.0.0`)✅ **Estável (GA)** — desenvolvimento na branch canônica `master`v2`^2.0` (congelada em `2.5`)❄️ Congelada — preservada nas branches `v2` / `v2-legacy`, sem novas atualizaçõesA v2 e a v3 compartilham o mesmo slug Packagist (`nfe/nfe`). Composer resolve cada constraint para a major correta automaticamente.

Requisitos
----------

[](#requisitos)

- PHP 8.2, 8.3 ou 8.4
- Extensões: `ext-curl`, `ext-json`, `ext-mbstring`

Instalação
----------

[](#instalação)

```
# v3 estável (atual)
composer require nfe/nfe:^3.0

# v2 legada (congelada)
composer require nfe/nfe:^2.0
```

### Skill para agentes de IA

[](#skill-para-agentes-de-ia)

Além do pacote de código, este repositório publica uma **skill de agente** (`nfeio-php-sdk`) que ensina assistentes de IA (Claude Code, Cursor, Copilot, etc.) a usar o SDK corretamente. São **dois canais distintos**:

CanalComandoO quêCódigo (Composer / Packagist)`composer require nfe/nfe`O SDK PHPSkill de agente ([skills.sh](https://www.skills.sh/))`npx skills add https://github.com/nfe/client-php --skill nfeio-php-sdk`O guia de uso para agentesO atalho `npx skills add nfe/client-php` também funciona. A skill é lida da árvore do GitHub (slug `nfe/client-php`); ela **não** é baixada pelo `composer require` (fica fora do dist via `.gitattributes` `export-ignore`).

Início rápido (API alvo da v3)
------------------------------

[](#início-rápido-api-alvo-da-v3)

```
use Nfe\Client;
use Nfe\Environment;

$nfe = new Client(
    apiKey: $_ENV['NFE_API_KEY'],
    environment: Environment::Production,
);

// Emite uma nota de serviço (NFS-e)
$result = $nfe->serviceInvoices->create($companyId, [
    'borrower' => [
        'federalTaxNumber' => 12345678901234,
        'name'             => 'Cliente exemplo',
        'email'            => 'cliente@example.com',
    ],
    'cityServiceCode'    => '01234',
    'federalServiceCode' => '01.02',
    'description'        => 'Serviço prestado',
    'servicesAmount'     => 1000.00,
]);

if ($result instanceof Nfe\Response\Pending) {
    // 202 — nota está sendo processada de forma assíncrona
    echo "Pendente — invoiceId: {$result->invoiceId()}\n";
} else {
    // 201 — nota emitida imediatamente
    echo "Emitida: {$result->resource()->id}\n";
}
```

Duas chaves de API (emissão vs. serviços de dados)
--------------------------------------------------

[](#duas-chaves-de-api-emissão-vs-serviços-de-dados)

A plataforma NFE.io separa o faturamento entre a API principal (emissão, empresas, webhooks — cobrada por documento) e a API de serviços de dados (consultas de CEP/CNPJ/CPF, query de NF-e/NFC-e — cobrada por consulta, tipicamente um plano separado). Alguns integradores possuem uma única chave com ambos os planos; outros possuem duas chaves distintas.

O SDK aceita as duas. Passe `dataApiKey` quando você tiver uma chave dedicada para serviços de dados; o SDK roteia `addresses`, `legalEntityLookup`, `naturalPersonLookup`, `productInvoiceQuery` e `consumerInvoiceQuery` para ela. Quando `dataApiKey` é omitido, essas chamadas caem por padrão na `apiKey` — mesma cadeia do `resolveDataApiKey()`do SDK Node.

```
$nfe = new Client(
    apiKey:     $_ENV['NFE_API_KEY'],
    dataApiKey: $_ENV['NFE_DATA_API_KEY'] ?? null,
);

// Roteado via apiKey (API principal)
$nfe->serviceInvoices->retrieve($companyId, $invoiceId);

// Roteado via dataApiKey quando definida; senão, via apiKey
$nfe->addresses->lookupByPostalCode('01310-100');
$nfe->legalEntityLookup->getBasicInfo('12.345.678/0001-90');
```

> Se você ver `Nfe\Exception\AuthorizationException` (HTTP 403) em chamadas de consulta, a causa mais provável é que a chave em uso não possui o plano de serviços de dados. Provisione uma `dataApiKey` com o plano de dados e o SDK fará o roteamento automaticamente.

Recursos (paridade com o SDK Node.js)
-------------------------------------

[](#recursos-paridade-com-o-sdk-nodejs)

PropriedadeFamília de endpoints`$nfe->serviceInvoices`NFS-e (nota de serviço)`$nfe->productInvoices`NF-e (nota de produto)`$nfe->consumerInvoices`NFC-e (nota ao consumidor) — emissão + consulta`$nfe->transportationInvoices`CT-e`$nfe->inboundProductInvoices`NF-e de entrada`$nfe->productInvoiceQuery`Consulta de NF-e`$nfe->consumerInvoiceQuery`Consulta de NFC-e`$nfe->companies`Gestão de empresas`$nfe->legalPeople`Pessoa jurídica (PJ)`$nfe->naturalPeople`Pessoa física (PF)`$nfe->webhooks`Configuração de webhooks`$nfe->addresses`Consulta de CEP`$nfe->legalEntityLookup`Consulta de CNPJ`$nfe->naturalPersonLookup`Consulta de CPF`$nfe->taxCalculation`Cálculo de impostos`$nfe->taxCodes`Códigos fiscais (NBS / CNAE)`$nfe->stateTaxes`Inscrição estadualExemplos por recurso
--------------------

[](#exemplos-por-recurso)

Os blocos abaixo cobrem os usos mais comuns de cada família. Os tipos de retorno declarados em cada método são a fonte da verdade — IDEs com PHP 8.2+ resolvem tudo via type hints.

**Notas de Serviço (NFS-e) — `$nfe->serviceInvoices`**```
// Emitir nota (assíncrono — retorna Pending|Issued)
$result = $nfe->serviceInvoices->create($companyId, [
    'borrower' => [
        'federalTaxNumber' => 12345678901,
        'name'             => 'João da Silva',
        'email'            => 'joao@example.com',
    ],
    'cityServiceCode' => '10677',
    'description'     => 'Consultoria',
    'servicesAmount'  => 1500.00,
]);

// Listar com filtros e paginação (pageIndex é 1-based)
$lista = $nfe->serviceInvoices->list($companyId, [
    'pageCount' => 50,
    'pageIndex' => 1,
    'issuedBegin' => '2026-01-01',
    'issuedEnd'   => '2026-01-31',
]);
foreach ($lista->data as $nota) {
    echo "{$nota->id} → {$nota->flowStatus}\n";
}

// Consultar, status, cancelar, reenviar por email
$nota   = $nfe->serviceInvoices->retrieve($companyId, $invoiceId);
$status = $nfe->serviceInvoices->getStatus($companyId, $invoiceId);
$nfe->serviceInvoices->cancel($companyId, $invoiceId);
$nfe->serviceInvoices->sendEmail($companyId, $invoiceId); // envia para o email do tomador

// Baixar PDF e XML (retornam bytes brutos)
file_put_contents('nota.pdf', $nfe->serviceInvoices->downloadPdf($companyId, $invoiceId));
file_put_contents('nota.xml', $nfe->serviceInvoices->downloadXml($companyId, $invoiceId));
```

**Notas de Produto (NF-e) — `$nfe->productInvoices`**Ciclo completo: emissão, listagem, consulta, cancelamento, carta de correção (CC-e) e inutilização de faixa.

```
// Emitir NF-e (assíncrono)
$result = $nfe->productInvoices->create($companyId, [
    'operationNature' => 'Venda de mercadoria',
    'operationType'   => 'Outgoing',
    'buyer' => ['name' => 'Empresa LTDA', 'federalTaxNumber' => 12345678000190],
    'items' => [[
        'code' => 'PROD-001',
        'description' => 'Produto X',
        'quantity' => 1,
        'unitAmount' => 100.00,
    ]],
]);

// Listar (environment obrigatório: Production | Development)
$lista = $nfe->productInvoices->list($companyId, [
    'environment' => 'Production',
    'pageCount'   => 10,
]);

// Carta de correção (CC-e) — razão entre 15 e 1000 caracteres
$nfe->productInvoices->sendCorrectionLetter(
    $companyId,
    $invoiceId,
    'Correcao do endereco do destinatario conforme novo cadastro',
);

// Inutilizar faixa de numeração
$nfe->productInvoices->disableRange($companyId, [
    'environment' => 'Production',
    'serie'       => 1,
    'state'       => 'SP',
    'beginNumber' => 100,
    'lastNumber'  => 110,
]);

// Downloads
$pdf = $nfe->productInvoices->downloadPdf($companyId, $invoiceId);
$xml = $nfe->productInvoices->downloadXml($companyId, $invoiceId);
$ccePdf = $nfe->productInvoices->downloadCorrectionLetterPdf($companyId, $invoiceId);
```

> Emissão, cancelamento, CC-e e inutilização são assíncronos (HTTP 202/204). A conclusão chega via webhook.

**Notas ao Consumidor (NFC-e) — `$nfe->consumerInvoices`**NFC-e segue o mesmo padrão de NF-e (emissão assíncrona, downloads, cancelamento, inutilização).

```
$result = $nfe->consumerInvoices->create($companyId, $payload);
$lista  = $nfe->consumerInvoices->list($companyId, ['environment' => 'Production']);
$nota   = $nfe->consumerInvoices->retrieve($companyId, $invoiceId);
$nfe->consumerInvoices->cancel($companyId, $invoiceId);

// Downloads (retornam bytes)
file_put_contents('nfce.pdf', $nfe->consumerInvoices->downloadPdf($companyId, $invoiceId));
file_put_contents('nfce.xml', $nfe->consumerInvoices->downloadXml($companyId, $invoiceId));

// Inutilizar faixa
$nfe->consumerInvoices->disableRange($companyId, [
    'environment' => 'Production',
    'serie'       => 1,
    'state'       => 'SP',
    'beginNumber' => 1000,
    'lastNumber'  => 1010,
]);
```

**CT-e — `$nfe->transportationInvoices`**Consulta de CT-e via Distribuição DFe. Requer certificado A1 válido na empresa.

```
// Ativar busca automática
$settings = $nfe->transportationInvoices->enable($companyId, [
    'startFromNsu' => 12345, // opcional
]);

// Verificar configuração atual / desativar
$config = $nfe->transportationInvoices->getSettings($companyId);
$nfe->transportationInvoices->disable($companyId);

// Consultar CT-e por chave (44 dígitos)
$accessKey = '35240112345678000190570010000001231234567890';
$cte = $nfe->transportationInvoices->retrieve($companyId, $accessKey);
echo "Remetente: {$cte->nameSender}, valor: {$cte->totalInvoiceAmount}";

// Baixar XML
file_put_contents('cte.xml',
    $nfe->transportationInvoices->downloadXml($companyId, $accessKey),
);

// Evento + XML do evento
$evento = $nfe->transportationInvoices->getEvent($companyId, $accessKey, $eventKey);
$eventoXml = $nfe->transportationInvoices->downloadEventXml($companyId, $accessKey, $eventKey);
```

**NF-e de Entrada (Distribuição) — `$nfe->inboundProductInvoices`**Recebe NF-e emitidas contra a empresa via Distribuição DFe.

```
// Ativar busca automática
$nfe->inboundProductInvoices->enableAutoFetch($companyId, [
    'environmentSEFAZ' => 'Production',
    'webhookVersion'   => '2',
]);

// Consultar NF-e por chave (formato webhook v2 — recomendado)
$accessKey = '35240112345678000190550010000001231234567890';
$nota = $nfe->inboundProductInvoices->getProductInvoiceDetails($companyId, $accessKey);
echo "Emissor: {$nota['issuer']['name']}";

// Baixar XML, PDF (DANFE) e JSON
file_put_contents('nfe.xml', $nfe->inboundProductInvoices->getXml($companyId, $accessKey));
file_put_contents('nfe.pdf', $nfe->inboundProductInvoices->getPdf($companyId, $accessKey));
$json = $nfe->inboundProductInvoices->getJson($companyId, $accessKey);

// Manifestação (Ciência da Operação por padrão = 210210)
$nfe->inboundProductInvoices->manifest($companyId, $accessKey);
$nfe->inboundProductInvoices->manifest($companyId, $accessKey, 210220); // Confirmação da Operação

// Reprocessar um webhook entregue
$nfe->inboundProductInvoices->reprocessWebhook($companyId, $accessKey);
```

CódigoEvento de manifestação`210210`Ciência da Operação (padrão)`210220`Confirmação da Operação`210240`Operação não Realizada**Consulta de NF-e na SEFAZ — `$nfe->productInvoiceQuery`**Consulta NF-e diretamente na SEFAZ pela chave de acesso. Read-only, sem escopo de empresa. Usa `dataApiKey` quando configurada.

```
$accessKey = '35240112345678000190550010000001231234567890';

$nota   = $nfe->productInvoiceQuery->retrieve($accessKey);
$pdf    = $nfe->productInvoiceQuery->downloadPdf($accessKey);
$xml    = $nfe->productInvoiceQuery->downloadXml($accessKey);
$eventos = $nfe->productInvoiceQuery->listEvents($accessKey);
```

**Consulta de CFe-SAT / NFC-e na SEFAZ — `$nfe->consumerInvoiceQuery`**```
$accessKey = '35240112345678000190590000000012341234567890';

$cupom = $nfe->consumerInvoiceQuery->retrieve($accessKey);
file_put_contents('cfe.xml', $nfe->consumerInvoiceQuery->downloadXml($accessKey));
```

**Empresas — `$nfe->companies`**```
// CRUD
$empresa = $nfe->companies->create([
    'federalTaxNumber' => 12345678000190,
    'name'             => 'Minha Empresa LTDA',
    'email'            => 'empresa@example.com',
    // ... endereço, regime tributário, etc.
]);

$lista     = $nfe->companies->list();
$todas     = $nfe->companies->listAll(); // sem paginação — itera tudo
$empresa   = $nfe->companies->retrieve($companyId);
$atualizada = $nfe->companies->update($companyId, ['email' => 'novo@example.com']);
$nfe->companies->remove($companyId);

// Buscas
$empresa = $nfe->companies->findByTaxNumber('12345678000190');
$matches = $nfe->companies->findByName('Minha Empresa');

// Certificado A1
$status = $nfe->companies->getCertificateStatus($companyId);
if ($status->hasCertificate && $status->isExpiringSoon) {
    echo "Expira em {$status->daysUntilExpiration} dia(s)\n";
}

// Painel de certificados (filtros prontos)
$comCert     = $nfe->companies->getCompaniesWithCertificates();
$expirando   = $nfe->companies->getCompaniesWithExpiringCertificates(thresholdDays: 30);
```

**Pessoas (PJ e PF) — `$nfe->legalPeople` / `$nfe->naturalPeople`**Ambos os recursos têm a mesma forma. Exemplo com PJ:

```
$pj = $nfe->legalPeople->create($companyId, [
    'federalTaxNumber' => '12345678000190',
    'name'             => 'Cliente PJ',
    'email'            => 'pj@example.com',
]);

$lista     = $nfe->legalPeople->list($companyId);
$pj        = $nfe->legalPeople->retrieve($companyId, $legalPersonId);
$atualizada = $nfe->legalPeople->update($companyId, $legalPersonId, ['email' => 'novo@x.com']);
$nfe->legalPeople->delete($companyId, $legalPersonId);

// Buscar por documento
$pj = $nfe->legalPeople->findByTaxNumber($companyId, '12345678000190');

// Criação em lote
$nfe->legalPeople->createBatch($companyId, [
    ['federalTaxNumber' => '11111111000111', 'name' => 'PJ 1', 'email' => 'a@x.com'],
    ['federalTaxNumber' => '22222222000122', 'name' => 'PJ 2', 'email' => 'b@x.com'],
]);
```

Para pessoas físicas (`$nfe->naturalPeople`), troque `federalTaxNumber` (CPF de 11 dígitos) e use os mesmos métodos.

**Inscrições Estaduais — `$nfe->stateTaxes`**Necessário para emitir NF-e de produto.

```
$lista = $nfe->stateTaxes->list($companyId);

$ie = $nfe->stateTaxes->create($companyId, [
    'taxNumber'       => '123456789',
    'serie'           => 1,
    'number'          => 1,
    'code'            => 'SP',
    'environmentType' => 'production',
    'type'            => 'nFe',
]);

$ie = $nfe->stateTaxes->retrieve($companyId, $stateTaxId);
$nfe->stateTaxes->update($companyId, $stateTaxId, ['serie' => 2]);
$nfe->stateTaxes->delete($companyId, $stateTaxId);
```

**Consulta de CEP — `$nfe->addresses`**```
// Por CEP (8 dígitos, com ou sem hífen). O host address.api.nfe.io/v2
// suporta apenas consulta por CEP.
$resultado = $nfe->addresses->lookupByPostalCode('01310-100');
foreach ($resultado->addresses as $end) {
    echo "{$end['street']}, {$end['city']['name']}/{$end['state']}\n";
}
```

**Consulta de CNPJ — `$nfe->legalEntityLookup`**```
// Dados cadastrais (Receita Federal)
$result = $nfe->legalEntityLookup->getBasicInfo('12.345.678/0001-90');
$pj = $result->legalEntity;
echo "Razão Social: {$pj['name']}, Status: {$pj['status']}";

// Com opções (atualizar endereço/código IBGE via Correios)
$result = $nfe->legalEntityLookup->getBasicInfo('12345678000190', [
    'updateAddress'  => false,
    'updateCityCode' => true,
]);

// IE por estado
$ieSP = $nfe->legalEntityLookup->getStateTaxInfo('SP', '12345678000190');

// Avaliar IE para emissão de nota
$avaliacao = $nfe->legalEntityLookup->getStateTaxForInvoice('MG', '12345678000190');

// Melhor IE sugerida
$sugestao = $nfe->legalEntityLookup->getSuggestedStateTaxForInvoice('SP', '12345678000190');
```

**Consulta de CPF — `$nfe->naturalPersonLookup`**```
// CPF + data de nascimento (string YYYY-MM-DD ou DateTimeImmutable)
$result = $nfe->naturalPersonLookup->getStatus('123.456.789-01', '1990-01-15');
echo "Nome: {$result->name}, Situação: {$result->status}";

// DateTimeImmutable também funciona
$result = $nfe->naturalPersonLookup->getStatus(
    '12345678901',
    new DateTimeImmutable('1990-01-15'),
);
```

**Cálculo de Impostos — `$nfe->taxCalculation`**Engine de cálculo ICMS / ICMS-ST / PIS / COFINS / IPI / II.

```
$resultado = $nfe->taxCalculation->calculate($tenantId, [
    'operationType' => 'Outgoing',
    'issuer'    => ['state' => 'SP', 'taxRegime' => 'RealProfit'],
    'recipient' => ['state' => 'RJ'],
    'items' => [[
        'id'            => 'item-1',
        'operationCode' => 121,
        'origin'        => 'National',
        'ncm'           => '61091000',
        'quantity'      => 10,
        'unitAmount'    => 100.00,
    ]],
]);

foreach ($resultado['items'] ?? [] as $item) {
    echo "Item {$item['id']}: CFOP={$item['cfop']}\n";
    echo "  ICMS: CST={$item['icms']['cst']}, valor={$item['icms']['vICMS']}\n";
}
```

**Códigos auxiliares — `$nfe->taxCodes`**```
$operacoes        = $nfe->taxCodes->listOperationCodes(['pageIndex' => 1, 'pageCount' => 20]);
$finalidades      = $nfe->taxCodes->listAcquisitionPurposes();
$perfisEmissor    = $nfe->taxCodes->listIssuerTaxProfiles();
$perfisDestinatario = $nfe->taxCodes->listRecipientTaxProfiles();

foreach ($operacoes->items as $cod) {
    echo "{$cod['code']} — {$cod['description']}\n";
}
```

Webhooks
--------

[](#webhooks)

### Configurar um webhook

[](#configurar-um-webhook)

```
$webhook = $nfe->webhooks->create($companyId, [
    'url'    => 'https://meuapp.com.br/api/webhooks/nfe',
    'events' => ['invoice.issued', 'invoice.cancelled', 'invoice.error'],
    'active' => true,
]);

// Listar / atualizar / remover / testar
$lista = $nfe->webhooks->list($companyId);
$nfe->webhooks->update($companyId, $webhookId, ['events' => ['invoice.issued']]);
$nfe->webhooks->delete($companyId, $webhookId);
$nfe->webhooks->test($companyId, $webhookId);

// Listar eventos suportados pela API
$eventos = $nfe->webhooks->getAvailableEvents();
```

### Verificar assinatura no endpoint

[](#verificar-assinatura-no-endpoint)

O SDK fornece um helper estático alinhado ao esquema canônico usado pela NFE.io (HMAC-SHA1 sobre `X-Hub-Signature`):

```
use Nfe\Webhook;
use Nfe\Exception\SignatureVerificationException;

try {
    $event = Webhook::constructEvent(
        payload:   file_get_contents('php://input'),
        sigHeader: $_SERVER['HTTP_X_HUB_SIGNATURE'] ?? '',
        secret:    $_ENV['NFE_WEBHOOK_SECRET'],
    );
    // $event é um WebhookEvent tipado: $event->type, $event->data, $event->id, $event->createdAt
} catch (SignatureVerificationException $e) {
    http_response_code(403);
    exit;
}

// Roteamento por tipo de evento
match ($event->type) {
    'invoice.issued'    => emitidaHandler($event->data),
    'invoice.cancelled' => canceladaHandler($event->data),
    'invoice.error'     => erroHandler($event->data),
    default             => null,
};

http_response_code(200);
```

Polling (manual na v3.0)
------------------------

[](#polling-manual-na-v30)

Para emissão assíncrona de notas (HTTP 202), a v3.0 retorna uma resposta discriminada `Pending | Issued`. Um helper `pollUntilComplete()` chegará em uma release 3.x posterior; até lá, faça o loop manualmente em um worker/CLI:

```
use Nfe\Util\FlowStatus;

$result = $nfe->serviceInvoices->create($companyId, $data);

if ($result instanceof Nfe\Response\Pending) {
    $invoiceId = $result->invoiceId();
    do {
        sleep(2);
        $invoice = $nfe->serviceInvoices->retrieve($companyId, $invoiceId);
    } while (!FlowStatus::isTerminal($invoice->flowStatus));
}
```

`FlowStatus::TERMINAL` lista os quatro estados terminais (`Issued`, `IssueFailed`, `Cancelled`, `CancelFailed`). Espelha `TERMINAL_FLOW_STATES` do SDK Node.

Tratamento de erros
-------------------

[](#tratamento-de-erros)

Toda resposta não-2xx é mapeada para uma exceção tipada que estende `Nfe\Exception\ApiErrorException`. Capture a classe base para um handler genérico, ou a subclasse para uma recuperação direcionada:

HTTPExceçãoCausa típica400`InvalidRequestException`Payload mal formado, falha de validação401`AuthenticationException`Chave de API ausente ou inválida403`AuthorizationException`Chave válida, mas o plano/escopo recusa a ação (ex.: requer chave de serviços de dados)404`NotFoundException`Recurso não existe429`RateLimitException`Throttling — consulte `Retry-After`5xx`ServerException`Falha na infraestrutura upstream / NFE.io—`ApiConnectionException`Falha de rede, DNS, TLS, timeout—`SignatureVerificationException`Assinatura do payload do webhook não confere```
use Nfe\Exception\ApiErrorException;
use Nfe\Exception\AuthorizationException;
use Nfe\Exception\RateLimitException;

try {
    $nfe->addresses->lookupByPostalCode($cep);
} catch (AuthorizationException $e) {
    // 403 — chave provavelmente sem o plano de serviços de dados
    error_log("Consulta negada: {$e->getMessage()}");
} catch (RateLimitException $e) {
    // Consulte $e->responseHeaders['retry-after']
    throw $e;
} catch (ApiErrorException $e) {
    // Qualquer outra resposta não-2xx
    error_log("Erro na API {$e->statusCode}: {$e->getMessage()}");
}
```

Cada exceção expõe `$statusCode`, `$responseBody`, `$responseHeaders` e `$errorCode` para diagnóstico.

Opções de configuração avançadas
--------------------------------

[](#opções-de-configuração-avançadas)

Quando você precisa de mais controle (timeout, retry, transporte customizado, logger), construa um `Config` explícito:

```
use Nfe\Client;
use Nfe\Config;
use Nfe\Environment;
use Nfe\Http\RetryPolicy;
use Psr\Log\LoggerInterface;

$config = new Config(
    apiKey:     $_ENV['NFE_API_KEY'],
    dataApiKey: $_ENV['NFE_DATA_API_KEY'] ?? null,
    environment: Environment::Production,
    timeout: 60, // segundos
    retry: new RetryPolicy(
        maxRetries: 3,
        baseDelay: 1.0,  // segundos
        maxDelay: 30.0,  // segundos
        jitter: 0.3,     // ±30%
    ),
    logger: $myPsr3Logger,            // opcional, qualquer LoggerInterface
    transport: $myCustomTransport,    // opcional, ex.: adaptador PSR-18
    userAgentSuffix: 'MeuApp/1.2.3',  // sufixo identificador no User-Agent
);

$nfe = new Client(config: $config);
```

CampoPadrãoDescrição`apiKey`obrigatórioChave principal (emissão, empresas, webhooks).`dataApiKey``null`Chave separada para serviços de dados. Quando `null`, faz fallback para `apiKey`.`environment``Production``Production` ou `Sandbox`.`timeout``60`Timeout HTTP por requisição (segundos).`retry``new RetryPolicy()`Backoff exponencial com jitter simétrico. Use `RetryPolicy::none()` para desabilitar.`transport``CurlTransport`Implementação de `Nfe\Http\Transport` (ex.: adaptador PSR-18).`logger``null`Qualquer `Psr\Log\LoggerInterface`. PSR-3 **não** é dependência em runtime.`userAgentSuffix``null`Identificador do integrador (ex.: `WHMCS/8.10`).### Override por chamada

[](#override-por-chamada)

`RequestOptions` sobrescreve `apiKey`, `baseUrl` e `timeout` em uma chamada específica — útil em integrações multi-tenant:

```
use Nfe\Http\RequestOptions;

$nota = $nfe->serviceInvoices->retrieve(
    $companyId,
    $invoiceId,
    options: new RequestOptions(apiKey: $chaveDoCliente, timeout: 120),
);
```

Variáveis de ambiente
---------------------

[](#variáveis-de-ambiente)

O SDK **não lê variáveis de ambiente automaticamente** — você passa as chaves no construtor. Convenção sugerida (compatível com o SDK Node):

VariávelUso`NFE_API_KEY`Chave principal.`NFE_DATA_API_KEY`Chave separada para CEP/CNPJ/CPF/NF-e query.`NFE_WEBHOOK_SECRET`Segredo HMAC do webhook.```
$nfe = new Client(
    apiKey:     getenv('NFE_API_KEY') ?: throw new RuntimeException('NFE_API_KEY ausente'),
    dataApiKey: getenv('NFE_DATA_API_KEY') ?: null,
);
```

Migrando da v2
--------------

[](#migrando-da-v2)

Veja [MIGRATION.md](MIGRATION.md) para o mapeamento completo v2 → v3. Não há retrocompatibilidade — a v3 é uma reescrita limpa.

Contribuindo
------------

[](#contribuindo)

Veja [CONTRIBUTING.md](CONTRIBUTING.md).

Licença
-------

[](#licença)

MIT — veja [LICENSE](LICENSE).

###  Health Score

53

—

FairBetter than 96% of packages

Maintenance64

Regular maintenance activity

Popularity46

Moderate usage in the ecosystem

Community23

Small or concentrated contributor base

Maturity65

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~306 days

Recently: every ~752 days

Total

13

Last Release

2d ago

Major Versions

1.0.2 → 2.02016-07-20

v2.x-dev → v3.0.0-rc.12026-06-30

PHP version history (3 changes)1.0.0PHP &gt;=5.2

2.0PHP &gt;=5.4

v3.0.0-rc.1PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/8da225a4adeb6ed39799b29c93fbe8de0da5d5f8598506bd2526454470c946bd?d=identicon)[gblmarquez](/maintainers/gblmarquez)

![](https://www.gravatar.com/avatar/fb8e76b7d55436a3f0d26a2de9ef8c1991679bace3abfc7027efaca8c844e640?d=identicon)[andrenfe](/maintainers/andrenfe)

---

Top Contributors

[![andrenfe](https://avatars.githubusercontent.com/u/274840925?v=4)](https://github.com/andrenfe "andrenfe (40 commits)")[![renatonascalves](https://avatars.githubusercontent.com/u/19148962?v=4)](https://github.com/renatonascalves "renatonascalves (31 commits)")[![gblmarquez](https://avatars.githubusercontent.com/u/367279?v=4)](https://github.com/gblmarquez "gblmarquez (9 commits)")[![luismallozzi](https://avatars.githubusercontent.com/u/4340446?v=4)](https://github.com/luismallozzi "luismallozzi (2 commits)")[![lnmunhoz](https://avatars.githubusercontent.com/u/4376835?v=4)](https://github.com/lnmunhoz "lnmunhoz (1 commits)")[![Leuloch](https://avatars.githubusercontent.com/u/5075742?v=4)](https://github.com/Leuloch "Leuloch (1 commits)")[![yagosenhorini](https://avatars.githubusercontent.com/u/14964398?v=4)](https://github.com/yagosenhorini "yagosenhorini (1 commits)")

---

Tags

apibrazilcomposere-invoicefiscalinvoicenfenfsenfse-nacionalnota-fiscalnota-fiscal-de-serviconota-fiscal-eletronicapackagistphpsdkapinfenota fiscalnfsenotanfe.io

### Embed Badge

![Health badge](/badges/nfe-nfe/health.svg)

```
[![Health](https://phpackages.com/badges/nfe-nfe/health.svg)](https://phpackages.com/packages/nfe-nfe)
```

###  Alternatives

[webmaniabr/nfe

PHP SDK da REST API de Nota Fiscal Eletrônica da WebmaniaBR®

1310.3k](/packages/webmaniabr-nfe)[m165437/laravel-blueprint-docs

API Blueprint Renderer for Laravel

22879.8k](/packages/m165437-laravel-blueprint-docs)[nfephp-org/sped-nfse-ginfes

API para geração e comunicação de RPS e NFSe no padão Ginfes.

445.9k](/packages/nfephp-org-sped-nfse-ginfes)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
