- v2 · actual
- v1 · descontinuada
- v0 · descontinuada
Estás viendo el contrato actual (v2). Agrega el motivo estructurado al bloque
cancellation — cancellationType (código estable), cancellationGroup (categoría) y cancellationNote (texto libre), siempre presentes (null si vacío) — sobre el snapshot v1.order.reversed dispara cuando SEFAZ confirma la cancelación de un documento fiscal (NFC-e o NF-e) que había sido previamente autorizado. Es la contraparte SEFAZ-confirmada de order.cancelled: la orden se cancela primero dentro de Fire (disparando order.cancelled), Fire después pide la cancelación en SEFAZ vía tu proveedor fiscal, y order.reversed dispara solo cuando SEFAZ estampa el protocolo de cancelación.
Condición de disparo
Fire emiteorder.reversed una vez por cancelación fiscal, la primera vez que todo lo siguiente es verdadero:
- La orden está en una tienda con facturación fiscal habilitada (
storeFiscalConfig.enabled === true) - Un documento fiscal había sido previamente autorizado (es decir,
order.invoicedse emitió antes) - Se envió una solicitud de cancelación a tu proveedor fiscal
- tu proveedor fiscal reporta que la autoridad fiscal confirmó la cancelación
Qué hay en trigger.data
Mismo snapshot V4 que order.cancelled — incluyendo el mismo bloque cancellation de auditoría — con un sub-objeto extra sefazCancellation dentro de cancellation.metadata.fiscal. Esa es la única diferencia estructural.
status es "CANCELLED". La orden es la misma referenciada por el evento order.cancelled previo del mismo orderId.
Ejemplo — payload real de producción (BR, sanitizado)
Referencia de data.cancellation.metadata.fiscal.sefazCancellation
Este es el único bloque que es único de order.reversed. Cada otro campo se comparte con order.cancelled — consulta esa página para los campos de auditoría de cancelación.
object
Confirmación SEFAZ de la cancelación. Presente solo después de que SEFAZ haya estampado el protocolo de cancelación.
Lifecycle
Para una orden brasileña fiscal-enabled, espera los cuatro eventos arriba. Para órdenes brasileñas sin autorización fiscal (porque la orden se canceló antes de la emisión fiscal, o fiscal estaba deshabilitado), solo disparaorder.cancelled — no order.reversed.
Handler de ejemplo
Errores comunes
- No proceses
order.reversedsinorder.cancelledprimero. Disparan en orden en flujo normal, pero entrega fuera de orden es posible. Si recibesorder.reversedpara unorderIdque no tienes registrado como cancelado, loguéalo y crea el registro desde el bloquecancellationde este evento — no botes el evento. sefazCancellation.dateycStatpueden sernullen sandbox. No hagas que la production-readiness dependa de que estén presentes en entornos dev.- El XML URL de cancelación es distinto del XML del documento original. Asegúrate que tu lógica de archivado guarde ambos — los necesitarás para auditoría.
- Mismo
cancellation.cancellationIdqueorder.cancelled. Ambos eventos para la misma cancelación comparten el cancellation ID — útil como llave de join cuando correlacionas los dos eventos en tu sistema. - No hay evento para cancelación SEFAZ fallida. Si SEFAZ rechaza la solicitud de cancelación, no dispara evento. Monitorea el log de ejecuciones del dashboard para esos casos.
Eventos relacionados
order.cancelled
Dispara antes de este evento — la cancelación misma.
order.invoiced
El evento previo que estableció el documento fiscal que se cancela acá.
data.fiscalRepresentation
En
order.reversed este bloque es especialmente relevante: son los números del
comprobante que se está anulando. La anulación no los cambia — lo que cambia
es lastKnown.fiscal.status, que pasa a cancelled.null cuando no se intentó numerar
—agregadores, países sin representación fiscal, o comercios con la numeración
desactivada— y con el bloque cuando sí se intentó.
Que traiga bloque significa que se intentó numerar, no que se numeró:
numberingStatus dice cómo terminó el intento, y failure por qué cuando no
terminó bien.
Ramificá por valor, no por presencia de la clave:
lastKnown.fiscal, que es lo que sí se mueve.
Lo que sí lo reemplaza es un documento nuevo. El bloque lleva el documento
fiscal vigente de la orden. Mientras solo hubo uno, era siempre la factura;
cuando una anulación produce una nota de crédito, arriba queda la nota —
documentType dice cuál es— y la factura baja a history, entera y con sus
propios identificadores del ente. No se pierde: se mueve. compensates apunta a
ella por su número, así que la relación entre los dos queda explícita.
Cuando la numeración falla
Una venta puede cobrarse y quedarse sin comprobante fiscal. Ese caso también viaja, y hay que contemplarlo: los identificadores vienen ennull y el motivo
en failure.
failure.scope:
TECHNICAL— imprimí “en trámite” y seguí. Puede resolverse solo.FUNCTIONAL— hay un dato mal y reintentar no lo arregla. Requiere corrección.
lastKnown.fiscal.sourceEvent ahora informa la procedencia real. Antes se
deducía del estado, y un processing sembrado al inyectar se reportaba como
fiscal.callback sin que ningún callback hubiera ocurrido. Ahora ese caso dice
order.injected. Si ramificás por este campo, contemplá el valor nuevo.
