Callback fiscal
API
Callback fiscal
Endpoint inbound para o qual seu provedor fiscal faz POST quando um documento fiscal muda de estado. Multipaís (BR, CO, EC, CL, AR, VE). Atualiza o estado fiscal do pedido dentro do Fire e — para o Brasil — dispara os eventos de pedido downstream.
POST
Callback fiscal
Este endpoint é inbound — seu provedor fiscal faz POST nele sempre que um documento fiscal é autorizado, rejeitado, denegado, cancelado ou falha. É a API canônica multi-país de fiscal callback que aceita payloads de BR, CO, EC, CL, AR, VE. O Fire valida o payload, atualiza o estado fiscal do pedido em
Como complementa
O estado
Resultados negativos (
Para estados não autorizados, omita
Um
fiscal_documents e orders.fiscal, e — para o Brasil — despacha eventos outbound order.invoiced / order.reversed para seus Integration Flows.
Este endpoint é assíncrono. O Fire autentica, roda o guard de source-of-truth + tenancy, deduplica, pré-marca o pedido como
processing e enfileira o callback — depois retorna 202 Accepted com um webhookEventId (tipicamente em menos de 100 ms). A atualização de fiscal_documents / orders.fiscal acontece um instante depois em um worker em segundo plano (normalmente em ~2 segundos). Para ver o resultado do processamento, consulte GET /v1/webhooks/events/{webhookEventId}. Problemas corrigíveis pelo cliente (payload inválido, eventId errado, tenant errado, uma ação reusando o evento de outra) são rejeitados sincronamente com 4xx antes do 202.Como complementa order.completed e order.cancelled
order.completed e order.cancelled carregam o estado de negócio de um pedido. O callback fiscal carrega o estado fiscal (autorização SEFAZ / DIAN / SRI / SII / AFIP / SENIAT). Juntos formam este lifecycle:
Após processar o callback, o próximo order.completed ou order.cancelled para o mesmo orderId reflete o estado fiscal atualizado em:
data.store.storeFiscalConfig— contexto do emissor (CNPJ / NIT / RUC / RUT / CUIT / RIF…)data.payments.metadata.fiscal— agregados fiscais totais (BR populado; outros paísesnull)data.orderLines[].metadata.fiscal— classificação fiscal por linha (BR populado; outrosnull)
order.invoiced (ou order.reversed) separado com as referências do documento SEFAZ em data.fiscal.
Hoje, apenas
order.invoiced e order.reversed estão cabeados como eventos outbound (Brasil). O endpoint valida e armazena callbacks para os 6 países (CO, EC, CL, AR, VE, BR), e o estado fiscal atualizado aparece no próximo evento order.completed / order.cancelled independentemente do país. Os eventos outbound para CO/EC/CL/AR/VE estão a caminho.Autenticação
Este endpoint requer uma API key com scopewebhooks:fiscal, vendor-scoped ao account dono do pedido. Keys sem scope ou apenas a nível account são rejeitadas com 403 Forbidden.
string
obrigatório
Sua API key do Fire. Gere uma no dashboard em Settings → API Keys → Developer keys, com scope
webhooks:fiscal e um binding de vendor para o account cujos pedidos esta key pode atualizar.string
Opcional
Bearer <token>. Não exigido para este endpoint hoje, mas reservado para futuros tokens emitidos pelo provedor.Corpo da requisição
O body é um objeto JSON com estes campos top-level. O formato dodocument é discriminado por countryCode — veja Documento por país abaixo.
string
obrigatório
Código de país ISO 3166-1 alpha-2. Um de
BR, CO, EC, CL, AR, VE. Determina as regras de validação do objeto document.string
obrigatório
Estado do documento. Um de:
fiscal_graphic— o provedor está entregando a representação gráfica (o artefato imprimível) do documento. Não é uma aprovação nem um estado terminal — veja O estadofiscal_graphicabaixo.authorized— a autoridade fiscal aprovou o documentocancelled— um documento previamente autorizado foi canceladorejected— o documento foi rejeitado (validação, schema, assinatura)denied— a autoridade negou a solicitação (tipicamente falha permanente de regra de negócio)error— ocorreu um erro não recuperável no provedor ou autoridade
eventType é fiscal_graphic, authorized ou cancelled, o campo document é obrigatório. Quando é rejected, denied ou error, o campo error é obrigatório.string
obrigatório
O id próprio do seu provedor para esta entrega. Armazenado para auditoria/forense — não é a chave de idempotência. O Fire deduplica por
(orderId, eventId), então você pode enviar um providerEventId novo a cada retentativa sem criar duplicatas. Use o ID nativo do evento do provedor se disponível; caso contrário, um UUID.string
obrigatório
Timestamp ISO 8601 UTC de quando o evento ocorreu na autoridade fiscal (não quando o provedor enviou o callback).
string
obrigatório
UUID do pedido no Fire. Coincide com
data.orderId nos eventos order.completed e order.cancelled. O Fire o usa para encontrar o documento fiscal existente.string
obrigatório
UUID de correlação e chave de idempotência (junto com
orderId). Deve ser o event.id de um envelope V4 que o Fire emitiu para este pedido — ecoe-o exato; nunca o invente.- Verificação de fonte da verdade. Um
eventIdque não referencie um evento do Fire para esse pedido é rejeitado com400antes do202. - Cada ação carrega seu próprio evento. Ecoe o
event.iddo evento que disparou esta ação — a emissãoorder.invoicedpara um callbackauthorized, o evento de cancelamento/estorno para um callbackcancelled. Reusar oeventIdde uma ação para outroeventType(ex. umcancelledque ecoa oeventIddoauthorized) é rejeitado com409— um cancelamento deve referenciar seu próprio evento, não se pendurar no da autorização. Veja Idempotência e cenários.
object
O documento fiscal autorizado / cancelado. Obrigatório quando
eventType é authorized ou cancelled. O formato varia por país — veja Documento por país.object
Contexto de erro para resultados negativos. Obrigatório quando
eventType é rejected, denied ou error.object
Bag free-form para extras específicos do provedor (resposta raw, IDs internos, etc.). Não validado; passa para o log de auditoria.
Documento por país
O formato exigido do campodocument depende do countryCode. Todas as variantes compartilham os campos base abaixo (comuns aos 6 países) mais os identificadores específicos do país exigidos por aquela autoridade.
Campos base comuns
Aplicam-se a qualquercountryCode. docType e docSubtype são obrigatórios; o restante é opcional — envie-os sempre que seu provedor fiscal os tiver disponíveis. O Fire os persiste em fiscal_documents / orders.fiscal e os reemite nos eventos outbound order.invoiced / order.reversed (Brasil) e no próximo order.completed / order.cancelled.
pdfUrl e xmlUrl são armazenados exatamente como você os envia — o Fire não baixa nem re-hospeda o arquivo. Se seu provedor assina essas URLs com expiração, considere que o link armazenado pode caducar; baixe e persista o artefato do seu lado se precisar de acesso durável.- Brasil (BR)
- Colombia (CO)
- Equador (EC)
- Chile (CL)
- Argentina (AR)
- Venezuela (VE)
Documentos fiscais brasileiros (NF-e / NFC-e). Use este código de país ao enviar callbacks do seu provedor fiscal ou de qualquer outro provedor BR.Além dos campos base comuns (
docType, docSubtype, pdfUrl, xmlUrl, emittedAt, etc.), o BR exige estes identificadores específicos:O exemplo abaixo inclui os campos base opcionais (
pdfUrl, xmlUrl, emittedAt, totalAmount, taxAmount, currencyCode) — todos podem ser omitidos, mas envie-os se seu provedor os tiver:O estado fiscal_graphic
fiscal_graphic informa que o seu provedor está entregando a representação gráfica — o artefato imprimível (PDF / RIDE / DANFE) do documento. É um estado próprio, não um resultado:
- Não é uma aprovação. Receber
fiscal_graphicnão diz nada sobre a autoridade ter aprovado o documento. O Fire armazena a representação e o documento permanece em estado não terminal. - É opcional. Se o seu provedor não tem representação gráfica para um documento, envie
authorized(ou qualquer estado terminal) diretamente — não é necessário umfiscal_graphicantes. Ambos os fluxos são válidos. - Pode compartilhar o
eventIdcom o seu desfecho. A representação e o resultado terminal pertencem à mesma ação, então você pode enviarfiscal_graphice depoisauthorized/rejected/denied/cancelledreutilizando o mesmoeventId. Isso não é um conflito e nunca retorna409— veja Idempotência e cenários. - Exige
documentcompdfUrl. O PDF é a representação, portanto é obrigatório.xmlUrlcontinua opcional aqui — o XML legal viaja com a autorização. - Não dispara nenhum evento de saída.
order.invoicedeorder.reversedseguem atrelados aauthorizedecancelledrespectivamente. A representação apenas muda o estado do documento.
fiscal_graphic (CO)
Resultados negativos (rejected, denied, error)
Para estados não autorizados, omita document e forneça error. O countryCode ainda se aplica (valida o roteamento); o documento não é exigido porque não há artefato autorizado.
Rejeitado
Resposta
Em caso de sucesso o endpoint retorna202 Accepted — o evento foi autenticado, validado, deduplicado e enfileirado. Um 202 não significa que o documento fiscal já foi atualizado; isso acontece de forma assíncrona em um worker em segundo plano. Use o endpoint de status para confirmar o resultado final.
O body traz dois ids distintos para não haver ambiguidade: eventId é o id que você enviou (devolvido como echo), webhookEventId é o id do Fire para o registro enfileirado.
boolean
Sempre
true quando a requisição foi aceita e enfileirada.boolean
true quando este (orderId, eventId) já foi ingerido com o mesmo eventType — o registro existente é retornado e nada é re-enfileirado. false para um evento novo.string
Echo do
eventId que você enviou (o event.id da emissão do Fire). Use-o para correlacionar este acuse com a sua requisição.string
O id do Fire para o registro enfileirado em
webhook_events. Passe para GET /v1/webhooks/events/{webhookEventId} para consultar o resultado do processamento. Em uma duplicata é o mesmo id retornado na primeira vez.string
Status atual do registro na fila —
queued → processing → processed (e retry / failed / dead / ignored).string
Timestamp ISO 8601 UTC de quando o Fire recebeu pela primeira vez este evento. Estável entre retentativas — útil como âncora de rastreamento.
string
Resumo legível do que aconteceu.
Verificar o resultado
Como o processamento é assíncrono, o202 só confirma que o evento foi enfileirado. Para ver se o documento fiscal foi atualizado, consulte o endpoint de status com o webhookEventId retornado pelo 202:
string
Ciclo de vida na fila:
queued → processing → processed (pronto) · failed / dead (esgotou as retentativas) · retry (aguardando a próxima tentativa) · ignored.number
Tentativas de processamento até agora.
object | null
Em sucesso, o resultado do worker — ex.
{ "kind": "updated", "documentId": "…", "receiptId": "…" }.object | null
{ "message": "…" } quando a última tentativa falhou; null caso contrário.404 é retornado para ids desconhecidos — ou ids de outro tenant — sem vazar existência. Autentique com a mesma key webhooks:fiscal que usou no callback.
Idempotência e cenários
O Fire deduplica callbacks por(orderId, eventId) — não por providerEventId (que você pode regenerar livremente). Um evento é único com o seu pedido: o mesmo (orderId, eventId) reenviado com o mesmo eventType é um replay benigno; o mesmo (orderId, eventId) com um eventType diferente é uma tentativa de pendurar uma ação no evento de outra, e o Fire rejeita.
fiscal_graphic é a exceção. É um passo da mesma ação, não um desfecho concorrente, então pode compartilhar o eventId com o estado terminal que vem depois — essa combinação é aceita, nunca retorna 409.
Esta é a matriz completa de comportamento — cada combinação que você pode enviar:
409 vs 202. Um 409 é o único caso em que um callback bem formado e autenticado é recusado na camada de idempotência — porque aceitá-lo divergiria o estado. Um replay do mesmo tipo nunca é um erro: retorna 202 para que suas retentativas fiquem limpas. Um 503 é nosso (infra transitória), então é seguro e esperado retentar.Concorrência
As transições de estado emfiscal_documents usam locking otimista. Se dois callbacks para o mesmo documento chegarem simultaneamente, um tem sucesso e o outro resolve para idempotent ou regression conforme a ordem. O merge de orders.fiscal JSONB é atômico.
O que acontece após o 202
O202 apenas enfileira o evento. Um worker em segundo plano então o pega — em ~2 segundos via o wake-up instantâneo, ou no próximo ciclo de polling como fallback — e:
- A linha
fiscal_documentsé upsertada com o novo status e referências do documento (chaveAcesso,protocolo,cufe,cae, etc., conforme o país). - A coluna
orders.fiscalJSONB é mergeada com os mesmos dados — visível no próximo eventoorder.completed/order.cancelledpara o mesmoorderId, independente do país. - Um trigger outbound é despachado — para o Brasil,
triggerType = 'order.invoiced'(paraeventType=authorized) ou'order.reversed'(paraeventType=cancelled). Os Integration Flows ativos para esse trigger rodam e fazem POST para o seu endpoint.
- Hoje, apenas
order.invoicedeorder.reversedestão cabeados. Disparam quando um callback authorized/cancelled para uma loja BR é processado. - Para CO/EC/CL/AR/VE, os eventos outbound equivalentes ainda não estão cabeados — os callbacks são validados e armazenados, e o estado fiscal se reflete no próximo
order.completed/order.cancelledpara o mesmo pedido.
Relacionado
order.completed
Veja onde o estado fiscal aterrissa dentro do snapshot V4 do pedido.
order.invoiced
Evento outbound BR-only disparado por este callback.
Injetar pedido
O endpoint de injeção que cria o pedido que este callback atualiza.
Autenticação
Como funcionam API keys, scopes e vendor binding.

