Skip to main content
Deprecado (v0). Contrato anterior, se mantiene solo como referencia histórica. La versión actual es order.completed — v1.1.
order.completed dispara cuando una orden se inyecta exitosamente y está pagada. Lleva el snapshot V4 de la orden como trigger.data — todos los campos que tu flow necesita para actuar sobre la orden sin volver a llamar a Fire.

Condición de disparo

Fire emite order.completed exactamente una vez por orden, la primera vez que ambos son verdaderos en momento de inyección:
  • order.status === "COMPLETED"
  • order.paymentStatus === "SUCCEEDED"
Las órdenes que siguen en PENDING de pago, o que fallan el pago, nunca producen order.completed. Las cancelaciones después de completar producen un evento separado order.cancelled — no retraen order.completed.

Qué hay en trigger.data

trigger.data es el snapshot V4 de la orden — el mismo objeto que se persiste en flow_queue.trigger_data y se expone a los templates de tu flow. Las claves top-level, en orden:

Ejemplo — payload real de producción (BR, sanitizado)

El ejemplo abajo viene de una fila real de flow_queue.trigger_data (tenant sandbox brasileño, canal KIOSK, servicio dine-in). Los campos PII se reemplazan por placeholders; el resto de los campos y formas son verbatim.
Los valores monetarios son strings con el importe entero escalado ×10.000 ("229000" son 22,9 BRL, no 229.000). Esto evita drift de punto flotante a través de múltiples integraciones. Parsea con una librería decimal, nunca con parseFloat. La excepción es paymentMethods[].totalBill, que el origen a veces envía como número JSON — maneja ambos.

Referencia de campos

Identificadores top-level

string
UUID interno de la orden en Fire. Estable a través de entregas; úsalo junto con event.id para trazabilidad.
string | null
Código corto legible mostrado en recibos y pantallas KDS (p. ej. 95K, OC-br-001). null cuando el canal no asigna uno.
string
Día de negocio al que pertenece esta orden, en YYYY-MM-DD. Calculado en hora local de la tienda, así que una orden hecha a las 01:00 puede pertenecer al día de negocio anterior según el corte de fin de día.
string
El ID de orden tal como lo provee el canal/agregador en la inyección. Úsalo para reconciliar con sistemas upstream (POS, dashboards de agregador).
string | null
Timestamp ISO 8601 UTC de cuándo se hizo la orden originalmente. Distinto de event.createdAt, que es cuándo arrancó la ejecución del flow.
string
Siempre "COMPLETED" para este evento.
string
Siempre "SUCCEEDED" para este evento.
boolean
true si se canjearon puntos de fidelidad en esta orden.
boolean
true si el cliente acumuló puntos de fidelidad.
boolean
true si se aplicó algún descuento.
string
Nota free-text del cliente para toda la orden. Empty string cuando no se setea.

data.store

object
Snapshot de la tienda en el momento que se completó la orden.

data.client

object | null
Cliente que hizo la orden. null para órdenes de canal totalmente anónimas. Para órdenes BR de “consumidor final”, client se popula con valores placeholder (govIdType: "FINAL_CONSUMER", govIdNumber: "00000000000").

data.payments

object
Desglose de dinero.

data.fulfillment

object
Cómo se entrega la orden.

data.kds

object
Contexto del kitchen display.

data.device y data.operator

object
{ uid, name, platform, metadata.ip } — dispositivo de origen. Los campos pueden ser null para canales no físicos.
object
{ uid, name, session.uid } — staff/cajero que procesó la orden. Todos los campos null para canales self-service (kiosko, web).

data.orderLines

object[]
Productos pedidos. Totalmente camelCase (transformado por el builder V4).

data.marketing, data.metadata, data.channel

object | null
Loyalty + cupones. null en la mayoría de países hoy; reservado para uso futuro.
object
Bag free-form para extras a nivel de orden. A menudo {}.
object
{ uid, code, metadata }. Ejemplos de code: KIOSK, APP, IFOOD, RAPPI.

Datos fiscales

La data fiscal se incluye solo cuando la tienda tiene emisión fiscal habilitada (store.storeFiscalConfig.enabled === true). Para países sin fiscal o tiendas sin configuración, las tres ubicaciones de abajo están ausentes o en null.
order.completed lleva información fiscal en tres ubicaciones distintas. Cada una sirve un propósito distinto:

1. data.store.storeFiscalConfig — identidad del emisor y config del proveedor

Identifica la entidad legal que emite el documento y cómo autenticar con el proveedor fiscal. Las credenciales NO están aquí intencionalmente — el nodo fiscal las obtiene por proveedor/account.

2. data.payments.metadata.fiscal — agregados fiscales a nivel de orden

Totales agregados estilo SEFAZ, listos para enviar al proveedor fiscal (tu proveedor fiscal en Brasil). Los valores son strings × 10000.

3. data.orderLines[n].metadata.fiscal — clasificación fiscal por línea

Códigos fiscales por producto. Usados por el proveedor fiscal para clasificar cada línea en el documento.
Además, metadata por impuesto vive dentro de cada taxes[n].metadata (en payments.totals[].taxes[], orderLines[].price.totalPrice[].taxes[] y orderLines[].lineTotals[].taxes[]) con códigos como cst, cBenef, cClassTrib, reducao, rateNominal, rateEffective.

Variaciones por país

El ejemplo de arriba es de una tienda brasileña con emisión fiscal habilitada — el caso más complejo. La forma del V4 es idéntica para todos los países; lo que cambia es cuánta data fiscal está populada. Hoy solo Brasil lleva los agregados por impuesto / por línea (payments.metadata.fiscal, orderLines[n].metadata.fiscal, lineTotals[n].taxes[]). Otros países tienen esos bloques presentes pero null / vacíos.
Las tiendas brasileñas con storeFiscalConfig.enabled === true llevan el payload fiscal completo — ver la sección Datos fiscales arriba. Marcadores de país:
  • store.locationInfo.country.code: "BR" · name: "Brasil" · timezone: "America/Sao_Paulo"
  • store.locationInfo.currencyCode: "BRL"
  • store.storeFiscalConfig.govIdType: "CNPJ" (14 dígitos)
  • store.storeFiscalConfig.secondaryGovIdType: "INSCRICAO_ESTADUAL"
  • payments.totals[].currency_code: "BRL", paymentMethods[].currencyCode: "BRL", orderLines[].selectedCurrency: "BRL"
  • Populados: payments.metadata.fiscal (vBC / vNF / vICMS / vPIS / vCOFINS / vTotTrib …), orderLines[].metadata.fiscal (ncm / cfop / csosn), lineTotals[].taxes[] (ICMS, PIS, COFINS, IBS_*)

Tabla de referencia rápida

A medida que más países tengan un pipeline fiscal dedicado, sus eventos fiscales llegarán como fiscal.*.{cc} (p. ej. fiscal.authorized.co, fiscal.authorized.ec). Hasta entonces, solo order.completed y order.cancelled disparan para tiendas no-BR — los bloques fiscales se quedan en null / vacíos.

Handler de ejemplo

Errores comunes

  • Decimales como strings × 10000. payments.totals[0].total === "229000" significa 22.9 BRL. Usa una librería decimal; nunca con parseFloat.
  • El casing es mixto en payments.totals[] y partes de paymentMethods[]. Lee tanto currencyCode como currency_code defensivamente. El builder V4 transforma la mayor parte del snapshot pero pasa los objetos de payment sin cambios.
  • fulfillment.delivery puede estar presente incluso para servicios non-delivery con ceros placeholder. Ramifica siempre por fulfillment.service.code.
  • client puede ser un placeholder “FINAL_CONSUMER” populado en BR — no es null. Trata govIdType === "FINAL_CONSUMER" como anónimo para analítica.
  • event.id es el ID de ejecución del flow, no el ID de la orden. Usa event.id para idempotencia (cambia por entrega), y orderId como llave de negocio.
  • Routing multi-tenant. Usa store.account.uid, store.vendor.uid y store.code para enrutar al tenant correcto en tu sistema, aunque Fire ya da scope al flow de su lado.

Eventos relacionados

order.cancelled

Dispara cuando esta orden se cancela después.

order.invoiced

Solo Brasil — dispara cuando SEFAZ autoriza el documento fiscal de la orden.