Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Notas Fiscais Laravel Package

danielbbarcelos/laravel-notas-fiscais

Laravel Notas Fiscais is a package by danielbbarcelos that helps Laravel/PHP applications work with Brazilian fiscal notes, offering integration helpers and tooling to issue, query, and manage notas fiscais more easily.

View on GitHub
Deep Wiki
Context7

Getting Started

  • composer require danielbbarcelos/laravel-notas-fiscais then publish config: php artisan vendor:publish --tag=notas-fiscais-config. Everything you need lives in config/notas-fiscais.php — that file is the first place to look, since drivers, certificates and (as of v1.2.0) proxies are all declared there.
  • Read the driver section of the config before writing any code. The package is driver-per-municipality: each entry maps a city/tenant to a driver class and its credentials (CNPJ do prestador, inscrição municipal, certificate path/password, homologação vs. produção).
  • First use case worth wiring up: emit a single NFS-e in homologação for one of your municipalities, synchronously, in a tinker session or an artisan command. Confirm the certificate loads and the municipality responds before you build anything around it.
  • v1.2.0 gives you the reason most integrations stall: some municipalities only accept requests originating from a national IP. If your app runs on a foreign/cloud egress IP, add an http/socks proxy block to that driver's config and the request is tunnelled out through it — no code changes, no separate deployment.

Implementation Patterns

Driver-level proxy is the new lever. The whole point of the feature is that it is per driver, not global. Model it that way:

'drivers' => [
    'prefeitura_x' => [
        'driver' => \Danielbbarcelos\NotasFiscais\Drivers\IssNet::class,
        'proxy'  => [
            'url'      => env('NF_PROXY_URL'),      // http://user:pass@host:port or socks5://...
            'timeout'  => 30,
        ],
    ],
],

Exact key names may differ from the snippet above — verify against the published config and the driver's own docblock before rolling out.

Wrap emission in a queued job. NFS-e endpoints are slow and flaky, and a proxy adds latency on top. A job with $tries, $backoff and a ShouldBeUnique key on (tenant, RPS number) will save you from duplicate notes when a timeout occurs after the municipality has already processed the request.

Multi-tenant runtime switching. If one app serves several municipalities, resolve the driver per tenant rather than per config file: build the config array at runtime and hand it to the driver. Keep proxy settings in a per-tenant column or a secrets store — different tenants will egress through different proxies, some with credentials.

Separate homologação and produção drivers. Give each environment its own driver entry, each with its own proxy if needed. Production proxies are usually IP-whitelisted; you do not want a staging run consuming the same egress IP quota or, worse, emitting to the production endpoint.

Test against a stubbed HTTP layer. Laravel's Http::fake() covers the cases where the driver uses the HTTP client; for SOAP-based drivers, point the WSDL/endpoint at a local fixture. Assert on the outbound request, not just the returned DTO, so you catch a missing or malformed proxy configuration in CI rather than in production.

Log the egress IP on boot. A one-line check against https://ifconfig.me (or the municipality's own echo endpoint) through the configured proxy at deploy time turns "why is the prefeitura returning 403?" into a five-second answer.

Gotchas and Tips

  • The proxy only covers that driver's outbound calls. It does not route your mail, storage, or webhook traffic. If your compliance story says "national IP", that is per request to the municipality, nothing more.
  • HTTPS through a proxy means CONNECT tunnelling, and municipal SOAP clients often use mutual TLS. Verify your proxy allows CONNECT on port 443 and passes the client certificate through untouched. An intercepting/terminating proxy will break certificate-based auth in a way that looks like an authentication failure from the municipality.
  • Whitelist the proxy's egress IP, not your app server's. This is the single most common post-upgrade support ticket: config is correct, proxy works, request still rejected because the municipality still has the old IP on file.
  • Config caching bites. php artisan config:cache after any proxy/env change, and remember that env() calls inside a cached config are resolved at cache time — a per-tenant proxy read via env() at runtime will silently return null.
  • Raise timeouts deliberately. Default HTTP timeouts are usually too tight once a proxy hop is added. Bump connect and total timeouts on the driver, and make sure the queue worker's --timeout exceeds them, or you get killed jobs mid-emission.
  • Debugging order for a rejected request: (1) curl -x $PROXY_URL https://ifconfig.me from the app host, (2) the same through the driver's logger, (3) confirm the driver picked up the proxy config (config('notas-fiscais.drivers.<name>.proxy')), (4) only then look at the municipality's error payload. Steps 1–3 solve almost everything.
  • v1.2.0 is additive. No deprecations, no signature changes — upgrading from v1.1.0 is safe and does nothing until you populate a proxy block. Treat it as a no-op release operationally.
  • Extension points if your driver isn't covered: the proxy is applied at the HTTP-client level, so a custom driver that resolves its client from the container inherits it; one that instantiates its own SOAP client will not. If a driver ignores the setting, wrap the emission in a custom driver that decorates the original and injects the configured client.
  • Don't commit proxy credentials. URL-embedded basic auth ends up in config cache files and stack traces. Keep it in env or a secrets manager and scrub the driver config from logged exceptions.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib