NFS-e or a simple receipt? How to decide what your software should generate
The question is not "which document is better" — it is who has the tax obligation. Answer that and the engineering follows in about five minutes.
This comes up constantly in products that touch Brazilian money: a marketplace paying sellers, a freelance platform, a SaaS billing local customers, a payroll tool handling contractors. Someone asks "do we need to generate notas fiscais?" and the team either overbuilds a fiscal integration they did not need, or ships a PDF that leaves their users non-compliant.
Both mistakes come from skipping one question.
This page assumes you know roughly what the document types are. If not, the taxonomy page covers NF-e, NFS-e, NFC-e, fatura, duplicata, recibo and boleto — who issues each and which ones software can produce at all. And if the answer turns out to be "a receipt", what a recibo must contain is the practical follow-up.
This page explains how the documents differ from a software engineer's point of view, so you can model them correctly. It is not advice about your obligations. Brazilian tax rules vary by municipality, by activity code and by tax regime, and they are changing through the current reform. Before you decide what your company must issue, talk to a Brazilian accountant (contador).
The question that decides everything
An NFS-e is issued by the service provider, using their CNPJ and their digital certificate, through their municipality's system. If the provider is your user rather than your own company, you are not the party with the obligation — and you cannot discharge it for them without holding their credentials.
A recibo has no issuing authority at all. It is a private document evidencing that money changed hands. Anyone can produce one, including a platform on behalf of a payment it actually made.
Run it through this
Is a service being provided by a Brazilian entity that must issue a nota fiscal?
│
├─ NO ─────────────────────────────────────────────────────────────────────┐
│ (a refund, an internal transfer, a payment to a foreign supplier, │
│ a deposit, a platform fee you charge your own user) │
│ v
│ A RECIBO is the right artefact.
│ Buildable today. No certificate.
│
└─ YES
│
├─ Is the provider YOUR OWN company?
│ │
│ ├─ YES ──> You must issue the NFS-e. That means a municipal
│ │ integration with your ICP-Brasil certificate — either
│ │ a Brazilian fiscal-integration provider, or direct
│ │ integration with your city's system.
│ │ You will ALSO want a fatura for the commercial side.
│ │
│ └─ NO, the provider is a USER of my platform
│ │
│ └─> You CANNOT issue it for them (no certificate, no standing).
│ What you CAN do, and what good platforms do:
│ 1. Issue a RECIBO / payout statement for the money you paid.
│ 2. Give the user the data they need to issue their own NFS-e.
│ 3. Optionally, let them upload theirs and track compliance.The four situations, concretely
1. Marketplace or platform paying Brazilian sellers
You transfer money to a seller. The seller renders the service and owes the nota fiscal — to the buyer, and sometimes to you for the commission relationship. Your correct artefact is a payout statement or recibo: what was paid, for which orders, gross, fees, net, when.
What mature platforms add on top: exposing each payout's data in a form the seller can copy into their own NFS-e, and a place to store the nota fiscal number once issued. What they do not do is generate the seller's nota fiscal.
2. Your own Brazilian company selling services
You need the NFS-e, full stop. Budget for it as an integration project, not a PDF feature: a certificate (an e-CNPJ A1 file is the practical choice for servers — A3 tokens do not virtualize well), a municipality with its own schema and authentication, service codes for your activity, ISS rates and withholding rules, plus cancellation and correction flows.
The pragmatic route is a Brazilian fiscal-integration provider that abstracts the municipal differences. Even then, expect the certificate handling, the service-code mapping and the edge cases to be real work. Separately, you will still want a readable fatura to send the customer — the NFS-e is a tax record, not a billing document your customer enjoys reading.
3. Foreign company billing Brazilian customers
You are generally outside the issuance system: the municipal and state systems are built around Brazilian-registered entities. A commercial invoice is the norm, and it is worth making it look local — amounts in BRL if you bill in BRL, DD/MM/YYYY dates, the customer's CNPJ printed and correct.
Your customer may still have obligations on their side (withholding, import-of-services treatment). That is their accountant's call, and no document you generate changes it. What you can do is make their bookkeeping easy: correct CNPJ, clear description, clear currency.
4. Paying individual freelancers directly
An individual (pessoa física) providing services may fall under different rules from a company, and an autônomo may need a municipal document (or an RPA-style flow) depending on the city and the arrangement. This is genuinely case-specific, and it is the scenario where guessing has bitten the most teams. A recibo documents the payment; whether it is sufficient is a question for an accountant.
Cost comparison, honestly
| Recibo / fatura PDF | NFS-e integration | |
|---|---|---|
| Legal weight | Private evidence of payment or billing | Official tax document |
| Digital certificate | Not needed | Required (e-CNPJ A1 or A3) |
| Who can issue | Anyone | Only the registered service provider |
| Build effort | Hours — one HTTP call, or a PDF library | Weeks, and ongoing maintenance |
| Per-municipality variation | None | Historically the dominant cost; converging under the national standard |
| Failure mode | An ugly PDF | A blocked transaction, or a compliance problem |
| Cancellation flow | Delete the file | A regulated procedure with deadlines |
The asymmetry is the point: these are not competing options at similar cost. If a recibo satisfies the requirement, building an NFS-e integration is a large amount of work bought for nothing. If it does not, no amount of PDF polish substitutes.
Designing so you are not trapped later
Whichever you need today, keep two things separate in your data model:
- The transaction record — parties, line items, amounts, dates, tax identifiers. This is yours and it is stable.
- The documents derived from it — zero or more, each with a type
(
recibo,fatura,nfse), a status, and a reference (a file, or an authorization key).
-- Transactions are yours. Documents are artefacts derived from them.
create table documents (
id uuid primary key,
transaction_id uuid not null references transactions(id),
kind text not null check (kind in ('recibo','fatura','nfse','nfe')),
status text not null default 'issued', -- issued | authorized | cancelled
-- Commercial documents: where the PDF lives.
file_path text,
-- Fiscal documents: the authority's key. NULL for recibo/fatura, by design.
access_key text,
authorized_at timestamptz,
issued_at timestamptz not null default now()
);
create index on documents (transaction_id, kind);With that shape, adding an NFS-e integration later inserts rows of a new kind instead of
rewriting your billing model. And the reverse holds: if you start with the fiscal integration, adding a
human-readable fatura is a new row, not a migration.
Validate every CPF/CNPJ you store, at input time, with the local check-digit algorithm. It costs nothing and it is the single highest-yield data-quality measure in any Brazilian billing system — a wrong tax ID is invisible until the moment it blocks a fiscal document, months later. See the check-digit guide.
Summary
- The deciding question is who owes the tax obligation, not which document looks more official.
- If the obligation belongs to your user, you cannot discharge it — issue a recibo for the money you moved, and hand them the data for their own NFS-e.
- If it belongs to your own company, budget a real integration; a PDF is not a substitute.
- Model transactions and documents separately so today's answer does not become tomorrow's migration.
- Confirm the specifics with a Brazilian accountant. This page helps you ask better questions, not skip the conversation.
Frequently asked questions
Can I issue an NFS-e for my platform's sellers?
No. The NFS-e must be issued by the service provider, signed with their digital certificate, in their municipality. Without their credentials you have no standing to issue it — and holding sellers' certificates is a liability most platforms decline. Issue a recibo or payout statement for the money you actually paid, and expose the data they need for their own document.
Is a recibo legally valid in Brazil?
It is a valid private document evidencing that a payment was made and received — commonly used and generally accepted as such. What it is not is a substitute for a nota fiscal when one is required by the transaction. The two do different jobs.
How long does an NFS-e integration take?
Weeks rather than days, plus ongoing maintenance. The classic cost driver was per-municipality variation, which the national standard is reducing, but certificate handling, service-code mapping, ISS/withholding rules and cancellation flows remain real work. Most teams use a Brazilian fiscal-integration provider rather than integrating city systems directly.
We are a foreign SaaS with Brazilian customers. Do we need NFS-e?
Generally not — the issuance systems are built around Brazilian-registered entities, so a commercial invoice is the norm. Your customers may have their own obligations regarding the transaction. Make their life easy with correct CNPJ, BRL amounts and DD/MM/YYYY dates, and let their accountant handle the rest.
Building the receipt side?
FaturaPDF produces the recibo layout Brazilians expect — the "Recebemos de..." paragraph, the amount spelled out in Portuguese, the signature line — from a JSON payload, in one call.
Get an API key on RapidAPI → Or try the free browser generator