Pular para o conteúdo
🧾 NOTA FISCAL

NFS-e pelo seu projeto, no CNPJ do seu cliente.

Você manda o pedido da nota pelo seu servidor. O SuperDB emite pelo padrão nacional, grava a nota numa tabela do seu banco e guarda o PDF e o XML no Storage. Nos planos Pro e Escala, ativado pelo painel.

💡

Nos planos Pro e Escala. O SuperDB Fiscal é do plano da sua conta: o Pro emite até 100 NFS-e por mês em 1 CNPJ, e o Escala, até 1.000 por mês em 5 CNPJs. Os planos Grátis e Site não incluem. Não há cobrança de excedente: acima da cota do mês, a emissão é recusada até o dia 1º. Todo emitente começa em homologação (sem valor fiscal) e só passa à produção depois de a equipe do SuperDB conferir o seu pedido. Veja os planos em Preço.

Como funciona

  1. Ativar: o SuperDB cria a conta fiscal do projeto, o bucket de arquivos (privado, só para o servidor) e a tabela sdb_notas_fiscais no seu banco.
  2. Cadastrar o emitente (o CNPJ que emite a nota) e enviar o certificado A1 dele.
  3. Salvar o serviço padrão do emitente: o código de tributação, o NBS e a descrição que quase toda nota repete.
  4. Emitir em homologação (a homologação do Sistema Nacional NFS-e, sem valor fiscal) até a prontidão dizer que está tudo certo.
  5. Pedir a produção. O dono do projeto pede no painel (a tela Notas fiscais do projeto, em /projects/<slug>/fiscal, no emitente). A equipe confere e libera, e daí em diante as notas têm valor fiscal.
  6. Emitir pelo seu servidor: POST /fiscal/v1/nfse com a chave de servidor. A nota vira uma linha na tabela do seu banco, e o PDF e o XML caem no Storage.
💡

O SuperDB Fiscal emite a NFS-e do padrão nacional (nota de serviço), no CNPJ do seu cliente. Não emite NF-e de produto. O município do emitente precisa emitir pelo padrão nacional: se não emitir, o SuperDB Fiscal recusa o cadastro do serviço e a produção (veja o município).

1. Ativar e cadastrar (painel ou API de gestão)

A gestão é feita no painel (a tela Notas fiscais do projeto, em /projects/<slug>/fiscal) ou pela API de gestão do projeto, com a chave de gestão (sdb_pmk_), a mesma da conexão do MCP e da gestão por API. O pedido de produção e a desativação são só pelo painel.

RotaO que faz
GET /platform/v1/projects/<id>/fiscalO resumo: se está ativo, a cota do mês e quanto foi usado, os emitentes, e se dá para ativar agora.
POST .../fiscal/ativacaoAtiva (ou reativa, se estava desativado).
DELETE .../fiscal/ativacaoDesativa. Só pelo painel (Notas fiscais): a chave de gestão recebe 403 so_pelo_painel.
POST .../fiscal/emitentesCadastra o emitente.
POST .../fiscal/emitentes/<emitente>/certificadoEnvia o certificado A1.
PUT .../fiscal/emitentes/<emitente>/servico-padraoSalva o serviço padrão (e confere o município).
GET .../fiscal/emitentes/<emitente>/prontidaoO que falta para emitir.
GET .../fiscal/emitentes/<emitente>/parametrosO que o município administra, para os códigos de serviço que você perguntar.
POST .../fiscal/emitentes/<emitente>/producaoPede a produção. Só pelo painel (Notas fiscais, no emitente): a chave de gestão recebe 403 so_pelo_painel. A equipe do SuperDB confere e libera.
GET /POST .../fiscal/notas, GET .../notas/<id>, POST .../notas/<id>/cancelamento, POST .../notas/previaAs mesmas notas da API de servidor, pelo caminho da gestão.

Ativar

curl -X POST https://auth.superdb.com.br/platform/v1/projects/<projectId>/fiscal/ativacao \
  -H "Authorization: Bearer $SUPERDB_MANAGEMENT_KEY"
# 201 { "ativo": true, "criada": true, "bucket": "proj_<slug>_fiscal", "tabela": "sdb_notas_fiscais" }

Ativar de novo, já ativo, só repara o bucket e a tabela (200). Se o seu projeto já tem um bucket chamado fiscal aberto, a ativação recusa: renomeie ou apague esse bucket e ative de novo: nota fiscal tem dado pessoal, e o bucket dos arquivos nasce fechado.

RecusaO que quer dizer
403 fiscal_fora_do_planoO plano da sua conta não inclui o SuperDB Fiscal (Grátis e Site não incluem). Mude o plano da conta no painel para ativar.
409 fiscal_suspensoA conta do SuperDB Fiscal está suspensa. Se for pagamento, regularize o plano no painel; se não for, fale com o suporte do SuperDB.
409 ativacao_em_andamentoOutra ativação deste projeto está em curso. Espere alguns minutos.

Cadastrar o emitente

curl -X POST https://auth.superdb.com.br/platform/v1/projects/<projectId>/fiscal/emitentes \
  -H "Authorization: Bearer $SUPERDB_MANAGEMENT_KEY" -H "Content-Type: application/json" \
  -d '{
    "cnpj": "11222333000181",
    "razao_social": "Clínica Exemplo LTDA",
    "crt": 1,
    "uf": "MG",
    "logradouro": "Rua das Flores", "numero": "100", "bairro": "Centro",
    "municipio": "Belo Horizonte", "codigo_municipio": "3106200", "cep": "30110000"
  }'
# 201 { "id": "...", "ambiente": "homologacao", "municipio_conveniado": null, ... }
CampoRegra
cnpj14 dígitos, válido.
razao_socialDe 1 a 255 caracteres.
crt1 Simples, 2 Simples com excesso de sublimite, 3 Regime Normal, 4 MEI.
uf, logradouro, numero, bairro, municipio, codigo_municipio (7 dígitos do IBGE), cep (8 dígitos)Obrigatórios. complemento é opcional.
nome_fantasia, inscricao_municipal, ie, regime_especial_issOpcionais.
somente_homologacaoOpcional, true ou false. Com true, o emitente nunca sai em produção: serve para testar com um CNPJ que já emite em outra conta.

O emitente nasce sempre em homologação. Campo que não é do cadastro (por exemplo ambiente_atual) é recusado com o nome dele, e não ignorado. Repetir o cadastro de um CNPJ que já é do projeto devolve 409 cnpj_repetido. Um CNPJ que já emite com valor fiscal em outra conta devolve 409 cnpj_ja_cadastrado: para testar com ele, cadastre com somente_homologacao: true. O número de CNPJs por projeto é o do plano da sua conta (403 limite_de_cnpjs ao passar). Se a conta foi para um plano sem o SuperDB Fiscal, o cadastro de um emitente novo responde 403 fiscal_fora_do_plano.

Enviar o certificado A1

jq -n --arg pfx "$(base64 -i certificado.pfx | tr -d '\n')" --arg senha "$SENHA_DO_CERTIFICADO" \
   '{pfx: $pfx, senha: $senha}' | \
curl -X POST https://auth.superdb.com.br/platform/v1/projects/<projectId>/fiscal/emitentes/<emitente>/certificado \
  -H "Authorization: Bearer $SUPERDB_MANAGEMENT_KEY" -H "Content-Type: application/json" --data-binary @-
# 201 { "certificado": { "situacao": "...", "validade_inicio": "...", "validade_fim": "...", "fingerprint": "..." } }

O .pfx (em base64, até 64 KB) e a senha vão direto ao motor fiscal na mesma requisição. O SuperDB não guarda nenhum dos dois, e a resposta traz só os dados do certificado (validade e impressão digital). São 10 tentativas por hora por projeto: errar a senha em laço é bloqueado.

Salvar o serviço padrão

curl -X PUT https://auth.superdb.com.br/platform/v1/projects/<projectId>/fiscal/emitentes/<emitente>/servico-padrao \
  -H "Authorization: Bearer $SUPERDB_MANAGEMENT_KEY" -H "Content-Type: application/json" \
  -d '{
    "codigo_tributacao_nacional": "010302",
    "codigo_tributacao_municipal": "001",
    "nbs": "115062300",
    "descricao": "Assinatura de plataforma de software",
    "iss": { "tributacao": "1", "retencao": "1" },
    "tributos_aproximados": { "simples_nacional_percentual": 6 }
  }'

O serviço padrão não tem valor: o valor vem em cada nota. O código de tributação nacional tem 6 dígitos (o desdobro nunca é 00), o municipal tem 3 dígitos, e o NBS tem 9 (com ou sem os pontos). Cada nota pode trocar qualquer um desses campos em servico.

O município

Ao salvar o serviço padrão, o SuperDB pergunta ao cadastro nacional da NFS-e se o município do emitente emite pelo padrão nacional. Para isso precisa do certificado A1 já enviado e de um código de serviço.

  • Se o município não emite pelo padrão nacional, o serviço padrão não é salvo e a resposta é 422 municipio_fora_do_padrao_nacional. O emitente fica marcado: a emissão e o pedido de produção recusam com a mesma explicação. A marca só se desfaz salvando de novo o serviço padrão, depois que o município passar na conferência.
  • Qualquer outra resposta da conferência (o cadastro nacional ocupado, o certificado ainda não enviado, um problema do motor) não impede de salvar: a resposta traz um aviso dizendo que a conferência não foi feita. Consulte os parâmetros do município antes de emitir.

2. A prontidão e os parâmetros

curl https://auth.superdb.com.br/platform/v1/projects/<projectId>/fiscal/emitentes/<emitente>/prontidao \
  -H "Authorization: Bearer $SUPERDB_MANAGEMENT_KEY"
# { "pronto": false, "faltas": 1, "avisos": 0,
#   "itens": [ { "nivel": "falta", "codigo": "...", "texto": "..." } ],
#   "producao": { "pedida_em": null, "liberada_em": null }, "somente_homologacao": false }

Cada item tem o nivel (ok, aviso ou falta) e um texto que diz o que fazer. O campo producao é o que vale para a produção: quando foi pedida e quando a equipe liberou.

curl "https://auth.superdb.com.br/platform/v1/projects/<projectId>/fiscal/emitentes/<emitente>/parametros?codigos=010302,040101" \
  -H "Authorization: Bearer $SUPERDB_MANAGEMENT_KEY"

Os parâmetros dizem se o município emite pelo padrão nacional (convenio.ativo) e, para cada código, se ele administra o serviço e quais são as alíquotas. São de 1 a 5 códigos por consulta (6 dígitos, 9 com o desdobro municipal, ou 01.03.02.001), com competencia (AAAA-MM-DD) e ambiente (producao ou homologacao) opcionais. Precisa do certificado A1 já enviado.

As duas consultas têm limite (a prontidão, 6 por minuto; os parâmetros, 5 por minuto):

RespostaO que fazer
429 motor_limiteConsultou demais. Espere o tempo do cabeçalho Retry-After (no máximo 1 hora) e tente de novo.
503 adn_ocupadoO cadastro nacional da NFS-e está cheio agora. Tente de novo depois do Retry-After (alguns segundos).
502 motor_indisponivelO motor fiscal não respondeu. A primeira consulta de um município que ninguém consultou antes pode demorar mais que o prazo: tente de novo, que a segunda costuma passar.
422 emitente_sem_certificadoEnvie o certificado A1 antes de consultar o município.

3. A produção

Emitir em produção é um ato consciente do dono do projeto, com valor fiscal. Por isso:

  • O pedido de produção é feito no painel (Notas fiscais, no emitente), pelo dono do projeto.
  • A equipe do SuperDB recebe o pedido por e-mail, confere e libera. Enquanto isso, as notas saem em homologação. Quando a produção é liberada, o dono do projeto recebe um e-mail avisando que as notas daquele emitente passaram a ter valor fiscal.
  • O emitente de somente_homologacao nunca sai em produção (409 somente_homologacao), e o de município fora do padrão nacional também não (422 municipio_fora_do_padrao_nacional).

4. Emitir pelo servidor

Só com a chave de servidor (service_role), que nunca vai no app. Com a anon ou com a sessão do usuário, a API responde 403 chave_de_servidor: quem extrair a chave anon do app emitiria nota no CNPJ do seu cliente.

curl -X POST https://auth.superdb.com.br/fiscal/v1/nfse \
  -H "Authorization: Bearer $SUPERDB_SERVICE_ROLE_KEY" -H "Content-Type: application/json" \
  -d '{
    "ref": "pedido-1042",
    "tomador": { "cnpj": "11222333000181", "nome": "Cliente Exemplo LTDA", "email": "financeiro@cliente.example" },
    "servico": { "valor": 150.00, "informacoes_complementares": "Referente ao pedido 1042" }
  }'
# 202 { "id": "...", "ref": "pedido-1042", "situacao": "pendente", "ref_repetida": false, ... }
CampoRegra
refObrigatória: o id do pedido no seu sistema, de 1 a 100 caracteres (letras, números e . _ : / -, sem espaço). É a chave de idempotência.
emitenteO CNPJ do emitente (14 dígitos). Opcional se o projeto tem um só.
competenciaOpcional, AAAA-MM-DD, do mês em que o serviço foi prestado. Sem ela, vale hoje. Depois de hoje, a emissão recusa (422 competencia_futura).
tomadorOpcional: cpf ou cnpj (um só), nome (até 300), email e endereco (logradouro, numero, bairro, codigo_municipio, cep).
servicoObrigatório: valor em reais (pelo menos 1 centavo, até 2 casas, abaixo de R$ 10 milhões), e qualquer campo do serviço padrão que você queira trocar nesta nota. informacoes_complementares tem até 2.000 caracteres.

A resposta é 202: a nota entrou na fila, e a emissão acontece em segundo plano. Campo que o SuperDB Fiscal ainda não aceita (desconto, retenções, local de prestação) é recusado com o nome dele, para você nunca achar que a nota saiu com um desconto que ela não tem.

A ref e a repetição

  • Repetir o mesmo pedido com a mesma ref devolve a mesma nota (200, com ref_repetida: true): é seguro repetir depois de um erro de rede.
  • A mesma ref com um pedido diferente devolve 409 ref_reusada. Para outra nota, use outra ref.

Recusas na emissão

RespostaO que fazer
403 fiscal_fora_do_planoO plano da sua conta não inclui o SuperDB Fiscal, ou a conta foi para um plano sem ele. Mude o plano da conta no painel para voltar a emitir. Uma ref que já existia segue devolvendo a mesma nota, e consulta, arquivos e cancelamento continuam.
429 cota_fiscal_esgotadaA cota de notas do mês acabou. Espere o tempo do cabeçalho Retry-After: a emissão volta no dia 1º, no horário de Brasília.
403 fiscal_inativoO SuperDB Fiscal não está ativo neste projeto. Ative no painel (Notas fiscais) ou pela API de gestão (Ativar).
403 fiscal_suspenso, 403 fiscal_desativadoNotas novas estão recusadas até regularizar ou reativar (veja Desativar e reativar).
422 sem_emitente, 422 emitente_obrigatorioCadastre um emitente, ou, havendo mais de um, diga qual em emitente (o CNPJ).
422 competencia_futuraA competência não pode ser depois de hoje. Use um dia do mês em que o serviço foi prestado.
422 municipio_fora_do_padrao_nacionalO município do emitente não emite pelo padrão nacional (veja o município).

Prévia, consulta e cancelamento

# a prévia: confere o leiaute e devolve o XML da DPS (xml_dps) e um PDF de prévia (pdf_base64), sem emitir e sem gravar
curl -X POST https://auth.superdb.com.br/fiscal/v1/nfse/previa -H "Authorization: Bearer $SUPERDB_SERVICE_ROLE_KEY" \
  -H "Content-Type: application/json" -d '{ "ref": "teste", "servico": { "valor": 150.00 } }'

# a nota
curl https://auth.superdb.com.br/fiscal/v1/nfse/<id> -H "Authorization: Bearer $SUPERDB_SERVICE_ROLE_KEY"

# o cancelamento (só nota emitida)
curl -X POST https://auth.superdb.com.br/fiscal/v1/nfse/<id>/cancelamento -H "Authorization: Bearer $SUPERDB_SERVICE_ROLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "motivo": "1", "justificativa": "Valor lançado errado, nota refeita." }'
# 202

O motivo é 1 (erro na emissão), 2 (serviço não prestado) ou 9 (outros). A justificativa tem de 15 a 255 caracteres, em uma linha só (sem quebra de linha). Só a nota emitida pode ser cancelada (409 nfse_nao_cancelavel nas outras), e a prefeitura tem o prazo dela para aceitar o cancelamento.

Pelo SDK

O @superdb/client tem o módulo fiscal, que fala com as mesmas rotas e devolve { data, error }. Ele só funciona com a chave de servidor: com a anon, o SDK nem faz o pedido e o erro (chave_de_servidor) diz o que fazer. Está disponível a partir da versão 0.4.0 do pacote (npm install @superdb/client@latest).

import { createClient } from '@superdb/client'

const sdb = createClient(process.env.SUPERDB_URL!, process.env.SUPERDB_SERVICE_ROLE_KEY!, { project: 'meu_projeto' })

const { data, error } = await sdb.fiscal.nfse.emitir({
  ref: 'pedido-1042',
  tomador: { cnpj: '11222333000181', nome: 'Cliente Exemplo LTDA' },
  servico: { valor: 150 },
})
if (error) throw new Error(error.message) // erro de rede (status 0): chame de novo com a mesma ref
// data.situacao === 'pendente'

await sdb.fiscal.nfse.consultar(data!.id)
await sdb.fiscal.nfse.previa({ servico: { valor: 150 } })
await sdb.fiscal.nfse.cancelar(data!.id, { motivo: '1', justificativa: 'Valor lançado errado, nota refeita.' })

Falha de rede em emitir não é repetida pelo SDK (ele não sabe se a nota nasceu): chame de novo com a mesma ref, que devolve a mesma nota, sem duplicar.

Texto que a nota não aceita

O SuperDB Fiscal recusa antes de gravar o texto que não pode entrar numa nota. A resposta é 400 texto_invalido, com o caminho do campo (por exemplo tomador.nome):

  • caractere de controle e texto fora do padrão Unicode (por exemplo, um par substituto solto);
  • \r (retorno de carro) em qualquer campo. Em servico.descricao e servico.informacoes_complementares a quebra de linha (\n) e a tabulação passam; nos outros campos, nenhuma das duas. A justificativa do cancelamento não aceita quebra de linha;
  • corpo aninhado em mais de 32 níveis. Nenhum campo de nota é tão fundo, e a mensagem é a mesma do caractere de controle: se você jura que não há caractere nenhum, olhe o aninhamento.

5. As situações da nota

SituaçãoO que quer dizer
pendenteAinda não foi aceita pelo motor fiscal. Se o envio falhar, a mesma nota é reenviada, sem duplicar.
processandoO motor aceitou e está falando com a Receita.
emitidaA Receita autorizou: a nota tem numero e chave_acesso, e o PDF e o XML vão para o Storage.
rejeitadaA Receita recusou. O codigo_recusa, o motivo e a dica dizem por quê e o que mudar. Para emitir de novo, use outra ref.
erroA nota não pôde ser emitida (por exemplo, a conta estava suspensa). Emita de novo, com outra ref, depois de resolver.
em_verificacaoA nota segue sendo reconferida automaticamente no motor fiscal. Não emita outra no lugar: se a primeira existir, sairiam duas. Há casos que só a equipe resolve: se ela não sair desse estado, fale com o suporte do SuperDB.
cancelamento_pendenteO cancelamento foi pedido e aguarda a Receita.
canceladaA Receita registrou o cancelamento.

A situação final de uma nota (rejeitada, erro e cancelada) não volta atrás.

Motivos de recusa comuns

CódigoO que fazer
E0312O código de tributação não é aceito pelo município, ou falta o código municipal de 3 dígitos: confira os dois no serviço padrão.
E0014O número da DPS já foi usado na Receita. Fale com o suporte do SuperDB, que ajusta o próximo número da DPS.
E0018A competência é anterior à abertura do CNPJ ou à opção pelo Simples. Use uma data depois delas.
E0116, E0120O município exige (ou não aceita) a inscrição municipal do prestador. Ajuste o cadastro do emitente.
E0625Para ME e EPP do Simples sem retenção, a alíquota do ISS não pode ser informada: tire aliquota do serviço.
producao_nao_liberadaA produção ainda não foi liberada para este emitente. Enquanto isso, as notas saem em homologação; o dono do projeto pede a produção no painel (Notas fiscais, no emitente).
tenant_suspensoO SuperDB Fiscal do projeto estava suspenso. Regularize o plano e emita de novo, com outra ref.

6. A tabela no seu banco

Cada nota vira uma linha em sdb_notas_fiscais, no schema do seu projeto:

select id, ref, situacao, numero, chave_acesso, valor, competencia, pdf_path
  from sdb_notas_fiscais order by criada_em desc limit 20;

As colunas: id, ref, tipo, emitente_cnpj, tomador_documento, tomador_nome, valor, competencia, situacao, numero, chave_acesso, codigo_recusa, motivo, ambiente, pdf_path, xml_path, criada_em, emitida_em, cancelada_em e atualizada_em.

  • Quem lê: o seu servidor (chave service_role) e o SQL do projeto. A chave anon e a sessão do usuário não veem nada até você criar uma policy (a tabela tem CPF e nome de tomador). Para mostrar a nota ao usuário do app, escreva a policy com o create policy ... to authenticated using (...) que o seu caso pedir.
  • Quem escreve: só o SuperDB. Nem a chave de servidor escreve nela.
  • É um espelho, não a fonte da verdade. A verdade da nota está no SuperDB: use GET /fiscal/v1/nfse/<id> para decidir qualquer coisa que valha dinheiro. Se você apagar a tabela, uma coluna ou uma linha, o SuperDB recria. Se você alterar uma linha, a alteração fica até a nota mudar de situação de novo, e então ela é regravada. Não escreva regra de negócio em cima de uma linha que você mesmo mexeu.

O PDF e o XML

Quando a nota é emitida, o PDF (DANFSe) e o XML caem no bucket proj_<slug>_fiscal, e os caminhos vêm em arquivos.pdf e arquivos.xml da nota (e em pdf_path e xml_path da tabela). O bucket é privado e só para o servidor: baixe pelo seu servidor, com a chave de servidor e o nome completo do bucket, e entregue ao seu cliente do jeito que você quiser. Não abra esse bucket: o SuperDB confere e recusa a emissão de arquivos num bucket aberto.

Limites

  • Notas por mês e CNPJs: os do plano da conta do projeto: Pro, 100 NFS-e por mês e 1 CNPJ; Escala, 1.000 por mês e 5 CNPJs. Grátis e Site não incluem. Não há cobrança de excedente: passou do limite, a emissão responde 429 cota_fiscal_esgotada com Retry-After até a virada do mês (horário de Brasília). Conta a nota emitida e as que estão a caminho; o cancelamento não devolve.
  • Requisições: até 600 por minuto por projeto (429 rate_limited, com Retry-After).
  • Certificado: 10 envios por hora por projeto.

Desativar, reativar e a falta de pagamento

  • Desativar (só pelo painel, em Notas fiscais): notas novas são recusadas (403 fiscal_desativado). Consulta, PDF e cancelamento continuam. A tabela e os arquivos ficam com você.
  • Reativar é ativar de novo: o mesmo cadastro volta, com as notas antigas.
  • Falta de pagamento: se o projeto é pausado ou suspenso, o SuperDB Fiscal é suspenso junto (403 fiscal_suspenso para notas novas; consulta e cancelamento continuam) e volta sozinho quando o projeto volta ao ar. Reativar com o projeto ainda fora do ar não reativa nada: a conta fica suspensa até o projeto voltar.

O que ainda não fazemos

  • NF-e de produto e outros tipos de nota: só NFS-e do padrão nacional.
  • Município que não emite pelo padrão nacional: o SuperDB Fiscal recusa o serviço padrão e a produção.
  • Desconto, retenções e local de prestação no pedido: ainda não.