- v2 · atual
- v1 · descontinuada
- v0 · descontinuada
Você está vendo o contrato atual (v2). Adiciona o motivo estruturado ao bloco
cancellation — cancellationType (código estável), cancellationGroup (categoria) e cancellationNote (texto livre), sempre presentes (null quando vazio) — sobre o snapshot v1.order.reversed dispara quando a SEFAZ confirma o cancelamento de um documento fiscal (NFC-e ou NF-e) que tinha sido previamente autorizado. É a contraparte SEFAZ-confirmada de order.cancelled: o pedido é cancelado primeiro dentro do Fire (disparando order.cancelled), o Fire então pede o cancelamento na SEFAZ via seu provedor fiscal, e order.reversed dispara apenas quando a SEFAZ carimba o protocolo de cancelamento.
Condição de disparo
O Fire emiteorder.reversed uma vez por cancelamento fiscal, na primeira vez em que tudo o seguinte é verdade:
- O pedido está em uma loja com faturamento fiscal habilitado (
storeFiscalConfig.enabled === true) - Um documento fiscal tinha sido previamente autorizado (ou seja,
order.invoicedfoi emitido antes) - Uma solicitação de cancelamento foi enviada ao seu provedor fiscal
- O seu provedor fiscal reporta que a autoridade fiscal confirmou o cancelamento
O que tem em trigger.data
Mesmo snapshot V4 que order.cancelled — incluindo o mesmo bloco cancellation de auditoria — com um sub-objeto extra sefazCancellation dentro de cancellation.metadata.fiscal. Essa é a única diferença estrutural.
status é "CANCELLED". O pedido é o mesmo referenciado pelo evento order.cancelled anterior do mesmo orderId.
Exemplo — payload real de produção (BR, sanitizado)
Referência de data.cancellation.metadata.fiscal.sefazCancellation
Este é o único bloco que é único de order.reversed. Cada outro campo é compartilhado com order.cancelled — veja essa página para os campos de auditoria de cancelamento.
object
Confirmação SEFAZ do cancelamento. Presente apenas após a SEFAZ ter carimbado o protocolo de cancelamento.
Lifecycle
Para um pedido brasileiro fiscal-enabled, espere os quatro eventos acima. Para pedidos brasileiros sem autorização fiscal (porque o pedido foi cancelado antes da emissão fiscal, ou o fiscal estava desabilitado), apenasorder.cancelled dispara — não order.reversed.
Handler de exemplo
Erros comuns
- Não processe
order.reversedsemorder.cancelledprimeiro. Eles disparam em ordem em fluxo normal, mas entrega fora de ordem é possível. Se você receberorder.reversedpara umorderIdque não tem como cancelado registrado, logue e crie o registro a partir do blococancellationdeste evento — não jogue o evento fora. sefazCancellation.dateecStatpodem sernullem sandbox. Não faça com que a production-readiness dependa de eles estarem presentes em ambientes dev.- A URL do XML de cancelamento é distinta do XML do documento original. Garanta que sua lógica de arquivamento salve ambos — você precisará deles para auditoria.
- Mesmo
cancellation.cancellationIdqueorder.cancelled. Ambos os eventos para o mesmo cancelamento compartilham o cancellation ID — útil como chave de join ao correlacionar os dois eventos no seu sistema. - Não há evento para cancelamento SEFAZ falho. Se a SEFAZ rejeita a solicitação de cancelamento, nenhum evento dispara. Monitore o log de execuções do dashboard para esses casos.
Eventos relacionados
order.cancelled
Dispara antes deste evento — o cancelamento em si.
order.invoiced
O evento anterior que estabeleceu o documento fiscal sendo cancelado aqui.
data.fiscalRepresentation
Em
order.reversed este bloco é especialmente relevante: são os números do
comprovante que está sendo anulado. A anulação não os altera — o que muda é
lastKnown.fiscal.status, que passa a cancelled.null quando não se tentou numerar
— agregadores, países sem representação fiscal, ou comércios com a numeração
desativada — e traz o bloco quando houve tentativa.
Trazer o bloco significa que se tentou numerar, não que foi numerado:
numberingStatus diz como a tentativa terminou, e failure por quê quando não
terminou bem.
Ramifique pelo valor, não pela presença da chave:
lastKnown.fiscal,
que é o que de fato se move.
O que o substitui é um documento novo. O bloco carrega o documento fiscal
vigente do pedido. Enquanto houve apenas um, era sempre a nota de venda;
quando um cancelamento produz uma nota de crédito, é ela que fica no topo —
documentType diz qual é — e a nota de venda desce para history, inteira e
com seus próprios identificadores do órgão. Não se perde: se move. compensates
aponta para ela pelo número, então a relação fica explícita.
Quando a numeração falha
Uma venda pode ser cobrada e ficar sem comprovante fiscal. Esse caso também viaja, e precisa ser tratado: os identificadores vêmnull e o motivo em
failure.
failure.scope:
TECHNICAL— imprima “em trâmite” e siga. Pode se resolver sozinho.FUNCTIONAL— há um dado errado e repetir não resolve. Precisa correção. O que muda élastKnown.fiscal.
lastKnown.fiscal.sourceEvent agora informa a procedência real. Antes era
deduzida do status, e um processing semeado na injeção era reportado como
fiscal.callback sem que nenhum callback tivesse ocorrido. Esse caso agora diz
order.injected. Se você ramifica por este campo, contemple o valor novo.
