Skip to main content
Descontinuado (v0). Contrato anterior, mantido apenas como referência histórica. A versão atual é order.completed — v1.
order.completed dispara quando um pedido é injetado com sucesso e está pago. Carrega o snapshot V4 do pedido como trigger.data — todos os campos que seu flow precisa para agir sobre o pedido sem voltar a chamar o Fire.

Condição de disparo

O Fire emite order.completed exatamente uma vez por pedido, na primeira vez em que ambos são verdadeiros no momento de injeção:
  • order.status === "COMPLETED"
  • order.paymentStatus === "SUCCEEDED"
Pedidos que ainda estão PENDING de pagamento, ou que falham o pagamento, nunca produzem order.completed. Cancelamentos após completar produzem um evento separado order.cancelled — eles não retraem order.completed.
CoberturaGlobal (todos os países, todos os canais)
Chave de idempotênciaevent.id (= flow_executions.id)
Dispara mais de uma vezNão, salvo em retentativas — use event.id para deduplicar
OrdemNão garantida entre pedidos — ordene por data.createdAt se precisar
RetentativasAté 5 tentativas com backoff exponencial

O que tem em trigger.data

trigger.data é o snapshot V4 do pedido — o mesmo objeto que está persistido em flow_queue.trigger_data e exposto aos templates do seu flow. As chaves top-level, em ordem:
ChaveTipoSempre presente
orderIdstring (UUID)sim
orderCodestring | nullsim
businessDayDatestring (YYYY-MM-DD)sim
externalOrderIdstringsim
redeemPointsbooleansim
accumulatePointsbooleansim
discountbooleansim
createdAtstring | null (ISO 8601 UTC)sim
orderCommentstring (pode ser "")sim
paymentStatusstring (sempre "SUCCEEDED")sim
statusstring (sempre "COMPLETED")sim
marketingobject | nullsim
storeobjectsim
deviceobjectsim
channelobjectsim
operatorobjectsim
clientobject | nullsim
paymentsobjectsim
kdsobjectsim
metadataobject (frequentemente {})sim
orderLinesobject[]sim
fulfillmentobjectsim

Exemplo — payload real de produção (BR, sanitizado)

O exemplo abaixo vem de uma linha real de flow_queue.trigger_data (tenant sandbox brasileiro, canal KIOSK, serviço dine-in). Os campos PII são substituídos por placeholders; o restante dos campos e formatos é verbatim.
{
  "orderId": "21ec1f6c-c301-4528-b999-7836c1d21c6c",
  "orderCode": "OC-br-001",
  "businessDayDate": "2026-03-31",
  "externalOrderId": "7805610b-97cf-461f-a2d6-d86f63a80833",
  "redeemPoints": false,
  "accumulatePoints": false,
  "discount": false,
  "createdAt": "2026-05-06T01:22:59.028Z",
  "orderComment": "Comentário de teste do pedido",
  "paymentStatus": "SUCCEEDED",
  "status": "COMPLETED",
  "marketing": null,
  "store": {
    "uid": "a4019cad-bbac-4269-9f8d-f29654e92c45",
    "code": "BR-SP-001",
    "name": "Loja Centro - SP",
    "phone": "1132094347",
    "address": "Av. Paulista 1578, Bela Vista, São Paulo - SP",
    "externalId": "a4019cad-bbac-4269-9f8d-f29654e92c45",
    "vendor": {
      "uid": "100.2.1",
      "name": "Sandbox Brand",
      "description": "Sandbox Brand",
      "loyaltyPlan": true
    },
    "account": {
      "uid": "100",
      "name": "Sandbox",
      "description": "Sandbox"
    },
    "locationInfo": {
      "city":     { "uid": "1", "code": "SAO", "name": "São Paulo" },
      "country":  { "uid": "6", "code": "BR",  "name": "Brasil" },
      "location": { "lat": "-23.5952979", "lon": "-46.6866818" },
      "timezone": "America/Sao_Paulo",
      "currencyCode": "BRL"
    },
    "storeFiscalConfig": {
      "enabled": true,
      "company": {
        "govIdType": "CNPJ",
        "govIdNumber": "00000000000000",
        "legalName": "Sandbox LTDA",
        "tradeName": "Sandbox"
      },
      "govIdType": "CNPJ",
      "govIdNumber": "00000000000000",
      "secondaryGovIdType": "INSCRICAO_ESTADUAL",
      "secondaryGovIdNumber": "000000000000",
      "metadata": {
        "neverstop":   { "url": "", "enabled": false },
        "storeCode3S": "50000001",
        "serialNumber": 1
      }
    }
  },
  "device": {
    "uid": "device_kiosk_001",
    "name": "KIOSK",
    "platform": "android",
    "metadata": { "ip": "10.0.0.0" }
  },
  "channel": {
    "uid": "c784d4ba-23c7-4929-b2f0-1a1960d9cdc2",
    "code": "KIOSK",
    "metadata": {}
  },
  "operator": {
    "uid": "op_001",
    "name": "Operator Name",
    "session": { "uid": "sess_001" }
  },
  "client": {
    "uid": "usr_consumidorfinal_001",
    "name": "CONSUMIDOR",
    "lastName": "FINAL",
    "email": "consumidor@example.com",
    "phone": "0000000000",
    "govIdType": "FINAL_CONSUMER",
    "govIdNumber": "00000000000",
    "externalId": null,
    "metadata": {
      "fiscal": null,
      "gender": "",
      "birthdate": ""
    },
    "billingInformation": {
      "email": "",
      "phone": "0000000000",
      "address": "",
      "govIdType": "FINAL_CONSUMER",
      "externalId": "",
      "govIdNumber": "00000000000",
      "businessName": ""
    }
  },
  "payments": {
    "totals": [
      {
        "taxes": [
          { "base": "229000", "name": "ICMS",   "rate": "0.04",   "amount": "9200",
            "metadata": { "cst": "90", "cBenef": "SP040100" } },
          { "base": "229000", "name": "PIS",    "rate": "0.0165", "amount": "3800",
            "metadata": { "cst": "01" } },
          { "base": "229000", "name": "COFINS", "rate": "0.076",  "amount": "17400",
            "metadata": { "cst": "01" } }
        ],
        "total": "229000",
        "subtotal": "197400",
        "discounts": [],
        "taxes_value": "31600",
        "currency_code": "BRL",
        "discount_value": "0",
        "subtotal_before_taxes": "197400"
      }
    ],
    "shippingCost": [],
    "extraCharges": [],
    "discounts": [],
    "paymentMethods": [
      {
        "mid": "",
        "tid": "",
        "processor": "CREDIT_CARD",
        "card": {
          "bin": "MASTERCARD",
          "mask": "",
          "brand": "MASTERCARD",
          "holder": "",
          "card_country": "",
          "last_four_digits": "0000"
        },
        "acquirer": { "code": "00000000000000", "name": "ACQUIRER NAME" },
        "voucher": "",
        "metadata": {},
        "totalBill": 22.9,
        "currencyCode": "BRL",
        "exactPayment": false,
        "transactionId": "tx_a1b2c3d4",
        "referenceNumber": null,
        "transactionDate": {
          "date": "2026-04-17T15:41:55.000Z",
          "timeZoneName": "America/Sao_Paulo"
        },
        "transactionType": "",
        "authorizationCode": "000000000000",
        "paymentMethodCode": "",
        "transactionStatus": "APPROVED",
        "customerCashAmount": "0"
      }
    ],
    "metadata": {
      "fiscal": {
        "vBC":      "229000",
        "vNF":      "229000",
        "vCBS":     "1100",
        "vIBS":     "100",
        "vPIS":     "3800",
        "vDesc":    "0",
        "vICMS":    "9200",
        "vProd":    "229000",
        "vIBSUF":   "100",
        "vCOFINS":  "17400",
        "vIBSMun":  "0",
        "vTotTrib": "31600",
        "vBCIBSCBS":"198700"
      }
    }
  },
  "kds": {
    "metadata": {},
    "orderCode": "OC-br-001",
    "buzzerName": "Leonardo",
    "invoiceEmail": "",
    "invoicePrint": true
  },
  "metadata": {},
  "orderLines": [
    {
      "uid": "b9912637-eb44-4533-a1e5-f5bf2cdd07e8",
      "hash": "0d86fae2b5bc6198",
      "itemId": "39d1bd7fcd45c52f0c824364c2c0cfc402bd72b046cfaaec276a0131908dbf20",
      "itemType": "PRODUCT",
      "itemDescription": "Crunch Salad + Batata Pequena + 1 Tira + Refri",
      "quantity": "1",
      "selectedCurrency": "BRL",
      "updatedAt": "2026-05-06T01:22:59.663Z",
      "price": {
        "unitPrice": [
          {
            "taxes": [],
            "netPrice": "229000",
            "grossPrice": "229000",
            "currencyCode": "BRL",
            "discounts": [],
            "discountValue": "0",
            "taxesValue": "0",
            "subtotalBeforeTaxes": "229000"
          }
        ],
        "totalPrice": [
          {
            "taxes": [
              { "base": "229000", "name": "ICMS",   "rate": "0.04",   "amount": "9200",
                "metadata": { "cst": "90", "cBenef": "SP040100" } }
            ],
            "netPrice": "197400",
            "grossPrice": "229000",
            "currencyCode": "BRL",
            "discounts": [],
            "discountValue": "0",
            "taxesValue": "31600",
            "subtotalBeforeTaxes": "197400"
          }
        ]
      },
      "lineTotals": [ /* mesmo formato que price.totalPrice[n] */ ],
      "modifierGroups": [
        {
          "uid": "e247256ad628b0fd9c45453370e247fef1ad173829cc809c9c6930698d62e56b",
          "description": "Selecione: Escolha seus sanduíches!",
          "selectedModifiers": [
            {
              "itemId": "0104fdb2010be9ac14750a950f81c026b35a49a3c32b36281f41ef650d278b72",
              "itemType": "PRODUCT",
              "itemDescription": "CRUNCH SALAD",
              "quantity": "1",
              "selectedCurrency": "BRL",
              "price": { /* arrays unitPrice / totalPrice — mesmo formato */ },
              "modifierGroups": [],
              "metadata": {
                "redeemed": false,
                "externalCode": "80229#900002186#91198"
              }
            }
          ]
        }
      ],
      "metadata": {
        "fiscal": {
          "ncm": "21069090",
          "cfop": "5101",
          "csosn": "500",
          "vTotTrib": 3.16,
          "fiscalCategoryCode": "2106.90.90"
        },
        "redeemed": false,
        "externalCode": "80229",
        "referenceUnitPrice": null,
        "referenceTotalPrice": null
      }
    }
  ],
  "fulfillment": {
    "service": { "uid": "726c4892-48b9-45da-b066-2a8e83d2cb78", "code": "DINE_IN", "metadata": {} },
    "pickup": {
      "prepDate": "2026-05-06T01:22:59.028Z",
      "prepTime": "",
      "pickupDate": "2026-05-06T01:22:59.028Z",
      "propertyId": "a4019cad-bbac-4269-9f8d-f29654e92c45",
      "prepTimeUnit": "minute"
    },
    "delivery": {
      "city": "São Paulo",
      "country": "Brasil",
      "zipCode": "",
      "latitude": "0",
      "nickName": "HOME",
      "longitude": "0",
      "reference": "",
      "mainStreet": "",
      "propertyId": 1,
      "deliveryDate": null,
      "secondaryStreet": ""
    }
  }
}
Os valores monetários são strings expressas como unidades menores inteiras × 10000 (ex.: "229000" = 22.9000 BRL). Isso evita drift de ponto flutuante através de múltiplas integrações. Parseie com uma biblioteca decimal, nunca com parseFloat. A exceção é paymentMethods[].totalBill, que a origem às vezes envia como número JSON — trate ambos.

Referência de campos

Identificadores top-level

orderId
string
UUID interno do pedido no Fire. Estável através de entregas; use junto com event.id para rastreabilidade.
orderCode
string | null
Código curto legível mostrado em recibos e telas KDS (ex.: 95K, OC-br-001). null quando o canal não atribui um.
businessDayDate
string
Dia de negócio ao qual este pedido pertence, em YYYY-MM-DD. Calculado em hora local da loja, então um pedido feito às 01:00 pode pertencer ao dia de negócio anterior dependendo do corte de fim de dia.
externalOrderId
string
O ID de pedido tal como provido pelo canal/agregador na injeção. Use para reconciliar com sistemas upstream (POS, dashboards de agregador).
createdAt
string | null
Timestamp ISO 8601 UTC de quando o pedido foi originalmente feito. Distinto de event.createdAt, que é quando a execução do flow começou.
status
string
Sempre "COMPLETED" para este evento.
paymentStatus
string
Sempre "SUCCEEDED" para este evento.
redeemPoints
boolean
true se pontos de fidelidade foram resgatados neste pedido.
accumulatePoints
boolean
true se o cliente acumulou pontos de fidelidade.
discount
boolean
true se algum desconto foi aplicado.
orderComment
string
Nota free-text do cliente para o pedido inteiro. Empty string quando não definido.

data.store

store
object
Snapshot da loja no momento em que o pedido foi completado.

data.client

client
object | null
Cliente que fez o pedido. null para pedidos de canal totalmente anônimos. Para pedidos BR de “consumidor final”, client é populado com valores placeholder (govIdType: "FINAL_CONSUMER", govIdNumber: "00000000000").

data.payments

payments
object
Detalhamento de dinheiro.

data.fulfillment

fulfillment
object
Como o pedido é entregue.

data.kds

kds
object
Contexto do kitchen display.

data.device e data.operator

device
object
{ uid, name, platform, metadata.ip } — dispositivo de origem. Os campos podem ser null para canais não físicos.
operator
object
{ uid, name, session.uid } — staff/caixa que processou o pedido. Todos os campos null para canais self-service (quiosque, web).

data.orderLines

orderLines
object[]
Produtos pedidos. Totalmente camelCase (transformado pelo builder V4).

data.marketing, data.metadata, data.channel

marketing
object | null
Loyalty + cupons. null na maioria dos países hoje; reservado para uso futuro.
metadata
object
Bag free-form para extras a nível de pedido. Frequentemente {}.
channel
object
{ uid, code, metadata }. Exemplos de code: KIOSK, APP, IFOOD, RAPPI.

Dados fiscais

Os dados fiscais são incluídos apenas quando a loja tem emissão fiscal habilitada (store.storeFiscalConfig.enabled === true). Para países sem fiscal ou lojas sem configuração, todas as três localizações abaixo estão ausentes ou em null.
order.completed carrega informação fiscal em três localizações distintas. Cada uma serve um propósito diferente:

1. data.store.storeFiscalConfig — identidade do emissor e config do provedor

Identifica a entidade legal que emite o documento e como autenticar com o provedor fiscal. Credenciais NÃO estão aqui intencionalmente — o nó fiscal as busca por provedor/account.
"storeFiscalConfig": {
  "enabled": true,
  "company": {
    "govIdType":   "CNPJ",
    "govIdNumber": "00000000000000",
    "legalName":   "Sandbox LTDA",
    "tradeName":   "Sandbox"
  },
  "govIdType":            "CNPJ",
  "govIdNumber":          "00000000000000",
  "secondaryGovIdType":   "INSCRICAO_ESTADUAL",
  "secondaryGovIdNumber": "000000000000",
  "metadata": {
    "neverstop":    { "url": "", "enabled": false },
    "storeCode3S":  "50000001",
    "serialNumber": 1
  }
}

2. data.payments.metadata.fiscal — agregados fiscais a nível de pedido

Totais agregados estilo SEFAZ, prontos para envio ao provedor fiscal (seu provedor fiscal no Brasil). Os valores são strings × 10000.
"metadata": {
  "fiscal": {
    "vBC":      "229000",
    "vNF":      "229000",
    "vICMS":    "9200",
    "vPIS":     "3800",
    "vCOFINS":  "17400",
    "vCBS":     "1100",
    "vIBS":     "100",
    "vIBSUF":   "100",
    "vIBSMun":  "0",
    "vTotTrib": "31600",
    "vBCIBSCBS":"198700",
    "vDesc":    "0",
    "vProd":    "229000"
  }
}

3. data.orderLines[n].metadata.fiscal — classificação fiscal por linha

Códigos fiscais por produto. Usados pelo provedor fiscal para classificar cada linha no documento.
"metadata": {
  "fiscal": {
    "ncm":               "21069090",
    "cfop":              "5101",
    "csosn":             "500",
    "vTotTrib":          3.16,
    "fiscalCategoryCode":"2106.90.90"
  }
}
Além disso, metadata por imposto vive dentro de cada taxes[n].metadata (em payments.totals[].taxes[], orderLines[].price.totalPrice[].taxes[] e orderLines[].lineTotals[].taxes[]) com códigos como cst, cBenef, cClassTrib, reducao, rateNominal, rateEffective.

Variações por país

O exemplo acima é de uma loja brasileira com emissão fiscal habilitada — o caso mais complexo. O formato V4 é idêntico em todos os países; o que muda é quanto dado fiscal está populado. Hoje apenas o Brasil carrega os agregados por imposto / por linha (payments.metadata.fiscal, orderLines[n].metadata.fiscal, lineTotals[n].taxes[]). Outros países têm esses blocos presentes mas null / vazios.
As lojas brasileiras com storeFiscalConfig.enabled === true carregam o payload fiscal completo — veja a seção Dados fiscais acima. 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_*)

Tabela de referência rápida

Paíscountry.codeMoeda efetivagovIdType (formato)Agregados fiscais
BrasilBRBRLCNPJ (14 dígitos)Sim — agregados SEFAZ completos
ArgentinaARARSCUIT (XX-XXXXXXXX-X)Não — null / vazio
ChileCLCLPRUT (XXXXXXXX-X)Não
ColombiaCOCOPNIT (XXXXXXXXX-X)Não
EcuadorECUSD (moeda oficial do Equador)RUC (13 dígitos)Não
VenezuelaVEVESRIF (J-XXXXXXXX-X)Não
Outros paísesvariavariavariaNão
À medida que mais países tiverem um pipeline fiscal dedicado, seus eventos fiscais chegarão como fiscal.*.{cc} (ex.: fiscal.authorized.co, fiscal.authorized.ec). Até lá, apenas order.completed e order.cancelled disparam para lojas não-BR — os blocos fiscais permanecem null / vazios.

Handler de exemplo

async function onOrderCompleted(data) {
  const {
    orderId,
    externalOrderId,
    store,
    payments,
    orderLines,
    fulfillment,
    createdAt,
  } = data;

  // 1. Persiste para contabilidade / analítica
  await db.orders.upsert({
    where: { fireOrderId: orderId },
    create: {
      fireOrderId: orderId,
      externalOrderId,
      storeCode: store.code,
      country: store.locationInfo.country.code,
      currency: store.locationInfo.currencyCode,
      // payments.totals[0].total é "229000" unidades menores × 10000
      totalMinorUnits: BigInt(payments.totals[0]?.total ?? "0"),
      completedAt: new Date(createdAt ?? Date.now()),
      service: fulfillment.service.code,
    },
    update: {},
  });

  // 2. Se fiscal-enabled, despache para o pipeline fiscal
  if (store.storeFiscalConfig?.enabled) {
    await fiscalPipeline.enqueue({
      orderId,
      country: store.locationInfo.country.code,
      emitter: store.storeFiscalConfig.company,
      aggregates: payments.metadata?.fiscal,
      lines: orderLines.map((l) => ({
        itemId: l.itemId,
        ncm: l.metadata?.fiscal?.ncm,
        cfop: l.metadata?.fiscal?.cfop,
      })),
    });
  }

  // 3. Se delivery, despache para logística
  if (fulfillment.service.code === "DELIVERY" && fulfillment.delivery) {
    await dispatcher.send({
      orderId,
      address: fulfillment.delivery,
      items: orderLines,
    });
  }
}

Erros comuns

  • Decimais como strings × 10000. payments.totals[0].total === "229000" significa 22.9 BRL. Use uma biblioteca decimal; nunca com parseFloat.
  • O casing é misto em payments.totals[] e partes de paymentMethods[]. Leia tanto currencyCode quanto currency_code defensivamente. O builder V4 transforma a maior parte do snapshot mas passa os objetos de payment sem alteração.
  • fulfillment.delivery pode estar presente mesmo para serviços non-delivery com zeros placeholder. Sempre ramifique em fulfillment.service.code.
  • client pode ser um placeholder “FINAL_CONSUMER” populado em BR — não é null. Trate govIdType === "FINAL_CONSUMER" como anônimo para analítica.
  • event.id é o ID de execução do flow, não o ID do pedido. Use event.id para idempotência (muda por entrega), e orderId como chave de negócio.
  • Routing multi-tenant. Use store.account.uid, store.vendor.uid e store.code para rotear ao tenant correto no seu sistema, mesmo que o Fire já dê escopo ao flow do lado dele.

Eventos relacionados

order.cancelled

Dispara quando este pedido é cancelado depois.

order.invoiced

Apenas Brasil — dispara quando a SEFAZ autoriza o documento fiscal do pedido.