Find your next open-source project

Search by name, purpose, or keyword — or paste a GitHub repository URL

gabrielbuzziv/emissor-nfse-nacional

Finance

Self-hosted NFS-e issuer on Cloudflare Workers that calls Brazil's national NFS-e API directly.

227
36
TypeScript
MIT
1 day old

Emissor de NFS-e Nacional

What it does

This is a self-hosted service that issues Brazilian NFS-e (electronic service invoices) by calling the national NFS-e API directly, with no per-invoice intermediary. It runs on your own Cloudflare account: a Worker receives the sale data over HTTP, stores invoices in a D1 database, and a container signs the XML and talks to the government over mutual TLS using your A1 certificate.

The container exists because the government's servers request the client certificate after the connection is open, which Cloudflare Workers' fetch cannot do. Each request carries a caller-supplied id, so repeating a request returns the same invoice instead of issuing a duplicate; if a government response is lost, it checks whether the invoice was issued before resending. It also cancels invoices, produces DANFSe PDFs (using the government's PDF when available, otherwise generating one from the signed XML with a public-consultation QR code), and creates signed public links for the PDF and XML.

It is aimed at service providers who want invoice issuance inside their own system without paying per note. The README states it already issues invoices in production for a Simples Nacional ME/EPP; MEI and companies outside Simples follow the official layout but have not been tested in production.

Getting started

You need an active municipality in the national system, the provider's A1 e-CNPJ certificate (.pfx plus password), tax details from your accountant, a Cloudflare Workers Paid account, and Node.js 22.12+, pnpm (corepack enable), and Docker running locally.

git clone https://github.com/gabrielbuzziv/emissor-nfse-nacional.git
cd emissor-nfse-nacional
pnpm install
pnpm wrangler login

Fill in the vars in wrangler.jsonc — at minimum NFSE_ENVIRONMENT (start with restricted), ISSUER_CNPJ, ISSUER_CITY_CODE, ISSUER_SIMPLES_OPTION, and the Simples fields where applicable. Then deploy and create the tables:

pnpm run deploy
pnpm run migrate

Send the certificate and create the API token:

pnpm run certificate caminho/do/certificado.pfx
node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"
pnpm wrangler secret put API_TOKEN

Check the installation, including certificate expiry and municipality agreement, with GET /health?deep=1 and the Authorization: Bearer header. Then issue a test note in the restricted environment and verify the returned data before switching NFSE_ENVIRONMENT to production, redeploying, and emitting a real sale. The response carries nfseNumber, accessKey, and links (pdf, xml, lookup); HTTP 200 means issued, 422 rejected, 202 unknown/pending, 400 invalid request.

Constraints

The service covers a common case only: service performed in the provider's municipality with ISSQN due and not withheld; no special tax regime, deductions, discounts, or highlighted federal taxes; takers identified by CPF/CNPJ without address, or no taker; one DPS series and no invoice replacement. Cancellation deadlines vary by municipality, and replacement of a note is not implemented.

Costs include the Cloudflare Workers Paid plan at US$5/month (container pricing) and an annually renewed A1 e-CNPJ certificate. The restricted environment does not include every municipality, so some users cannot test issuance before going live. Government layout changes arrive via technical notes, and src/dps.ts must track them. Keep API_TOKEN server-side only; rotating it invalidates already-sent public links. The project is MIT licensed, not affiliated with the Receita Federal, and tax responsibility stays with the issuer — confirm settings with your accountant. See the national NFS-e portal and technical documentation.

HotRepo's take

The repository was recorded at 101 stars and 14 forks on 2026-11-13, its first day in the new-project ranking, with 101 stars gained in a roughly five-hour window from 2026-11-12T23:02 to 2026-11-13T04:15 UTC. That single snapshot is all the data available, so it supports interest on that day only, not a trend. What stands out technically is the split architecture: the container is there for TLS renegotiation the Workers runtime cannot handle, and the test suite validates documents against official XSDs and checks signatures with xmlsec1 — concrete details that make the project's claims about production use plausible without settling the untested MEI and non-Simples cases.

Written by AI from the project's README, updated . The project's own docs are the source of truth.