Saltar al contenido principal
Estás viendo el contrato actual (v3) de order.cancelled. v3 es un cambio que rompe solo en el contexto fiscal: cancellation.metadata.fiscal pasa a ser cancellation.fiscal, estructurado como { status, authority }, y ahora aplica a todo país con un documento autorizado, no solo a Brasil. cancellation.metadata ya no se emite. El resto del evento no cambia. Ver Rutas que cambian respecto del contrato anterior.
order.cancelled dispara cuando se cancela una orden previamente inyectada — desde el backoffice de Fire (cancellationSource: backoffice), o por un adaptador o la API de cancelación (cancellationSource: adapter). No retrae un order.completed previo de la misma orden; ambos eventos se emiten independientes.
Este evento no significa que el documento fiscal esté anulado. Se emite cuando se cancela la orden, antes de consultar a la autoridad. Cuando la orden tenía un documento autorizado, cancellation.fiscal describe ese documento tal como estaba en ese momento — todavía SALE_INVOICE, con cancelledAt: null. La confirmación de la autoridad llega después en order.reversed.

Condición de disparo

Fire emite order.cancelled una vez cuando una orden transiciona a CANCELLED, sin importar su estado de pago previo, con contexto completo de auditoría.

Qué hay en trigger.data

El mismo snapshot V4 de orden que order.completed, con cuatro diferencias:
  1. status es "CANCELLED".
  2. paymentStatus queda igual (típicamente "SUCCEEDED" si la orden había sido pagada).
  3. Un bloque top-level cancellation lleva la metadata de auditoría y, cuando aplica, el documento fiscal.
  4. No hay data.fiscal en la raíz. En este evento el documento del ente vive solo en cancellation.fiscal.
policy y lastKnown viajan exactamente igual que en order.completed. fiscalRepresentation tiene la misma forma, pero si para la cancelación se numeró una nota de crédito, trae esa nota arriba y la factura en history. En Brasil (PlugNotas) fiscalRepresentation es null: no hay paso de numeración. authority.providerIdentity y authority.providerMetadata aparecen en los documentos guardados bajo este contrato; en órdenes anteriores las claves pueden faltar — trata la clave ausente como null.

Ejemplo — Brasil, con un documento autorizado (sanitizado)

Ejemplo — sin un documento autorizado

Cuando la orden no tenía un documento autorizado (el ente todavía no había respondido, la tienda no emite documentos, o el documento no tiene id de proveedor), la clave fiscal está ausente — no en null. Acá, una tienda que no numera en la caja, cancelada antes de que el ente respondiera: fiscalRepresentation es null, lastKnown.fiscal todavía dice processing y cancellation no tiene fiscal. No sigue ningún order.reversed. En los países que numeran en la caja, una orden no se puede cancelar mientras su factura siga vigente: Fire responde 409 (FISCAL_REPRESENTATION_NOT_VOIDED) hasta que se pida la nota de crédito. Una vez pedida, el evento trae fiscalRepresentation con la CREDIT_NOTE arriba y la factura en history.
Compruébalo con if (data.cancellation.fiscal).
Los bloques elididos como igual que order.completed son exactamente el snapshot que lleva order.completed. Ver la referencia de campos de order.completed.
Campos de efectivo en payments.paymentMethods[]. customerCashAmount y changeAmount son números. Las órdenes inyectadas antes del 24 de septiembre de 2026 traen customerCashAmount como el texto "0" y sin changeAmount: si reenviás o reprocesás eventos viejos, leé el campo como número. Ver la referencia de campos de order.completed.

Referencia de data.cancellation

object
Bloque de auditoría que describe cómo, cuándo y por quién se canceló la orden.

El bloque fiscal

Para ver cómo llega acá cada campo del callback fiscal, consulta Del callback a los eventos. El bloque fiscal de order.invoiced, order.cancelled y order.reversed es lo que Fire guardó en la orden, con la misma forma. No se rearma por emisor: ya sea que el documento haya entrado por la integración nativa de tu proveedor fiscal o por el callback fiscal, lees los mismos campos a la misma profundidad.

Dónde vive en cada evento

En una cancelación el bloque está en cancellation.fiscal, no en cancellation.metadata.fiscal. Subió un nivel. Si tus flows o handlers leen cancellation.metadata.fiscal.*, leen undefined en el contrato actual.

Campos del bloque

string | null
El estado fiscal de la orden, no de un documento: awaiting_payment, not_issued, pending, processing, fiscal_graphic, authorized, cancelling, cancelled, rejected, denied, error. En la práctica order.invoiced lleva authorized, order.reversed lleva cancelled y order.cancelled lleva authorized o cancelling.
string | null
Código ISO 3166-1 alfa-2 del régimen que emitió el documento (BR, CO, EC, CL, AR, VE). El país ya no vive en el nombre del evento: filtra por este campo.
string | null
Identificador de Fire para el adaptador que procesó el documento (plugnotas, generic). Es nuestro, no el nombre del proveedor.
string | null
Timestamp ISO 8601 UTC del hecho fiscal que disparó el evento, tal como lo reportó el proveedor.
object | null
El veredicto del ente sobre el documento vigente. Los campos que significan lo mismo en todo país van arriba; los identificadores propios del ente van en countryData, con el vocabulario de ese país.
object[]
Cada parada del recorrido fiscal de la orden que describe un documento, de la más vieja a la más nueva — incluida la vigente. En order.invoiced suele tener una entrada, igual a authority; en order.reversed tiene la factura y después la cancelación. Las paradas sin bloque de documento no aparecen — por ejemplo el cancelling que Fire asienta antes de consultar al ente; un processing que ya trae la numeración de la caja sí aparece.
No es fiscalRepresentation.history. Ese lista solo los documentos anteriores de la numeración; este es el recorrido completo y termina con el documento vigente.
object | null
Un puntero al documento que el vigente reemplaza. Presente cuando el estado fiscal de la orden es cancelled; null en otro caso. Apunta a la última parada de history que no es a su vez una cancelación — busca su documentNumber ahí para tener el documento entero.
No lleva reason, a diferencia de fiscalRepresentation.compensates. El motivo ya viaja en el mismo evento, con más detalle: cancellation.cancellationType, cancellationGroup, cancellationReason, cancellationNote y cancellationSource. Fire no emite order.reversed sin un registro operativo de cancelación, así que ese bloque siempre está cuando está compensates. Un código fijo ORDER_CANCELLATION acá diría lo mismo con menos información. El bloque de numeración sí lleva reason: es donde el código canónico se resuelve al texto que se imprime en la nota de crédito, que necesita la redacción propia de la empresa.
En Brasil el puntero se refiere al mismo número. SEFAZ no numera un documento nuevo para cancelar uno, así que compensates.documentNumber es igual a authority.documentNumber. Es correcto, no un bug.

countryData y el callback fiscal

countryData es un bloque con tres nombres, según de qué lado de Fire lo mires: Lo que tu proveedor manda en el document del callback es lo que recibes en authority.countryData, con los mismos nombres de clave. La regla que separa a los dos es la exclusión: toda clave del callback que no sea un campo canónico cae intacta en countryData. Por eso un identificador nuevo de un país viaja sin ningún cambio del lado de Fire. Los campos raíz del callback pasan a ser los campos de primer nivel de authority con los mismos nombres, salvo los tres importes, que se agrupan en amounts. provider y metadata pasan a ser providerIdentity y providerMetadata (null si están ausentes o vacíos). La tabla campo por campo está en Del callback a los eventos.
El protocolo de Brasil vive en countryData, no arriba. Solo SEFAZ lo tiene — Chile tiene trackId, Argentina el cae — así que es vocabulario del ente, no un campo canónico. Las órdenes guardadas antes de este contrato lo tenían arriba como authorizationProtocol; Fire también lo emite como countryData.protocolo para esas.

Rutas que cambian respecto del contrato anterior

Cada ruta anterior tiene exactamente una ruta actual. El payload no lleva número de versión: la versión pertenece a este contrato documentado.

Lifecycle relativo a otros eventos

  • order.cancelled se emite inmediatamente, antes de contactar a la autoridad.
  • order.reversed sigue una vez que la autoridad confirma — segundos o minutos después.
  • Sin un documento autorizado, solo dispara order.cancelled.

Handler de ejemplo

Errores comunes

  • Lee cancellation.fiscal, no cancellation.metadata.fiscal. La ruta anterior viene vacía en v3.
  • cancellation.fiscal es el documento antes de la anulación. Para la confirmación de la autoridad, escucha order.reversed.
  • Ausente, no null. Verifica la presencia de la clave; no compares contra null.
  • order.cancelled no es un refund. El refund, si lo hay, lo inicia el canal o el procesador.
  • No asumas que order.completed llegó primero. Tolera un order.cancelled de una orden que aún no conoces.

Eventos relacionados

order.completed

El evento que verás para la misma orden antes de la cancelación.

order.reversed

Dispara cuando la autoridad confirma la cancelación del documento.

data.fiscalRepresentation

Sin cambios en v3. Es la numeración fiscal impresa en la caja, un bloque distinto de cancellation.fiscal: nunca dice que el documento esté autorizado. Cuando una cancelación numera una nota de crédito, esa nota queda arriba y la factura baja a fiscalRepresentation.history. Es el mismo bloque que en order.completed — referencia de campos en order.completed → data.fiscalRepresentation.

data.policy y data.lastKnown

Sin cambios en v3 e iguales en todos los eventos de orden. lastKnown.fiscal.status es el estado fiscal actual de la orden y es orientativo — nunca condiciones una acción irreversible a él. Referencia en order.completed → data.policy y data.lastKnown.