> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fire.rest/llms.txt
> Use this file to discover all available pages before exploring further.

# Solicitar numeração fiscal

> Obtém os identificadores fiscais que o ponto de venda precisa para imprimir o comprovante. É síncrono: chama-se depois de cobrar e antes de injetar o pedido.

O Fire resolve internamente qual provedor fiscal corresponde ao país da loja, pede a numeração e
devolve os dados prontos para imprimir.

<Info>
  **Três coisas antes de integrar:**

  1. **Aqui não há id de pedido.** Ao cobrar, o pedido ainda não existe no Fire. O `orderCode` é a
     única coisa que liga esta solicitação à venda, então precisa ser **a mesma string** que
     depois viaja na injeção.
  2. **A resposta não diz que o documento está autorizado.** Diz que há números para imprimir. A
     autorização do órgão chega depois, de forma assíncrona.
  3. **Você pede uma operação, não um tipo de documento.** `INVOICE` ou `CANCEL`. Com qual
     instrumento fiscal isso se materializa — nota de venda, nota de crédito, evento de
     cancelamento — quem decide é o país, e não é assunto do ponto de venda.
</Info>

## O fluxo completo

<Steps>
  <Step title="Você cobra">
    O cliente paga no PDV ou no quiosque.
  </Step>

  <Step title="Você pede a numeração">
    Você chama este endpoint. O Fire resolve a loja, o emitente e o provedor, e grava a
    solicitação **antes** de sair atrás dos números.
  </Step>

  <Step title="Você imprime">
    Conforme `printing.mode` você imprime o comprovante fiscal ou um ticket provisório.
  </Step>

  <Step title="Você injeta o pedido">
    Com o corpo de sempre, sem acrescentar nada. O Fire correlaciona a venda com sua numeração
    pelo `orderCode`.
  </Step>

  <Step title="O órgão autoriza">
    Minutos depois. O Fire recebe o resultado do provedor e atualiza o pedido. Se quiser ver,
    consulte esta mesma solicitação.
  </Step>
</Steps>

<Warning>
  **A Fire nunca te trava por conta própria.** Falhe o que falhar, este endpoint responde com
  uma decisão explícita em `policy.numberingFailure.action` — não com um erro que te deixa sem
  saber o que fazer.

  Mas a decisão **nem sempre é seguir**: a conta pode configurar que sem comprovante não se
  vende. Ramifique pelo `action`, nunca pelo código HTTP:

  * **`CONTINUE`** (o padrão) — imprima conforme `printing.mode` e injete o pedido. Se saiu
    sem numeração, **chame de novo com o mesmo `orderCode`**: nada completa sozinho, e um
    `202` que ninguém retenta fica assim para sempre.
  * **`REFUND`** — devolva a cobrança e **não injete o pedido**. Não há nada a completar
    depois: retentar a numeração de uma venda que você devolveu geraria um comprovante para
    algo que não aconteceu.

  Nos dois casos: não retenha a venda nem retente em loop com o cliente esperando.

  **Quantas vezes tentar de novo, no caminho `CONTINUE`: duas.** Enquanto `retryable` vier
  `true`, chame de novo com o mesmo `orderCode` até mais duas vezes. Se depois da segunda
  tentativa ainda não houver numeração, trate como definitivo: a venda já foi injetada com
  comprovante provisório, e o que falta se resolve pelo suporte, não no balcão.

  Com `REFUND` não há retentativa: zero. A venda foi devolvida, e numerá-la depois geraria um
  comprovante de algo que não aconteceu.

  **O limite é você quem aplica.** O Fire numera cada tentativa e guarda para o suporte, mas não
  corta por conta própria: se você chamar uma quarta vez, ele pergunta ao provedor de novo. E a
  resposta não vai mudar por insistir — `action` não depende de `retryable`, então o que a
  terceira tentativa disser, a primeira já dizia.
</Warning>

## Headers

<ParamField header="x-api-key" type="string" required>
  Sua API key do Fire, com a permissão **Fiscal Gateway (numbering)**.

  A conta e o vendor são derivados da key, **nunca do corpo**. Por isso o payload não leva
  `accountId` nem `vendorId`: uma credencial não pode mentir sobre a quem pertence.
</ParamField>

<ParamField header="Idempotency-Key" type="string" required>
  UUID que identifica **esta tentativa**. Gere uma vez por venda e reutilize nas retentativas
  dessa mesma venda.

  <Note>
    **Não é isso que evita o documento duplicado** — quem faz isso é o `orderCode`, que é a chave
    natural nas duas pontas: se você repetir o mesmo `orderCode`, recebe o mesmo documento mesmo
    gerando uma chave nova.

    O que esta chave acrescenta é **detectar que você a reutilizou para outra venda**: se a mesma
    chave chegar com um corpo diferente, o Fire responde `409` em vez de numerar. É uma proteção
    contra um bug do ponto de venda — não regerar a chave — que sem isso passaria despercebido.
  </Note>
</ParamField>

<ParamField header="x-correlation-id" type="string">
  **Opcional.** Um identificador seu para esta operação — o mesmo que você já usa nos seus logs.

  O Fire o guarda com a solicitação e o devolve em `correlationId`. Não muda nada do
  comportamento: serve para que, quando algo falhar, você possa cruzar o seu registro com o nosso
  sem ter que parear por horário e `orderCode`.

  Se você não enviar, `correlationId` vem `null`.
</ParamField>

## Corpo

É um **payload próprio**, não o da injeção de pedidos: só o que é necessário para numerar. Os
nomes coincidem com os que você já usa (`store`, `device`, `orderCode`) para que você o monte
recortando o que já tem, mas não envie o corpo completo do pedido — nada de `products`, `payments`
nem `shippingMethod`.

Cinco campos, e nenhum deles é um código do órgão.

<ParamField body="orderCode" type="string" required>
  Código da venda. É **a chave de idempotência**, a do Fire e a do provedor.

  Precisa ser único por conta e país, e **o mesmo** que você depois envia ao injetar o pedido. Se
  duas lojas da mesma conta usarem o mesmo `orderCode`, o Fire corta com `409` antes de emitir:
  sem esse corte, a segunda loja imprimiria o sequencial da primeira.
</ParamField>

<ParamField body="createdAt" type="string" required>
  Data e hora de criação do pedido.

  Tem dois usos, e convém não confundi-los. É o **fallback** da data de emissão — a fonte
  principal é o dia de negócio aberto da loja, porque uma venda de madrugada pertence ao dia que
  segue aberto, não ao do relógio — e além disso **viaja ao provedor fiscal** como a hora em que
  a venda aconteceu, para os regimes que a exigem no comprovante.

  Sem fuso horário (`2026-08-12 17:26:09`), é interpretada como **UTC**. Ao provedor sai sempre
  normalizada, com `Z`.
</ParamField>

<ParamField body="operation" type="string" default="INVOICE">
  O que se pede. Um de:

  * `INVOICE` — numerar a venda.
  * `CANCEL` — anular.

  **Você pede uma operação, não um tipo de documento.** Com qual instrumento fiscal isso se
  materializa quem decide é o país: no Equador um cancelamento é uma **nota de crédito** com sua
  própria série de sequenciais; no Brasil é um evento de cancelamento que não produz comprovante
  novo.

  <Note>
    **Para anular você manda o mesmo `orderCode` da venda**, com `operation: "CANCEL"`. Nada mais:
    nem chaves fiscais, nem o número do documento original, nem identificadores do Fire.

    O Fire encontra o documento a compensar pela chave natural —`país + orderCode + operação`— e
    devolve a qual corresponde em `document.compensates`. Seu ponto de venda **não precisa guardar
    nada nosso** para poder anular.
  </Note>
</ParamField>

<ParamField body="store" type="object" required>
  A loja que emite. Com `code`, o Fire resolve o país, a identidade fiscal do emitente e o
  estabelecimento — não os envie você.

  <Expandable title="store">
    <ParamField body="code" type="string" required>Código da loja no Fire (ex. `K004`).</ParamField>
  </Expandable>
</ParamField>

<ParamField body="device" type="object" required>
  O aparelho que emite. **É o mesmo bloco que você já manda na injeção de pedidos** — não é
  preciso acrescentar nada.

  <Expandable title="device">
    <ParamField body="uid" type="string" required>
      Identificador do aparelho. **É a única coisa que identifica o terminal.**
    </ParamField>

    <ParamField body="name" type="string">Nome do aparelho (`KIOSK`, `CAIXA 3`).</ParamField>
    <ParamField body="platform" type="string">`android`, `ios`, `web`… Informativo.</ParamField>

    <ParamField body="metadata" type="object">
      Chave-valor do aparelho (`ip`, e o que você precisar). Opaco: o Fire não interpreta.

      Viaja porque quando um caixa emite errado, saber de qual máquina saiu é a diferença entre
      consertar e adivinhar.
    </ParamField>
  </Expandable>

  <Note>
    **Não declare o ponto de emissão.** Antes havia um `externalId` com o qual o canal o
    informava; foi removido. Quem o atribui é o órgão sob o CNPJ/RUC do emitente, e o ponto de
    venda não fala essa língua: agora o provedor o resolve a partir do `uid`, igual ao que faz com
    `store.code`.

    Ele volta em `countryData.puntoEmision`, com o valor sob o qual foi efetivamente emitido.
  </Note>
</ParamField>

<ParamField body="totals" type="array">
  O que foi cobrado. **É o mesmo `payments.totals` que você já envia na injeção de pedidos**
  — envie tal como está, inteiro.

  <Expandable title="totals[] — o que o Fire usa para fiscalizar">
    <ParamField body="currencyCode" type="string">
      ISO 4217, o da loja: `USD` no Equador, `COP` na Colômbia, `BRL` no Brasil.
    </ParamField>

    <ParamField body="total" type="number">Total cobrado, impostos incluídos.</ParamField>
    <ParamField body="subtotalWithoutTaxes" type="number">Base de cálculo, antes dos impostos.</ParamField>
    <ParamField body="taxValue" type="number">Soma dos impostos.</ParamField>

    <ParamField body="taxes" type="array">
      Um elemento **por imposto**, com `name`, `base`, `rate` e `amount`. Sempre o array
      granular: há regimes que os declaram separadamente e não aceitam o total somado.

      O nome é o seu (`IVA`, `ICMS`, `PIS`…): traduzi-lo para o código do órgão é trabalho do
      provedor fiscal, não seu.
    </ParamField>
  </Expandable>

  <Note>
    **O que se envia hoje, por país:**

    | País     | Moeda | Impostos                                                  |
    | -------- | ----- | --------------------------------------------------------- |
    | Equador  | `USD` | `IVA` 15%                                                 |
    | Colômbia | `COP` | `IVA` 19%                                                 |
    | Brasil   | `BRL` | seis: `ICMS`, `PIS`, `COFINS`, `IBS_UF`, `IBS_MUN`, `CBS` |

    **Envie `taxes[]` com `amount`, não uma porcentagem solta.** Um elemento por imposto, com
    `name`, `base`, `rate` e `amount` — a mesma forma em todos os países.

    O valor tem de vir calculado por você, que foi quem cobrou e imprimiu. Onde o identificador
    fiscal é um hash da nota —o CUFE colombiano— derivá-lo da porcentagem obriga outra pessoa
    a arredondar, e se ela arredondar diferente do caixa, o identificador deixa de corresponder
    ao papel que o cliente tem.
  </Note>

  <Note>
    **Os valores vão sem escalar.** Envie o número tal como cobrou: `50000`, `42016.81`. Não o
    multiplique por 10.000.

    Essa escala existe, mas é de **outro caminho**: os eventos do pedido
    ([`order.completed`](/pt/events/order-completed) e os demais) levam os mesmos valores como
    inteiro em string ×10.000, porque é assim que o FIRE os armazena. Aqui não.

    Se você integra os dois caminhos, essa é a única conversão que precisa fazer — e fazê-la ao
    contrário significa declarar dez mil vezes o montante.
  </Note>

  <Note>
    **Envie o valor tal como cobrou e imprimiu.** O Fire não arredonda nem reformata: o número
    da requisição e o do comprovante são o mesmo.

    Importa porque há regimes em que o identificador fiscal é um **hash da nota** — o CUFE
    colombiano, por exemplo. Se o valor que entra no hash não é o impresso, o identificador não
    corresponde à nota que o cliente tem em mãos.
  </Note>
</ParamField>

<ParamField body="client" type="object">
  Quem comprou. **É o mesmo bloco que você já envia na injeção de pedidos: envie inteiro, tal
  como está.** Não recorte, não renomeie, não traduza.

  O Fire lê dali o que o regime do país precisa e descarta o resto. Que seja o bloco completo e
  não um subconjunto é de propósito: se cada país exigisse o seu próprio recorte, o ponto de
  venda teria de saber qual campo cada órgão olha — que é exatamente o que este contrato evita.

  <Expandable title="client — o que o Fire usa para fiscalizar">
    <ParamField body="govIdType" type="string">
      Tipo de documento. O Fire espera um de: **`FINAL_CONSUMER`** · **`CI`** · **`RUC`** ·
      **`CC`** · **`NIT`**.
    </ParamField>

    <ParamField body="govIdNumber" type="string">Número do documento.</ParamField>
    <ParamField body="name" type="string">Nome. Para empresas, a razão social está em `billingInformation.businessName`.</ParamField>

    <ParamField body="billingInformation" type="object">
      Dados de faturamento. Quando traz `govIdType`/`govIdNumber`, **têm prioridade** sobre os da
      raiz: é o documento que o cliente pediu para a sua nota.
    </ParamField>

    <ParamField body="additionalInfo.fiscal" type="object">
      Endereço fiscal do comprador, quando o regime exige para faturar a empresas.
    </ParamField>
  </Expandable>

  Os demais campos —`uid`, `email`, `phone`, `gender`, `birthdate`, `externalId`— trafegam e não
  são fiscalizados. O Fire **não os reenvia ao provedor fiscal**: não são assunto do órgão.

  <Note>
    **Os valores que o Fire espera em `govIdType`:**

    | Valor            | O que é                                                   | Onde     |
    | ---------------- | --------------------------------------------------------- | -------- |
    | `FINAL_CONSUMER` | venda sem comprador identificado — `govIdNumber` em zeros | todos    |
    | `CI`             | cédula de identidade                                      | Equador  |
    | `RUC`            | Registro Único de Contribuyentes                          | Equador  |
    | `CC`             | cédula de cidadania                                       | Colômbia |
    | `NIT`            | Número de Identificación Tributaria                       | Colômbia |

    **Hoje não há guard: mande o que mandar, a venda é numerada.** O campo trafega tal como
    está até o provedor fiscal, então um valor fora desta lista não quebra a numeração — chega
    a ele, que é quem tem de reconhecê-lo.

    Por isso convém se ater: um `CEDULA` onde vai `CI`, ou duas grafias diferentes para o
    consumidor final, são documentos que saem errados sem que nada falhe no caminho.
  </Note>

  <Note>
    **Consumidor final: envie os dois campos, sem traduzir nenhum.**

    ```json theme={null}
    "govIdType": "FINAL_CONSUMER",
    "govIdNumber": "00000000000"
    ```

    O número é você quem envia, igual a qualquer outra venda. O que **não** deve fazer é
    convertê-lo para o que cada regime exige: o NIT genérico `222222222222` da DIAN na Colômbia,
    a ausência de destinatário no Brasil. Isso é resolvido pelo provedor fiscal, que é quem
    está certificado perante o órgão.

    É deliberado: essa regra muda por país e por resolução do órgão, e não deveria obrigar você
    a fazer deploy do ponto de venda quando mudar.

    **O Fire também não mexe.** O bloco `client` trafega tal como está até o provedor: não
    preenchemos o número, não normalizamos e não validamos. O que você envia é o que ele recebe.
  </Note>
</ParamField>

<ParamField body="metadata" type="object">
  Chave-valor **da venda**: o que muda em cada transação e que algum país exige.

  É opaco para a sua integração: o Fire não interpreta, transporta. As chaves válidas dependem do
  país da loja e uma chave desconhecida é rejeitada com `400` — é preferível um erro do Fire a um
  campo inventado viajando até o órgão.

  Na maioria dos casos vai vazio: **o que é constante da loja não se manda aqui**, se configura
  uma vez (veja abaixo).
</ParamField>

### O que NÃO se manda: a configuração da loja

Tudo o que é **constante da loja** se configura uma única vez no backoffice e viaja sozinho: a
identidade fiscal do emitente, e um bloco **chave-valor por país** para os atributos que o
provedor daquele país precise.

<Info>
  Esse chave-valor vive na configuração fiscal da loja, **separado por país**. É a razão pela qual
  este endpoint é o mesmo em todo lugar: o que é específico de cada país se administra, não se
  programa nem se envia em cada venda.

  Se a sua integração começar a precisar de um campo novo por país, a resposta quase sempre é
  configurá-lo ali — não acrescentá-lo ao payload.
</Info>

<ParamField body="referencedFiscalRequestId" type="string">
  Só para `CANCEL`, e só quando a resolução automática não basta: um cancelamento que referencia
  um documento de outro pedido, ou várias notas para o mesmo.

  **No caso normal não envie.** O Fire encontra o original pela chave natural, então seu ponto de
  venda não precisa guardar nenhum identificador nosso para poder anular.
</ParamField>

## Resposta

<ResponseField name="fiscalRequestId" type="string">
  Identificador da solicitação no Fire. É com ele que você consulta o desfecho depois.
</ResponseField>

<ResponseField name="orderCode" type="string">Eco do código que você enviou.</ResponseField>

<ResponseField name="correlationId" type="string">
  Eco do header `x-correlation-id`, ou `null` se você não mandou. É para rastreabilidade: não
  participa da numeração nem da idempotência.
</ResponseField>

<ResponseField name="reused" type="boolean">
  `true` se esta solicitação já existia e foi devolvida como estava, sem numerar de novo.
</ResponseField>

<ResponseField name="requestStatus" type="string">
  Status **da numeração**: consegui números para imprimir?

  Cinco valores possíveis. Os quatro primeiros descrevem como terminou a tentativa; o quinto diz
  que não houve tentativa porque esta loja não numera.

  | Valor              | O que aconteceu                                                      | HTTP  |
  | ------------------ | -------------------------------------------------------------------- | ----- |
  | `GENERATED`        | Há números. Imprima o comprovante fiscal                             | `201` |
  | `PENDING`          | **Não se sabe.** O provedor não respondeu — pode ter numerado        | `202` |
  | `FAILED_RETRYABLE` | O provedor disse "agora não". Você pode tentar de novo (até 2 vezes) | `202` |
  | `FAILED_FINAL`     | O provedor disse "não" definitivo. Tentar de novo não adianta        | `200` |
  | `NOT_APPLICABLE`   | Esta loja não tem numeração fiscal. **Não é um erro**                | `200` |

  <Warning>
    **`PENDING` não significa "não há comprovante": significa "não sabemos".** A comunicação caiu e
    o provedor pode ter numerado, consumido um sequencial e emitido o documento sem que a gente
    fique sabendo.

    Tente de novo **com o mesmo `orderCode`**. O Fire retoma a solicitação e volta a perguntar ao
    provedor; se da primeira vez numerou, você recebe esse mesmo documento em vez de um novo.
    Numerar de novo com outro `orderCode` seria declarar a mesma venda duas vezes ao órgão.
  </Warning>

  <Note>
    `NOT_APPLICABLE` é o único que **não é gravado**: não cria solicitação fiscal
    (`fiscalRequestId: null`) e não aparece nos eventos do pedido. Existe porque o PDV sempre chama
    este endpoint — é assim que ele descobre se a loja numera — e responder com um erro faria cada
    venda de uma loja sem gateway parecer uma falha.
  </Note>
</ResponseField>

<ResponseField name="documentStatus" type="string">
  Status do **documento perante o órgão**: ele autorizou?

  `PENDING` · `AUTHORIZED` · `REJECTED` · `CANCELLED`

  <Note>
    Nesta resposta é **sempre** `PENDING`: há números, não há veredicto. Só o resultado do
    provedor o move, e ele chega depois. Colapsar os dois status em um é o erro que faz um PDV
    achar que uma venda está autorizada quando ela apenas está numerada.
  </Note>
</ResponseField>

<ResponseField name="environment" type="string">
  Em qual ambiente o **Fire** numerou: `SANDBOX` ou `PRODUCTION`.

  É nosso, não do órgão. Sai da configuração fiscal da conta —que é por vendor e por país, então a
  mesma conta pode ter o Equador em produção e a Colômbia em sandbox— e fica congelado na
  solicitação: se amanhã a configuração mudar, este valor continua dizendo com o que **esta** venda
  foi numerada.

  <Warning>
    **Não confunda com o ambiente do órgão**, que viaja dentro de `countryData` com o vocabulário
    do país (`ambiente: "PRUEBAS" | "PRODUCCION"` no Equador). São dois fatos distintos: um diz
    contra qual configuração o Fire emitiu, o outro o que o órgão declarou. Normalmente coincidem
    — e quando não, é exatamente isso que você precisa poder ver, por isso um não se deduz do
    outro.
  </Warning>

  `null` quando `requestStatus` é `NOT_APPLICABLE`: nada foi numerado, então não houve ambiente em
  que numerar.
</ResponseField>

<ResponseField name="document" type="object">
  O que você precisa para imprimir, **sem saber de países**. `null` se nada foi numerado.

  <Expandable title="document">
    <ResponseField name="documentType" type="string">
      `SALE_INVOICE` ou `CREDIT_NOTE`. Vocabulário do Fire: diz qual operação é, não com qual
      instrumento o país a materializa.
    </ResponseField>

    <ResponseField name="documentLabel" type="string">
      **Como é intitulado no comprovante**: `FACTURA`, `NOTA DE CREDITO`. Quem traduz é o Fire — o
      instrumento fiscal é definido pelo regime, e não queremos que cada canal carregue o seu mapa.
    </ResponseField>

    <ResponseField name="documentNumber" type="string">
      Número visível, **tal como o provedor o compõe** conforme a convenção do seu país
      (`001-020-000000123`). É para **imprimir**: para buscar ou conciliar use os identificadores
      de `countryData`.

      No Equador é o eco de `countryData.numeroComprobante`. O Fire não o recompõe nem lhe muda o
      formato — a regra é do regime, não nossa.
    </ResponseField>

    <ResponseField name="authorizationMode" type="string">
      `ONLINE` · `OFFLINE` · `BATCH`. Vocabulário do Fire.
    </ResponseField>

    <ResponseField name="authorizationLabel" type="string">
      **Como é impresso**: `EMISION NORMAL`, `EMISION POR CONTINGENCIA`. Mesma razão de
      `documentLabel`.
    </ResponseField>

    <ResponseField name="issuedAt" type="string">Data de emissão.</ResponseField>

    <ResponseField name="compensates" type="object">
      **Qual documento este anula.** Somente em notas de crédito; `null` em uma nota de venda.

      ```json theme={null}
      {
        "documentNumber": "005-004-000000068",
        "issuedAt": "2026-08-14T18:31:57.649Z",
        "reason": "ORDER_CANCELLATION",
        "reasonLabel": "Anulación de pedido"
      }
      ```

      <Expandable title="compensates">
        <ResponseField name="documentNumber" type="string">
          Número visível do documento original. No Equador é impresso como
          `N. FACTURA MODIFICADA`.
        </ResponseField>

        <ResponseField name="issuedAt" type="string">
          Quando o original foi emitido. É impresso como `FECHA EMISION FAC.` — é diferente da data
          da nota de crédito, que está um nível acima.
        </ResponseField>

        <ResponseField name="reason" type="string">
          Por que está sendo anulado. Vocabulário do Fire. Hoje só existe `ORDER_CANCELLATION`: o
          cancelamento do pedido inteiro.
        </ResponseField>

        <ResponseField name="reasonLabel" type="string">
          Como o motivo é impresso. **Cada empresa o redige** na sua configuração: o órgão exige
          que a nota de crédito traga um motivo, mas não dita o texto.
        </ResponseField>
      </Expandable>

      É um bloco **universal**: todo cancelamento, em qualquer país, referencia o documento que
      modifica. O que muda por país é como ele é rotulado ao imprimir, não o conceito — por isso
      vive aqui e não em `countryData`.
    </ResponseField>
  </Expandable>

  <Note>
    **`sequential` e `serie` não estão mais aqui.** São peças com forma de país —no Equador a série
    são seis dígitos que se partem ao meio— e vivem em `countryData` com o nome que o órgão delas
    lhes dá. Em `document` ficou só o que significa o mesmo em todo lugar.
  </Note>
</ResponseField>

<ResponseField name="countryData" type="object">
  **Os identificadores do país, no vocabulário do seu órgão e prontos para imprimir.**

  <CodeGroup>
    ```json Equador (EC) — SRI theme={null}
    {
      "numeroComprobante": "001-020-000000123",
      "claveAcceso": "1208202601179141513200110010200000001231234567813",
      "establecimiento": "001",
      "puntoEmision": "020",
      "secuencial": "000000123",
      "ambiente": "PRODUCCION"
    }
    ```

    ```json Colômbia (CO) — DIAN theme={null}
    {
      "numeroComprobante": "SETP990000001",
      "cufe": "9c4f1e… (96)",
      "prefijo": "SETP",
      "numeroDian": "990000001",
      "qrCode": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=9c4f1e…",
      "ambiente": "PRODUCCION"
    }
    ```
  </CodeGroup>

  <Note>
    **O bloco muda inteiro conforme o país, e os rótulos também.** Na Colômbia
    `documentLabel` é `FACTURA ELECTRONICA DE VENTA` e `authorizationLabel` é
    `VALIDACION PREVIA` — são os nomes da DIAN, não uma variante do texto equatoriano.

    `ambiente` chega traduzido nos dois países, e aí está o ponto: a DIAN codifica `1` como
    produção e o SRI como homologação. O Fire resolve isso para que nenhum canal precise
    carregar essa tabela.
  </Note>

  É um **mapa aberto**: as chaves são definidas pelo regime de cada país, não por este contrato. Um
  país novo entra sem que a forma da resposta mude.

  <Note>
    **Os valores vêm traduzidos, não em código do órgão.** O provedor manda `ambiente: "2"` —é
    assim que o SRI define— e aqui chega `"PRODUCCION"`, que é o que o ticket diz. Traduzir do lado
    do canal significaria que cada integrador carrega sua cópia da tabela do órgão, e o primeiro
    que copiar errado imprime "PRUEBAS" numa nota de produção.
  </Note>

  <Warning>
    **Não procure campos fixos: percorra as chaves que vierem.** O Equador traz `claveAcceso`, o
    a Colômbia `cufe`, o Brasil `chaveAcesso`. Um canal que leia
    `countryData.claveAcceso` direto funciona no Equador e quebra no segundo país.
  </Warning>
</ResponseField>

### `countryData` por país

Hoje o gateway numera no **Equador** e na **Colômbia**. Cada país que entra soma sua aba aqui — e só isso: a forma
da resposta não muda, porque o bloco é aberto.

<Tabs>
  <Tab title="Equador (EC) · disponível">
    Comprovantes do **SRI**.

    | Chave               | Tipo   | Sempre | Notas                                                                           |
    | ------------------- | ------ | ------ | ------------------------------------------------------------------------------- |
    | `numeroComprobante` | string | ✓      | O número **visível**, já composto: `estab-ptoEmi-secuencial`                    |
    | `claveAcceso`       | string | ✓      | 49 dígitos. É também o que se codifica no QR                                    |
    | `establecimiento`   | string | ✓      | 3 dígitos. O provedor o resolve a partir de `store.code`                        |
    | `puntoEmision`      | string | ✓      | 3 dígitos. O provedor o resolve a partir de `device.uid`                        |
    | `secuencial`        | string | ✓      | 9 dígitos. A nota de venda e a de crédito seguem **sequências distintas**       |
    | `ambiente`          | string | ✓      | `PRUEBAS` ou `PRODUCCION` — **já traduzido**; o SRI o define como `"1"` / `"2"` |

    ```json theme={null}
    {
      "numeroComprobante": "001-020-000000123",
      "claveAcceso": "1208202601179141513200110010200000001231234567813",
      "establecimiento": "001",
      "puntoEmision": "020",
      "secuencial": "000000123",
      "ambiente": "PRODUCCION"
    }
    ```

    <Note>
      **Quem compõe o número é o provedor, não o Fire.** O formato é do regime —quinze dígitos em
      três trechos, art. 18 do Reglamento de Comprobantes de Venta— e quem o conhece é quem está
      certificado perante o SRI. Se o regime mudar a convenção, muda lá e não é preciso que o
      Fire faça deploy.

      `document.documentNumber` é um **eco** deste mesmo valor, para que você não tenha que
      entrar no bloco do país só para imprimir. É o mesmo fato, não dois.
    </Note>

    <Warning>
      **As três peças soltas não são um substituto.** O Reglamento permite omitir os zeros à
      esquerda do sequencial, então `001-020-123` pode ser tão legal quanto `001-020-000000123`.
      Compor o número você mesmo a partir de `establecimiento`, `puntoEmision` e `secuencial` é
      adotar uma convenção que não lhe cabe: imprima `numeroComprobante` tal como chega.
    </Warning>
  </Tab>

  <Tab title="Colômbia (CO) · disponível">
    Comprovantes da **DIAN**.

    | Chave               | Tipo   | Sempre | Notas                                                                               |
    | ------------------- | ------ | ------ | ----------------------------------------------------------------------------------- |
    | `numeroComprobante` | string | ✓      | O número **visível**, já montado: `prefixo + consecutivo`                           |
    | `cufe`              | string | ✓      | 96 caracteres hexadecimais (SHA-384). É o identificador do documento perante a DIAN |
    | `prefijo`           | string | ✓      | Prefixo da faixa de numeração autorizada por resolução                              |
    | `numeroDian`        | string | ✓      | Somente o consecutivo, sem o prefixo                                                |
    | `qrCode`            | string | ✓      | URL do catálogo da DIAN. É o que se imprime como QR                                 |
    | `ambiente`          | string | ✓      | `PRUEBAS` ou `PRODUCCION` — **já traduzido**; a DIAN o define como `"1"` / `"2"`    |

    ```json theme={null}
    {
      "numeroComprobante": "SETP990000001",
      "cufe": "9c4f1e… (96 caracteres hexadecimais)",
      "prefijo": "SETP",
      "numeroDian": "990000001",
      "qrCode": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=9c4f1e…",
      "ambiente": "PRODUCCION"
    }
    ```

    <Warning>
      **`ambiente` chega traduzido, e ainda bem.** A DIAN usa `1` para produção e `2` para
      homologação — **o contrário do SRI**. O Fire resolve isso aqui para que nenhum canal
      precise carregar sua própria cópia da tabela: o primeiro que copiar do lado errado
      imprime "PRUEBAS" numa nota real.
    </Warning>

    <Note>
      **`numeroComprobante` e `numeroDian` não são a mesma coisa.** O primeiro é o número
      visível completo, tal como vai impresso; o segundo é só o consecutivo. Os dois chegam
      resolvidos pelo provedor — o Fire não concatena nada, igual ao Equador.

      `document.documentNumber` é um **eco** de `numeroComprobante`, para imprimir sem entrar
      no bloco do país.
    </Note>

    <Warning>
      **Não existe `graphic` na Colômbia.** O QR é a URL do catálogo da DIAN e vive em
      `countryData.qrCode`. Um canal que espere `graphic.qr` como no Equador não acha nada.
    </Warning>

    <Note>
      **Só CUFE, sem CUDE.** Emitimos a nota fiscal eletrônica de venda, que leva CUFE. O
      "documento equivalente P.O.S." leva CUDE e hoje não é emitido.
    </Note>
  </Tab>

  <Tab title="Outros países · quando entrarem">
    Um país entra com seu adaptador, e com ele chegam suas chaves e sua aba. A forma da resposta
    **não muda**: `countryData` continua sendo o mesmo mapa aberto.

    O que muda é o vocabulário, e por isso não convém indexar chaves fixas: o Equador fala
    de `claveAcceso` e a Colômbia de `cufe`, para o mesmo fato. O Brasil dirá
    `chaveAcesso`. São exemplos de como cada regime nomeia, não um contrato já disponível.

    <Warning>
      **Se a sua integração opera em mais de um país, percorra as chaves.** Um canal que leia
      `countryData.claveAcceso` direto funciona no Equador e já quebra na Colômbia.
    </Warning>
  </Tab>
</Tabs>

<ResponseField name="store" type="object">
  A **filial** que emite, para o cabeçalho do comprovante.

  <Expandable title="store">
    <ResponseField name="code" type="string">Código de loja do negócio.</ResponseField>
    <ResponseField name="name" type="string">Nome da loja.</ResponseField>

    <ResponseField name="address" type="string">
      Endereço da filial. **Não é o da matriz** — o comprovante equatoriano imprime os dois, e são
      diferentes.
    </ResponseField>

    <ResponseField name="city" type="string">Cidade.</ResponseField>
    <ResponseField name="phone" type="string">Telefone.</ResponseField>
    <ResponseField name="govIdType" type="string">Tipo de identificação fiscal da filial.</ResponseField>
    <ResponseField name="govIdNumber" type="string">Identificação fiscal da filial.</ResponseField>
    <ResponseField name="secondaryGovIdType" type="string">Identificação secundária, se aplicável.</ResponseField>
    <ResponseField name="secondaryGovIdNumber" type="string">Valor da anterior.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="company" type="object">
  A **pessoa jurídica** que emite: o cabeçalho e o rodapé do comprovante, já resolvidos.

  <Expandable title="company">
    <ResponseField name="legalName" type="string">Razão social.</ResponseField>
    <ResponseField name="tradeName" type="string">Nome fantasia.</ResponseField>
    <ResponseField name="govIdType" type="string">Tipo de identificação (`RUC`, `CNPJ`…).</ResponseField>
    <ResponseField name="govIdNumber" type="string">Identificação da empresa.</ResponseField>

    <ResponseField name="headquartersAddress" type="string">
      Endereço da **matriz**, diferente do da filial.
    </ResponseField>

    <ResponseField name="countryLines" type="array">
      O que o regime exige no cabeçalho, **já rotulado e ordenado**:

      ```json theme={null}
      [
        { "key": "granContribuyente", "label": "GRAN CONTRIBUYENTE", "value": "NAC-GCFOIOC21-00000900-E" },
        { "key": "contribuyenteEspecial", "label": "CONTRIBUYENTE ESPECIAL", "value": "155" },
        { "key": "obligadoContabilidad", "label": "Obligado a llevar contabilidad", "value": "SI" }
      ]
      ```

      Vem com `label` porque o comprovante o imprime literalmente. Se o rótulo fosse posto por cada
      canal, dois caixas da mesma marca imprimiriam diferente. **Percorra a lista e desenhe**: você
      não precisa saber o que significa "gran contribuyente", só onde colocá-lo.
    </ResponseField>

    <ResponseField name="legends" type="array">
      Os textos do rodapé, **em ordem e já interpolados**:

      ```json theme={null}
      [
        { "key": "avisoCambios", "text": "Estimado cliente: Por favor verifique los datos…" },
        { "key": "facturaElectronica", "text": "…con la Clave de Acceso: 1408…7811" }
      ]
      ```

      A `key` é estável e escolhida por quem os carrega: se você preferir os seus próprios textos,
      indexe por ela e ignore o nosso.

      Uma legenda que interpola um dado que falta **não viaja**: meia legenda com um marcador cru
      impresso é pior do que não imprimi-la.
    </ResponseField>

    <Warning>
      **Sem comprovante não viajam `countryLines` nem `legends`.** São atributos do
      comprovante, não da empresa: o fisco os exige *na* nota. Quando a numeração não produz
      documento —`PENDING`, `FAILED_RETRYABLE`, `FAILED_FINAL`— os dois chegam como `[]`.

      A **identidade** chega completa (`legalName`, `tradeName`, `govIdType`, `govIdNumber`,
      `headquartersAddress`): o ticket provisório precisa de cabeçalho com quem vendeu.

      Sem essa regra, um provisório imprimia "verifique os dados da sua nota, alterações só
      são aceitas no mesmo dia da emissão" sobre um papel que **não é uma nota**, e declarava
      um "GRAN CONTRIBUYENTE" num documento que não declara nada.
    </Warning>
  </Expandable>

  <Note>
    **`store`, `company` e `document.compensates` vêm em toda resposta deste endpoint**,
    incluindo `NOT_APPLICABLE` e o `400` de loja que não pode emitir, inclusive
    na da retentativa idempotente — o canal precisa do cabeçalho tanto na primeira vez quanto
    quando repete por uma queda de rede.

    As **consultas** (`GET` por `fiscalRequestId` ou `orderCode`) os devolvem em `null`: são
    resolvidos ao emitir e não são gravados com a solicitação. Se a sua integração precisar deles
    para reimprimir, use [os dados de impressão](/pt/api-reference/fiscal-print).
  </Note>
</ResponseField>

<ResponseField name="graphic" type="object">
  Chave → **string exata a codificar**, pronta para renderizar. Por exemplo
  `{ "qr": "1208202601…811" }`.

  É um mapa aberto porque o comprovante de cada país não leva sempre a mesma coisa, e um país pode
  precisar de mais de um elemento. **Percorra as chaves que vierem**, não procure campos fixos.

  O Fire não gera imagens: o tamanho e a resolução dependem da sua impressora, e isso só quem
  imprime sabe.
</ResponseField>

<ResponseField name="printing" type="object">
  O que você pode imprimir. **É uma regra legal do país, não uma derivação de haver documento**:
  por isso quem resolve é o Fire e não cada canal.

  <Expandable title="printing">
    <ResponseField name="printable" type="boolean">Se você pode entregar o comprovante fiscal.</ResponseField>

    <ResponseField name="mode" type="string">
      **Que papel sai da impressora.** Três valores, fechados.

      | valor                 | o que você imprime                        | quando                                                    |
      | --------------------- | ----------------------------------------- | --------------------------------------------------------- |
      | `FISCAL_DOCUMENT`     | O comprovante fiscal, com os seus números | Há numeração (`GENERATED`) e o país permite entregá-lo    |
      | `PROVISIONAL_RECEIPT` | Um comprovante **não fiscal**             | Ainda não há numeração, ou o órgão rejeitou               |
      | `NONE`                | Nada                                      | Esta loja não tem representação fiscal (`NOT_APPLICABLE`) |
    </ResponseField>

    <ResponseField name="reason" type="string">
      **Por que esse modo**, para você poder explicar ao caixa. `null` quando `mode` é
      `FISCAL_DOCUMENT` — o caso normal não precisa de justificativa.

      | valor                       | o que aconteceu                                        |
      | --------------------------- | ------------------------------------------------------ |
      | `ISSUED_OFFLINE`            | O país permite emitir sem conexão e regularizar depois |
      | `AWAITING_FISCAL_NUMBERING` | Ainda não há números: foram pedidos e não chegaram     |
      | `FISCAL_REJECTED`           | O órgão ou o provedor disseram não                     |
      | `NUMBERING_DISABLED`        | Este vendor não numera — não é um erro                 |
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="policy" type="object">
  **O que fazer com a venda quando não deu para numerar.** Quem decide é a conta, não você: se
  configura por vendor no backoffice e a Fire devolve a decisão já tomada, igual a `printing`.

  Viaja **sempre**, inclusive quando a numeração deu certo. Ramifique pelo valor, nunca pela
  presença da chave.

  <Note>
    **O que esta política decide, e o que não decide.**

    Decide **uma única coisa**: se o caixa devolve o dinheiro ao cliente quando a venda foi
    cobrada e não deu para numerar. Nada mais.

    Não decide o que você imprime — isso é `printing`, e é uma regra legal do país, não uma
    preferência de ninguém. Não bloqueia vendas: quando você pede a numeração o cliente **já
    pagou**, então não há venda para bloquear. E não depende de `retryable`: uma falha que se
    resolve sozinha continua sendo uma falha, e se a conta configurou devolver, devolve-se.

    **Quem configura é a conta**, por país e por vendor, no backoffice. Você não deduz nem
    negocia: a Fire devolve resolvido, igual a `printing`. Se não estiver configurado, se trouxer
    um valor que não reconhecemos, ou se não conseguimos ler, aplica-se `CONTINUE` — o padrão
    aponta para esse lado de propósito, porque uma configuração mal escrita **não pode** disparar
    devoluções de dinheiro.

    **Dois casos a ignoram por completo**, não importa como esteja configurada: quando não houve
    falha (`GENERATED` ou `NOT_APPLICABLE`), e quando o que falhou foi um cancelamento
    (`operation: "CANCEL"`) — ali o pedido existe e o dinheiro dele não foi devolvido, então não
    há o que devolver.

    Os outros dois campos são o **recibo** da decisão: `configVersion` diz com qual configuração
    se decidiu e `resolvedFrom` com qual contexto. Servem para reconstruir uma devolução de três
    semanas atrás mesmo que hoje a conta esteja configurada de outro jeito.
  </Note>

  <Expandable title="policy.numberingFailure">
    <ResponseField name="action" type="string">
      **O único campo que você precisa ler.** Enum fechado de dois valores, e não vão crescer
      sem aviso.

      | valor      | o que você faz                                                               | o que você NÃO faz      |
      | ---------- | ---------------------------------------------------------------------------- | ----------------------- |
      | `CONTINUE` | Imprime conforme `printing.mode` e injeta o pedido                           | Não devolve dinheiro    |
      | `REFUND`   | Devolve a cobrança e [reporta a venda perdida](/pt/api-reference/lost-sales) | **Não injeta o pedido** |

      `CONTINUE` é o padrão: é o que sai sem configurar, com a configuração quebrada, e em todo
      caso em que não houve falha.

      `CONTINUE` → siga como sempre: imprima conforme `printing.mode` e injete o pedido.

      `REFUND` → devolva a cobrança no balcão e **não injete o pedido**. Depois reporte com
      [Registrar venda perdida](/pt/api-reference/lost-sales).

      Não existe um valor para "bloqueie a venda": quando você pede a numeração o cliente **já
      pagou**. Não há venda para bloquear — o que resta decidir é se você devolve o dinheiro.
    </ResponseField>

    <ResponseField name="lostSaleReason" type="string">
      Com qual `reason` reportar essa venda. Copie tal como está — assim você nunca precisa
      conhecer o nosso catálogo, e no dia em que adicionarmos uma causa você não mexe em código.

      **É um enum fechado, e hoje tem um único valor:**

      | valor                     | o que aconteceu                                  |
      | ------------------------- | ------------------------------------------------ |
      | `FISCAL_NUMBERING_FAILED` | A venda foi cobrada e não foi possível numerá-la |

      Este campo **é** o `reason` de
      [Registrar venda perdida](/pt/api-reference/lost-sales): você passa sem transformar. Não há
      endpoint para consultar o catálogo, e isso é de propósito — enquanto for um enum deste
      tamanho, exigir uma chamada a mais para descobrir um valor que já estamos mandando nesta
      resposta seria trabalho sem benefício. Se um dia crescer o suficiente para valer a pena, o
      catálogo vira um endpoint e este campo não muda.

      Por isso mesmo: **ramifique pelo valor só se precisar fazer algo diferente por causa.**
      Para reportar, copie. Um canal que hoje fixa `FISCAL_NUMBERING_FAILED` no código em vez de
      ler daqui funciona igual — há um único valor — e quebra em silêncio no dia em que houver
      dois.

      `null` quando essa venda **não pode terminar sem pedido**: a numeração deu certo, ou o que
      falhou foi um cancelamento — ali o pedido existe e o dinheiro dele não foi devolvido.
    </ResponseField>

    <ResponseField name="configVersion" type="string">
      Impressão digital da configuração com que se decidiu, tipo `fnv1a:d096701f`. Serve para o
      mesmo que o hash de um deploy: você pega uma devolução de três semanas atrás e sabe com
      qual configuração foi decidida, mesmo que hoje seja outra.

      **`null` significa que a conta não configurou nada** e o padrão foi aplicado.
    </ResponseField>

    <ResponseField name="resolvedAt" type="string">Quando foi resolvido.</ResponseField>

    <ResponseField name="resolvedFrom" type="object">
      O contexto **avaliado**: `requestStatus`, `operation`, `retryable` e — se o provedor
      respondeu — `failureCode` e `failureScope`.

      É um recibo forense, não a regra. **Nenhum desses campos decide nada**: a decisão vem do
      que a conta configurou. Existem para que a decisão possa ser reconstruída mesmo depois de
      a configuração mudar.
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  **Onde se configura e o que acontece sem isso.** A política é definida por conta, país e
  vendor. Se o vendor não tem, se traz um valor que não reconhecemos, ou se não conseguimos ler,
  aplica-se **`CONTINUE`** — e esse padrão aponta para esse lado de propósito: uma configuração
  mal escrita **não pode** disparar devoluções. Você vê isso como `configVersion: null`.
</Note>

<Warning>
  **Cancelamentos nunca pedem devolução.** Se o que falhou foi um `operation: "CANCEL"`, a
  resposta traz `CONTINUE` independentemente da configuração: não há cobrança a estornar, porque
  a venda já aconteceu e continua válida. O que falta é o documento do cancelamento.

  **`PENDING` obedece sim à configuração.** O provedor não ter respondido não é uma exceção:
  para o caixa, não ter número é não ter comprovante. Você distingue de uma recusa **apenas** por
  `resolvedFrom.requestStatus`. Um `PENDING` traz `failureCode` como qualquer outro — um timeout
  chega como `PROVIDER_TIMEOUT` / `TECHNICAL` — então não procure na ausência do código.

  Tem uma consequência que vale ter em mente: o provedor **pode ter numerado mesmo assim** e não
  ter conseguido avisar. Se esse documento aparecer depois, vai existir um comprovante de uma
  venda que você devolveu, e ele precisa ser cancelado.
</Warning>

### O que fazer quando chega `REFUND`

Três passos, nesta ordem. O terceiro é o que se esquece.

<Steps>
  <Step title="Devolva a cobrança no balcão">
    O cliente já pagou. Essa devolução é você quem faz com o seu meio de pagamento — a Fire não
    movimenta dinheiro nem sabe se você devolveu.
  </Step>

  <Step title="Não injete o pedido">
    Não mande para [Criar pedido](/pt/api-reference/orders). Essa venda não aconteceu: injetá-la
    deixaria um pedido cobrado sem comprovante fiscal, o que é pior do que não tê-lo.
  </Step>

  <Step title="Reporte com Registrar venda perdida">
    `POST /orders/lost-sales`, copiando `policy.numberingFailure.lostSaleReason` em `reason`.
    É o único passo que nos avisa.
  </Step>
</Steps>

<Warning>
  **Se você pular o passo 3, essa venda não existe em lugar nenhum.**

  Não há pedido —você não injetou— e não há evento. Do nosso lado só fica a solicitação fiscal
  que falhou, que diz que não deu para numerar mas **não diz que houve dinheiro envolvido nem
  que você devolveu**. Ninguém fica sabendo que aquela loja parou de vender, e o fechamento de
  caixa não consegue explicar.

  O reporte é a única trilha. Retentar é seguro — é idempotente por `orderId` + vendor — então
  se você ficou sem rede bem ali, acumule e reenvie.
</Warning>

### Quando o que falha é um cancelamento

Cancelar são **duas chamadas, nesta ordem**: primeiro você pede aqui a numeração da nota de
crédito (`operation: "CANCEL"`), e só depois chama
[Cancelar pedido](/pt/api-reference/cancel-order).

Se a numeração da nota falha, este endpoint responde **como sempre**: nunca um `4xx`. `PENDING`
e `FAILED_RETRYABLE` voltam `202`; `FAILED_FINAL` volta `200`. O corpo traz o `failure` com o
motivo e o `fiscalRequestId` para escalar.

E **`policy.numberingFailure.action` vem sempre `CONTINUE`, com `lostSaleReason: null`**,
independentemente de como a conta esteja configurada. Não é uma exceção arbitrária: aqui não há
cobrança a estornar. A venda já aconteceu, está em `orders` e continua válida — o que falta é o
papel do cancelamento, não o dinheiro.

<Warning>
  **Mas o pedido não é cancelado.** O cancel valida que a nota de crédito exista, e sem ela
  responde `409 FISCAL_CREDIT_NOTE_MISSING`.

  Essa é a grande diferença em relação a uma venda: na venda a falha te deixa seguir com um
  ticket provisório; no cancelamento te deixa **travado**, com o pedido ainda válido.

  O que fazer: se `retryable` vier `true`, chame aqui de novo com o mesmo `orderCode` — a Fire
  retoma a solicitação. Se for `FAILED_FINAL`, leia `failure.scope` e escale com o
  `fiscalRequestId`: não há nada que o caixa possa fazer, e **ninguém retenta por você**.
</Warning>

<Warning>
  **Um `FAILED_FINAL` na nota de crédito não se resolve esperando.** Essa solicitação fica
  gravada como definitiva, e chamar de novo com o mesmo `orderCode` — mesmo com o provedor
  já saudável — devolve a mesma resposta sem voltar a perguntar a ele. Não é uma retentativa
  que falha: é a resposta arquivada.

  A consequência é que **esse pedido não pode mais ser cancelado** por este caminho: continua
  vigente no Fire, com a sua nota, e [Cancelar pedido](/pt/api-reference/cancel-order)
  responde `409 FISCAL_CREDIT_NOTE_MISSING` para sempre. Escalar aqui não é "avise e tente de
  novo mais tarde" — é avise, porque isso já não se destrava sozinho.
</Warning>

<ResponseField name="failure" type="object">
  Por que não há documento. `null` quando há.

  <Expandable title="failure">
    <ResponseField name="scope" type="string">
      **O que você ramifica.** `TECHNICAL` → o problema é de comunicação ou do serviço; você
      imprime provisório e se resolve depois. `FUNCTIONAL` → há um dado errado e tentar de novo não
      conserta.
    </ResponseField>

    <ResponseField name="code" type="string">
      Código estável, para alertas e suporte. **Não é um status**: os status são os cinco de
      `requestStatus` e não crescem; este catálogo cresce.
    </ResponseField>

    <ResponseField name="message" type="string">
      Texto acionável. Diz qual loja, qual ponto de emissão ou qual dado falta.

      **Quando o provedor manda um motivo, é o dele, literal** — por exemplo
      `"clave de API inválida"`. Só se ele não mandar nenhum usamos um texto próprio conforme o
      `code`. É um texto **para ler, não para ramificar**: vem do provedor e pode mudar sem
      aviso. Para decidir, use `code` e `scope`.
    </ResponseField>
  </Expandable>

  | `code`                         | O que aconteceu                                                                           | `scope`      |
  | ------------------------------ | ----------------------------------------------------------------------------------------- | ------------ |
  | `FISCAL_BUSINESS_RULE`         | O órgão ou o provedor rejeitaram por uma regra de negócio. A `message` traz o motivo real | `FUNCTIONAL` |
  | `FISCAL_COUNTRY_NOT_SUPPORTED` | O provedor não atende o país daquela loja                                                 | `TECHNICAL`  |
  | `PROVIDER_AUTH_FAILED`         | Credencial do provedor errada ou revogada. **É configuração, não uma falha de numeração** | `TECHNICAL`  |
  | `PROVIDER_TIMEOUT`             | Não respondeu dentro do orçamento de tempo                                                | `TECHNICAL`  |
  | `PROVIDER_UNAVAILABLE`         | Respondeu que não pode agora                                                              | `TECHNICAL`  |
  | `PROVIDER_UNREACHABLE`         | Não foi possível estabelecer comunicação                                                  | `TECHNICAL`  |
  | `PROVIDER_CONTRACT_VIOLATION`  | Respondeu `2xx` com algo que não cumpre o contrato                                        | `TECHNICAL`  |

  <Warning>
    **`PROVIDER_TIMEOUT` e `PROVIDER_CONTRACT_VIOLATION` chegam com `requestStatus: "PENDING"`, não
    com uma falha definitiva.** Nos dois casos o provedor pode ter numerado sem que a gente consiga
    ler: emitir outro comprovante por fora declararia a mesma venda duas vezes ao órgão.
  </Warning>
</ResponseField>

<ResponseField name="providerCode" type="string">
  **Nosso** identificador de adaptador (`hio`), não o nome do provedor. É o que diz com qual
  integração esta venda foi numerada. `null` em `NOT_APPLICABLE`: nenhum interveio.
</ResponseField>

<ResponseField name="providerIdentity" type="object">
  Quem numerou, do lado do provedor. **Tem forma** —os três campos fazem parte do contrato— e
  por isso viaja separado da bolsa opaca. `null` quando não se numerou nada.

  <Expandable title="providerIdentity">
    <ResponseField name="name" type="string">
      Identificador estável do serviço que resolveu a numeração.
    </ResponseField>

    <ResponseField name="version" type="string">
      Qual versão a resolveu. É o que permite delimitar um problema a um deploy.
    </ResponseField>

    <ResponseField name="reference" type="string">
      **A referência de suporte do provedor**: o identificador que você cita para ele encontrar
      esta operação nos registros dele. **Não é a sua `Idempotency-Key`** — essa você enviou e
      volta em `idempotencyKey`.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="providerMetadata" type="object">
  A bolsa de diagnóstico do provedor, tal como chegou. **Opaca**: não tem forma garantida e
  ninguém deve programar contra suas chaves — elas mudam sem aviso e sem versionar o contrato.
  Serve para colar num ticket, não para ramificar.

  `null` quando o provedor não mandou nada.

  <Note>
    **É o mesmo campo que viaja no evento**, com o mesmo nome e o mesmo conteúdo. Os três campos
    do provedor —`providerCode`, `providerIdentity`, `providerMetadata`— se leem igual aqui e em
    `fiscalRepresentation`: o que se aprende num extremo serve no outro.
  </Note>
</ResponseField>

## Códigos de status

<Warning>
  **O código HTTP não diz se você conseguiu comprovante.** `200` pode ser uma retentativa
  idempotente que numerou perfeitamente, ou uma rejeição definitiva do órgão. Ramifique por
  `printing.mode` e `requestStatus`, nunca pelo código sozinho.
</Warning>

| Código        | Quando                                                                                | `requestStatus`                |
| ------------- | ------------------------------------------------------------------------------------- | ------------------------------ |
| `201`         | Numerado agora                                                                        | `GENERATED`                    |
| `200`         | Retentativa idempotente — já existia (`reused: true`)                                 | qualquer                       |
| `200`         | Esta loja não numera. **Não é um erro**                                               | `NOT_APPLICABLE`               |
| `200`         | Rejeição definitiva. É a resposta à sua pergunta, não uma falha da chamada            | `FAILED_FINAL`                 |
| `202`         | Não há números **ainda**. Imprima provisório e injete do mesmo jeito                  | `PENDING` · `FAILED_RETRYABLE` |
| `400`         | Corpo inválido ou loja sem configuração para emitir                                   | —                              |
| `401` · `403` | Credenciais ou permissão                                                              | —                              |
| `404`         | A loja não existe para o vendor da sua API key                                        | —                              |
| `409`         | Mesma `Idempotency-Key` com outro corpo, ou o `orderCode` já foi usado por outra loja | —                              |

<Note>
  **A chamada é síncrona, mas tem um orçamento de tempo.** O cliente está parado no caixa: o Fire
  espera o provedor alguns segundos e, se não responder, corta e devolve `202` em vez de deixar a
  venda pendurada.

  Esse `202` **não é uma promessa de que depois chega por outro canal ao seu PDV**: é o Fire
  dizendo "não tenho números ainda, imprima provisório e siga".

  **Para completá-la, tente de novo com o mesmo `orderCode`.** O Fire retoma a solicitação e volta
  a perguntar ao provedor. É raro, mas existe porque a alternativa — falhar a venda — é pior.
</Note>

## O que fazer com cada resposta

<Note>
  **O que segue descreve o caminho `CONTINUE`**, que é o padrão e o da maioria das contas. Se
  `policy.numberingFailure.action` disser `REFUND`, a instrução se inverte: você não injeta o
  pedido e não retenta a numeração — devolve a cobrança e
  [reporta a venda perdida](/pt/api-reference/lost-sales).

  O resto de cada estado —o que significa e se a falha se resolve sozinha— vale nos dois casos.
</Note>

<AccordionGroup>
  <Accordion title="GENERATED — há comprovante" icon="circle-check">
    `printing.mode: "FISCAL_DOCUMENT"`. Imprima o comprovante com `document.documentNumber` e
    desenhe os códigos de `graphic`. Injete o pedido com **o mesmo `orderCode`**.

    Se `printing.reason` for `ISSUED_OFFLINE`, o comprovante é válido mas foi emitido em
    contingência: imprima a legenda que aquele país exige.

    <CodeGroup>
      ```json Equador (EC) — SRI theme={null}
      {
        "requestStatus": "GENERATED",
        "documentStatus": "PENDING",
        "reused": false,
        "environment": "PRODUCTION",
        "document": {
          "documentType": "SALE_INVOICE",
          "documentLabel": "FACTURA",
          "documentNumber": "005-004-000000058",
          "authorizationMode": "ONLINE",
          "authorizationLabel": "EMISION NORMAL",
          "issuedAt": "2026-08-14T01:01:14.722Z",
          "compensates": null
        },
        "countryData": {
          "numeroComprobante": "005-004-000000058",
          "claveAcceso": "1308202601000000000000210050040000000581234567811",
          "establecimiento": "005",
          "puntoEmision": "004",
          "secuencial": "000000058",
          "ambiente": "PRODUCCION"
        },
        "printing": { "printable": true, "mode": "FISCAL_DOCUMENT", "reason": null },
        "graphic": { "qr": "1308202601000000000000210050040000000581234567811" },
        "failure": null
      }
      ```

      ```json Colômbia (CO) — DIAN theme={null}
      {
        "requestStatus": "GENERATED",
        "documentStatus": "PENDING",
        "reused": false,
        "environment": "PRODUCTION",
        "document": {
          "documentType": "SALE_INVOICE",
          "documentLabel": "FACTURA ELECTRONICA DE VENTA",
          "documentNumber": "SETP990000001",
          "authorizationMode": "ONLINE",
          "authorizationLabel": "VALIDACION PREVIA",
          "issuedAt": "2026-08-16T14:21:03.118Z",
          "compensates": null
        },
        "countryData": {
          "numeroComprobante": "SETP990000001",
          "cufe": "9c4f1e… (96 hex)",
          "prefijo": "SETP",
          "numeroDian": "990000001",
          "qrCode": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=9c4f1e…",
          "ambiente": "PRODUCCION"
        },
        "printing": { "printable": true, "mode": "FISCAL_DOCUMENT", "reason": null },
        "graphic": null,
        "failure": null
      }
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="PENDING — não se sabe se há comprovante" icon="circle-question">
    O provedor **não respondeu**: timeout ou conexão cortada. Pode ter numerado e consumido um
    sequencial sem que a gente fique sabendo.

    Imprima o ticket provisório e injete o pedido. Depois **tente de novo com o mesmo
    `orderCode`**: o Fire retoma a solicitação e volta a perguntar ao provedor, então se da
    primeira vez numerou, você recupera esse documento.

    <Warning>
      **Não assuma que a venda ficou sem comprovante.** Emitir um novo por outro caminho pode
      declarar a mesma venda duas vezes ao órgão.
    </Warning>

    ```json theme={null}
    {
      "requestStatus": "PENDING",
      "document": null,
      "printing": { "printable": false, "mode": "PROVISIONAL_RECEIPT", "reason": "AWAITING_FISCAL_NUMBERING" },
      "graphic": null,
      "retryable": true,
      "environment": "PRODUCTION",
      "failure": {
        "code": "PROVIDER_TIMEOUT",
        "scope": "TECHNICAL",
        "message": "El proveedor fiscal no respondió dentro del tiempo configurado."
      }
    }
    ```
  </Accordion>

  <Accordion title="FAILED_RETRYABLE — não há, mas pode haver" icon="rotate-right">
    O provedor **respondeu** que não pode agora. Diferente de `PENDING`, aqui sabemos com certeza
    que **nada foi numerado**.

    Imprima provisório, injete o pedido e tente de novo com o mesmo `orderCode`.

    ```json theme={null}
    {
      "requestStatus": "FAILED_RETRYABLE",
      "document": null,
      "printing": { "printable": false, "mode": "PROVISIONAL_RECEIPT", "reason": "AWAITING_FISCAL_NUMBERING" },
      "graphic": null,
      "retryable": true,
      "environment": "PRODUCTION",
      "failure": {
        "code": "PROVIDER_UNAVAILABLE",
        "scope": "TECHNICAL",
        "message": "El servicio de fiscalización no está disponible."
      }
    }
    ```
  </Accordion>

  <Accordion title="FAILED_FINAL — não há, e tentar de novo não adianta" icon="circle-xmark">
    Tentar de novo com o mesmo corpo vai dar no mesmo. Leia `failure.message`, que traz o
    motivo real, e **`failure.scope`, que diz de quem é o problema**:

    * `FUNCTIONAL` — há um dado que o fisco não aceita. Corrige-se na venda ou na configuração
      da loja.
    * `TECHNICAL` — a integração com o provedor está quebrada. A venda está certa; o que falha
      é a conexão com quem numera. Ninguém no caixa consegue resolver.

    Nos dois casos: imprima o ticket provisório, injete o pedido e escale com o
    `fiscalRequestId`. Com `CONTINUE`, **a venda fica cobrada sem comprovante fiscal** — isso também viaja
    nos eventos do pedido, para que você possa compensar. Com `REFUND` não há pedido nem
    evento: a única trilha é o reporte de venda perdida.

    <CodeGroup>
      ```json FUNCTIONAL — um dado não é aceito theme={null}
      {
        "requestStatus": "FAILED_FINAL",
        "document": null,
        "printing": { "printable": false, "mode": "PROVISIONAL_RECEIPT", "reason": "FISCAL_REJECTED" },
        "graphic": null,
        "retryable": false,
        "environment": "PRODUCTION",
        "failure": {
          "code": "FISCAL_BUSINESS_RULE",
          "scope": "FUNCTIONAL",
          "message": "identidad fiscal no configurada: EC / la tienda K004 no está cargada en el catálogo de identidades fiscales"
        }
      }
      ```

      ```json TECHNICAL — o provedor rejeitou as credenciais theme={null}
      {
        "requestStatus": "FAILED_FINAL",
        "document": null,
        "printing": { "printable": false, "mode": "PROVISIONAL_RECEIPT", "reason": "FISCAL_REJECTED" },
        "graphic": null,
        "retryable": false,
        "environment": "SANDBOX",
        "failure": {
          "code": "PROVIDER_AUTH_FAILED",
          "scope": "TECHNICAL",
          "message": "clave de API inválida"
        },
        "company": {
          "legalName": "INT FOOD SERVICES CORP S.A.",
          "tradeName": "KFC",
          "govIdType": "RUC",
          "govIdNumber": "1791415132001",
          "headquartersAddress": "PICHINCHA / QUITO / COREA 126 Y AV. AMAZONAS",
          "countryLines": [],
          "legends": []
        },
        "timestamps": {
          "requestedAt": "2026-08-18T21:36:58.702Z",
          "respondedAt": "2026-08-18T21:36:59.617Z",
          "providerLatencyMs": 742
        }
      }
      ```
    </CodeGroup>

    <Warning>
      **`PROVIDER_AUTH_FAILED` não é uma queda do provedor.** Ele respondeu, e rápido: 742 ms
      no exemplo. O que ele rejeitou foi a nossa credencial —errada, revogada ou rotacionada do
      lado dele—, então é configuração e não algo transitório: por isso `retryable` é `false` e
      o estado é `FAILED_FINAL`, e não `PENDING`.

      Se em vez disso você vir `PROVIDER_TIMEOUT` com `requestStatus: "PENDING"`, aí sim o
      provedor não respondeu a tempo — e aí vale tentar de novo.

      Repare também no bloco `company` do exemplo: a identidade chega para o cabeçalho, mas
      `countryLines` e `legends` vêm vazios porque **não há comprovante declarando nada**.
    </Warning>
  </Accordion>

  <Accordion title="NOT_APPLICABLE — esta loja não numera" icon="ban">
    **Não é um erro.** Este vendor não tem representação fiscal: não há nada a numerar e nenhuma
    solicitação foi criada (`fiscalRequestId: null`).

    Imprima seu ticket de sempre e injete o pedido normalmente. É a resposta esperada para
    agregadores, países sem gateway fiscal e comércios com a numeração desativada.

    ```json theme={null}
    {
      "fiscalRequestId": null,
      "requestStatus": "NOT_APPLICABLE",
      "document": null,
      "printing": { "printable": false, "mode": "NONE", "reason": "NUMBERING_DISABLED" },
      "graphic": null,
      "failure": null,
      "documentStatus": null,
      "environment": null,
      "idempotencyKey": null,
      "store": {
        "code": "K000",
        "name": "Laboratorio Ecuador",
        "address": "PICHINCHA / QUITO / AV. AMAZONAS Y AV COREA",
        "city": "Quito",
        "phone": "023920070",
        "govIdType": "RUC",
        "govIdNumber": "1791415132001"
      },
      "company": {
        "legalName": "INT FOOD SERVICES CORP S.A.",
        "tradeName": "KFC",
        "govIdType": "RUC",
        "govIdNumber": "1791415132001",
        "countryLines": [],
        "legends": []
      }
    }
    ```

    <Note>
      **`store` e `company` vêm aqui também.** Nada foi numerado, então chega a identidade do
      emissor e não o aparato fiscal (`countryLines` e `legends` vazios). É o mesmo bloco de
      qualquer outra resposta: não há uma forma diferente para aprender neste caso.
    </Note>
  </Accordion>

  <Accordion title="4xx — o problema está na requisição">
    Nestes casos **nenhuma solicitação fiscal foi criada**: corrija e chame de novo.

    Se você receber `404` com uma mensagem de loja não encontrada, verifique se a sua API key é a do
    vendor dono daquela loja — a mensagem inclui contra qual vendor foi buscado.

    **O `400` de loja que não pode emitir traz a identidade do emissor em `data`.** É o caso de
    uma loja sem CNPJ/RUC ou não habilitada: a venda já aconteceu e você ainda precisa imprimir
    um provisório, então o cabeçalho viaja junto com o erro.

    ```json theme={null}
    {
      "success": false,
      "error": "VALIDATION_ERROR",
      "message": "La tienda no tiene identificador tributario del emisor configurado (settings.fiscal.govIdNumber)",
      "data": {
        "storeCode": "K000",
        "store": { "code": "K000", "name": "Laboratorio Ecuador", "address": "…" },
        "company": { "legalName": "INT FOOD SERVICES CORP S.A.", "countryLines": [], "legends": [] }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

<Info>
  **Chame sempre. É assim que você sabe se a loja numera.**

  Você não precisa sincronizar configuração nem decidir por país: se aquele vendor não tem
  representação fiscal, a resposta é `200` com `requestStatus: "NOT_APPLICABLE"` e
  `printing.mode: "NONE"` — você imprime seu ticket e segue. **Não é um erro** e nenhuma
  solicitação é criada.

  É o mesmo desvio que você já tem: você ramifica por `printing.mode`, não pelo código HTTP.
</Info>

## Anular

Você manda **o mesmo `orderCode` da venda** com `operation: "CANCEL"`. Nada mais.

```json theme={null}
{
  "orderCode": "EC-K004-42-1786579046934",
  "createdAt": "2026-08-12T19:10:00.000Z",
  "operation": "CANCEL",
  "store": { "code": "K004" },
  "device": { "uid": "kiosk-01", "name": "KIOSK", "platform": "android" },
  "totals": [
    {
      "currencyCode": "USD",
      "total": 10,
      "subtotalWithoutTaxes": 8.7,
      "taxValue": 1.3,
      "taxes": [
        { "name": "IVA", "base": 8.7, "rate": "0.15", "amount": 1.3 }
      ]
    }
  ],
  "client": {
    "uid": "8Z35YvBbgKVj67AJwZ3nFmAqrtk1",
    "name": "CONSUMIDOR",
    "lastName": "FINAL",
    "email": "consumidor.final@ejemplo.com",
    "phone": "2222222",
    "govIdType": "FINAL_CONSUMER",
    "govIdNumber": "00000000000",
    "externalId": "",
    "additionalInfo": { "fiscal": "", "gender": "", "birthdate": "" },
    "billingInformation": {
      "email": "", "phone": "2222222", "address": "",
      "govIdType": "FINAL_CONSUMER", "externalId": "",
      "govIdNumber": "00000000000", "businessName": ""
    }
  },
  "metadata": {}
}
```

A resposta tem **a mesma forma** da de uma nota de venda. Mudam três coisas:

|                          | Nota de venda  | Cancelamento           |
| ------------------------ | -------------- | ---------------------- |
| `document.documentType`  | `SALE_INVOICE` | `CREDIT_NOTE`          |
| `document.documentLabel` | `FACTURA`      | `NOTA DE CREDITO RIDE` |
| `document.compensates`   | `null`         | o documento que anula  |

<Note>
  **A nota de crédito tem sua própria numeração.** Não continua a das notas de venda: no exemplo, a
  nota de venda é `005-004-000000068` e o cancelamento dela `005-004-000000002`. São duas
  sequências distintas sob o mesmo estabelecimento e ponto de emissão.
</Note>

<Warning>
  **O cancelamento é um comprovante fiscal novo, não uma exclusão.** A nota original continua
  existindo perante o órgão e precisa ser conservada: o que a nota de crédito faz é compensá-la.

  Por isso `GET /numbering?orderCode=…` devolve **dois** documentos para aquele pedido.
</Warning>

### Se não houver nada a anular

Se a venda nunca foi numerada —porque a loja não emite, ou porque a numeração falhou— o
cancelamento responde **`400`**:

```json theme={null}
{
  "success": false,
  "error": "VALIDATION_ERROR",
  "message": "No existe un documento emitido para esa orden al que referenciar la nota de crédito"
}
```

<Warning>
  **É um `400`, não uma falha dentro de um `200`.** É a única diferença importante entre anular e
  emitir: ao emitir, uma rejeição do órgão viaja como resposta bem-sucedida com
  `requestStatus: "FAILED_FINAL"`, porque é a resposta à sua pergunta. Aqui não há pergunta a
  responder — você pediu para compensar algo que não existe.

  Seu ponto de venda imprime seu comprovante de cancelamento interno e segue.
</Warning>

### Quando o cancelamento não se resolve na hora

Cancelar tem os **mesmos desfechos incertos que faturar**, e vale dizer em voz alta porque é fácil
supor que cancelar sempre fecha.

| `requestStatus`    | O que aconteceu                           | O que fazer                         |
| ------------------ | ----------------------------------------- | ----------------------------------- |
| `GENERATED`        | O cancelamento foi numerado               | Nada                                |
| `PENDING`          | **Não se sabe.** O provedor não respondeu | Consultar por `orderCode`           |
| `FAILED_RETRYABLE` | Falhou, dá para repetir                   | Repetir com o mesmo `orderCode`     |
| `FAILED_FINAL`     | O fisco recusou o cancelamento            | **A nota original continua válida** |

<Warning>
  **Uma recusa deixa a venda faturada.** Se o cancelamento voltar `FAILED_FINAL`, o documento
  original não foi compensado e continua produzindo efeitos fiscais. Não é um estado intermediário
  do qual o sistema saia sozinho: não há retentativa automática.

  Medido em produção sobre 72 pedidos cancelados: **67 fecharam o circuito, 3 ficaram aguardando
  confirmação e 2 foram recusados.** Esses \~7% não se resolvem sem intervenção.
</Warning>

<Note>
  **Cancelar o pedido e cancelar o documento são coisas diferentes.** Seu pedido pode ficar
  cancelado na hora enquanto o cancelamento fiscal ainda está em andamento. Se você precisa de
  certeza fiscal — um fechamento contábil, uma conciliação — consulte o documento; o status do
  pedido não lhe dá isso.
</Note>

### Quando o instrumento não é uma nota de crédito

No Equador o cancelamento produz um documento novo. Em outros países não: no Brasil é um evento de
cancelamento que **não gera comprovante**, e ali a resposta chega com `status: "CANCELLED"` e
`document: null`. **Não é um erro** — é o desfecho correto daquela operação naquele país.

Por isso você pede `operation` e não um tipo de documento: quem decide o instrumento é o regime.

## Consultar uma solicitação

São dois endpoints de leitura, e existem para **quando o caminho normal não basta**: você perdeu a
resposta síncrona, ou quer ver se o órgão já autorizou sem esperar o evento. Na operação diária
você não deveria precisar deles — os dados chegam pelos eventos do pedido.

* **[Por identificador](/pt/api-reference/fiscal-document-get)** — `GET /numbering/{fiscalRequestId}`.
* **[Por pedido](/pt/api-reference/fiscal-documents-query)** — `GET /numbering?orderCode=…`. Devolve
  `items[]`, porque um pedido pode ter **dois** documentos: a nota de venda e o cancelamento que a
  compensa. É o que você usa quando perde a resposta por uma queda de rede — o `orderCode` é a
  única coisa que você tem em mãos.

Quando o órgão autoriza, `documentStatus` passa a `AUTHORIZED`.

<RequestExample>
  ```json Emitir theme={null}
  {
    "orderCode": "EC-K004-42-1786579046934",
    "createdAt": "2026-08-12T17:26:09.386Z",
    "operation": "INVOICE",
    "store": { "code": "K004" },
    "device": { "uid": "kiosk-01", "name": "KIOSK", "platform": "android" },
    "totals": [
      {
        "currencyCode": "USD",
        "total": 10,
        "subtotalWithoutTaxes": 8.7,
        "taxValue": 1.3,
        "taxes": [
          { "name": "IVA", "base": 8.7, "rate": "0.15", "amount": 1.3 }
        ]
      }
    ],
    "client": {
      "uid": "8Z35YvBbgKVj67AJwZ3nFmAqrtk1",
      "name": "CONSUMIDOR",
      "lastName": "FINAL",
      "email": "consumidor.final@ejemplo.com",
      "phone": "2222222",
      "govIdType": "FINAL_CONSUMER",
      "govIdNumber": "00000000000",
      "externalId": "",
      "additionalInfo": { "fiscal": "", "gender": "", "birthdate": "" },
      "billingInformation": {
        "email": "", "phone": "2222222", "address": "",
        "govIdType": "FINAL_CONSUMER", "externalId": "",
        "govIdNumber": "00000000000", "businessName": ""
      }
    },
    "metadata": {}
  }
  ```

  ```json Faturar — Colômbia (CO) theme={null}
  {
    "orderCode": "CO-K039-1786901234",
    "createdAt": "2026-08-16T14:03:22.145Z",
    "operation": "INVOICE",
    "store": { "code": "K039" },
    "device": { "uid": "52CAEA5A18D9B75F", "name": "CAJA 3", "platform": "android" },
    "client": {
      "name": "Consumidor",
      "lastName": "final",
      "govIdType": "FINAL_CONSUMER",
      "govIdNumber": "00000000000"
    },
    "totals": [
      {
        "currencyCode": "COP",
        "total": 50000,
        "subtotalWithoutTaxes": 42016.81,
        "taxValue": 7983.19,
        "taxes": [
          { "name": "IVA", "base": 42016.81, "rate": "0.19", "amount": 7983.19 }
        ]
      }
    ],
    "metadata": {}
  }
  ```

  ```json Anular theme={null}
  {
    "orderCode": "EC-K004-42-1786579046934",
    "createdAt": "2026-08-12T19:10:00.000Z",
    "operation": "CANCEL",
    "store": { "code": "K004" },
    "device": { "uid": "kiosk-01", "name": "KIOSK", "platform": "android" },
    "metadata": {}
  }
  ```
</RequestExample>

<ResponseExample>
  ```json 201 Numerado theme={null}
  {
    "success": true,
    "data": {
      "fiscalRequestId": "8d5b425c-87d2-4848-ab74-517a0ca2743e",
      "orderCode": "EC-K004-42-1786579046934",
      "idempotencyKey": "9305c960-2304-4b37-a845-fea3a38daa5e",
      "reused": false,
      "countryCode": "EC",
      "requestStatus": "GENERATED",
      "documentStatus": "PENDING",
      "retryable": false,
      "environment": "PRODUCTION",
      "document": {
        "documentType": "SALE_INVOICE",
        "documentLabel": "FACTURA",
        "documentNumber": "005-004-000000011",
        "authorizationMode": "ONLINE",
        "authorizationLabel": "EMISION NORMAL",
        "issuedAt": "2026-08-12T23:57:47.118Z",
        "compensates": null
      },
      "countryData": {
        "numeroComprobante": "005-004-000000011",
        "claveAcceso": "1208202601000000000000110050040000000111234567811",
        "establecimiento": "005",
        "puntoEmision": "004",
        "secuencial": "000000011",
        "ambiente": "PRODUCCION"
      },
      "store": {
        "code": "K004", "name": "Sucursal Amazonas",
        "address": "AV. AMAZONAS N36-15", "city": "Quito", "phone": "022222222",
        "govIdType": "RUC", "govIdNumber": "1791415132001",
        "secondaryGovIdType": null, "secondaryGovIdNumber": null
      },
      "company": {
        "legalName": "INT FOOD SERVICES CORP SA",
        "tradeName": "KFC",
        "govIdType": "RUC",
        "govIdNumber": "1791415132001",
        "headquartersAddress": "PICHINCHA / QUITO / INAQUITO / COREA 126 Y AV. AMAZONAS",
        "countryLines": [
          { "key": "granContribuyente", "label": "GRAN CONTRIBUYENTE", "value": "NAC-GCFOIOC21-00000900-E" },
          { "key": "contribuyenteEspecial", "label": "CONTRIBUYENTE ESPECIAL", "value": "155" },
          { "key": "obligadoContabilidad", "label": "Obligado a llevar contabilidad", "value": "SI" }
        ],
        "legends": [
          { "key": "avisoCambios", "text": "Estimado cliente: Por favor verifique los datos de su factura…" }
        ]
      },
      "graphic": { "qr": "1208202601000000000000110050040000000111234567811" },
      "policy": {
        "numberingFailure": {
          "action": "CONTINUE",
          "lostSaleReason": null,
          "resolvedAt": "2026-08-21T21:59:56.203Z",
          "configVersion": null,
          "resolvedFrom": { "requestStatus": "GENERATED" }
        }
      },
      "printing": { "printable": true, "mode": "FISCAL_DOCUMENT", "reason": null },
      "failure": null,
      "timestamps": {
        "requestedAt": "2026-08-12T23:57:46.7Z",
        "respondedAt": "2026-08-12T23:57:47.2Z",
        "providerLatencyMs": 406
      },
      "correlationId": null,
      "providerCode": "hio",
      "providerIdentity": { "name": "hio.fiscalization", "version": "dev", "reference": null },
      "providerMetadata": { "deviceUid": "4B8E21F9A0D35C7A", "externalStoreCode": "K000" }
    }
  }
  ```

  ```json 201 Numerado — Colômbia (CO) theme={null}
  {
    "success": true,
    "data": {
      "fiscalRequestId": "c1a7f0e2-9b34-4d21-8e55-3f60ab12cd90",
      "orderCode": "CO-K039-1786901234",
      "idempotencyKey": "2f81dcb4-77a0-4c19-9e3b-5a04e7f1b2c8",
      "reused": false,
      "countryCode": "CO",
      "requestStatus": "GENERATED",
      "documentStatus": "PENDING",
      "retryable": false,
      "environment": "PRODUCTION",
      "document": {
        "documentType": "SALE_INVOICE",
        "documentLabel": "FACTURA ELECTRONICA DE VENTA",
        "documentNumber": "SETP990000001",
        "authorizationMode": "ONLINE",
        "authorizationLabel": "VALIDACION PREVIA",
        "issuedAt": "2026-08-16T14:21:03.118Z",
        "compensates": null
      },
      "countryData": {
        "numeroComprobante": "SETP990000001",
        "cufe": "9c4f1e… (96 caracteres hexadecimales)",
        "prefijo": "SETP",
        "numeroDian": "990000001",
        "qrCode": "https://catalogo-vpfe.dian.gov.co/document/searchqr?documentkey=9c4f1e…",
        "ambiente": "PRODUCCION"
      },
      "store": {
        "code": "K039", "name": "Sucursal Chapinero",
        "address": "CRA 13 # 63-39", "city": "Bogotá", "phone": "6013334444",
        "govIdType": "NIT", "govIdNumber": "9001234567",
        "secondaryGovIdType": null, "secondaryGovIdNumber": null
      },
      "company": {
        "legalName": "COMERCIALIZADORA ANDINA S.A.S.",
        "tradeName": "KFC",
        "govIdType": "NIT",
        "govIdNumber": "9001234567",
        "headquartersAddress": "BOGOTA D.C. / CHAPINERO / CRA 13 # 63-39",
        "countryLines": [
          { "key": "regimen", "label": "REGIMEN", "value": "RESPONSABLE DE IVA" },
          { "key": "resolucion", "label": "RESOLUCION DIAN", "value": "18760000001" }
        ],
        "legends": []
      },
      "graphic": null,
      "policy": {
        "numberingFailure": {
          "action": "CONTINUE",
          "lostSaleReason": null,
          "resolvedAt": "2026-08-21T21:59:56.203Z",
          "configVersion": null,
          "resolvedFrom": { "requestStatus": "GENERATED" }
        }
      },
      "printing": { "printable": true, "mode": "FISCAL_DOCUMENT", "reason": null },
      "failure": null,
      "timestamps": {
        "requestedAt": "2026-08-16T14:21:02.6Z",
        "respondedAt": "2026-08-16T14:21:03.3Z",
        "providerLatencyMs": 712
      },
      "correlationId": null,
      "providerCode": "hio",
      "providerIdentity": { "name": "hio.fiscalization", "version": "dev", "reference": null },
      "providerMetadata": { "externalStoreCode": "K039" }
    }
  }
  ```

  ```json 201 Anulado — nota de crédito theme={null}
  {
    "success": true,
    "data": {
      "fiscalRequestId": "b73b2fd9-c7a6-42bd-815f-d39c210983ef",
      "orderCode": "EC-K004-42-1786579046934",
      "idempotencyKey": "1e07b0e1-784b-40b9-8903-0326361ebefd",
      "reused": false,
      "countryCode": "EC",
      "requestStatus": "GENERATED",
      "documentStatus": "PENDING",
      "retryable": false,
      "environment": "PRODUCTION",
      "document": {
        "documentType": "CREDIT_NOTE",
        "documentLabel": "NOTA DE CREDITO RIDE",
        "documentNumber": "005-004-000000002",
        "authorizationMode": "ONLINE",
        "authorizationLabel": "EMISION NORMAL",
        "issuedAt": "2026-08-14T18:32:32.242Z",
        "compensates": {
          "documentNumber": "005-004-000000068",
          "issuedAt": "2026-08-14T18:31:57.649Z",
          "reason": "ORDER_CANCELLATION",
          "reasonLabel": "Anulación de pedido"
        }
      },
      "countryData": {
        "numeroComprobante": "005-004-000000002",
        "claveAcceso": "1408202604179141513200110050040000000021234567815",
        "establecimiento": "005",
        "puntoEmision": "004",
        "secuencial": "000000002",
        "ambiente": "PRODUCCION"
      },
      "policy": {
        "numberingFailure": {
          "action": "CONTINUE",
          "lostSaleReason": null,
          "resolvedAt": "2026-08-21T21:59:56.203Z",
          "configVersion": null,
          "resolvedFrom": { "requestStatus": "GENERATED" }
        }
      },
      "printing": { "printable": true, "mode": "FISCAL_DOCUMENT", "reason": null },
      "graphic": { "qr": "1408202604179141513200110050040000000021234567815" },
      "failure": null,
      "providerCode": "hio",
      "providerIdentity": { "name": "hio.fiscalization", "version": "dev", "reference": null },
      "providerMetadata": { "deviceUid": "4B8E21F9A0D35C7A", "externalStoreCode": "K000" }
    }
  }
  ```

  ```json 202 Sem resposta do provedor theme={null}
  {
    "success": true,
    "data": {
      "fiscalRequestId": "81670b02-4073-4e50-adca-e3c9917e7006",
      "orderCode": "EC-K004-42-1786579046934",
      "reused": false,
      "countryCode": "EC",
      "requestStatus": "PENDING",
      "documentStatus": "PENDING",
      "retryable": true,
      "environment": "PRODUCTION",
      "document": null,
      "countryData": null,
      "graphic": null,
      "policy": {
        "numberingFailure": {
          "action": "REFUND",
          "lostSaleReason": "FISCAL_NUMBERING_FAILED",
          "resolvedAt": "2026-08-21T21:59:56.203Z",
          "configVersion": "fnv1a:d096701f",
          "resolvedFrom": {
            "retryable": "true",
            "operation": "INVOICE",
            "requestStatus": "PENDING",
            "failureScope": "TECHNICAL",
            "failureCode": "PROVIDER_UNREACHABLE",
            "storeCode": "K004"
          }
        }
      },
      "printing": {
        "printable": false,
        "mode": "PROVISIONAL_RECEIPT",
        "reason": "AWAITING_FISCAL_NUMBERING"
      },
      "failure": {
        "code": "PROVIDER_UNREACHABLE",
        "scope": "TECHNICAL",
        "message": "No se pudo establecer comunicación con el proveedor fiscal."
      },
      "providerCode": "hio",
      "providerIdentity": { "name": null, "version": null, "reference": null },
      "providerMetadata": null
    }
  }
  ```

  ```json 202 Provedor indisponível theme={null}
  {
    "success": true,
    "data": {
      "fiscalRequestId": "c4f0a1e2-5d3b-4f77-9a10-6b2e8c4d1f03",
      "orderCode": "EC-K000-42-1786579046934",
      "reused": false,
      "countryCode": "EC",
      "requestStatus": "FAILED_RETRYABLE",
      "documentStatus": "PENDING",
      "retryable": true,
      "environment": "PRODUCTION",
      "document": null,
      "countryData": null,
      "graphic": null,
      "policy": {
        "numberingFailure": {
          "action": "CONTINUE",
          "lostSaleReason": "FISCAL_NUMBERING_FAILED",
          "resolvedAt": "2026-08-21T21:59:56.203Z",
          "configVersion": null,
          "resolvedFrom": {
            "retryable": "true",
            "operation": "INVOICE",
            "requestStatus": "FAILED_RETRYABLE",
            "failureScope": "TECHNICAL",
            "failureCode": "PROVIDER_UNAVAILABLE",
            "storeCode": "K000"
          }
        }
      },
      "printing": {
        "printable": false,
        "mode": "PROVISIONAL_RECEIPT",
        "reason": "AWAITING_FISCAL_NUMBERING"
      },
      "failure": {
        "code": "PROVIDER_UNAVAILABLE",
        "scope": "TECHNICAL",
        "message": "El servicio de fiscalización no está disponible."
      },
      "providerCode": "hio",
      "providerIdentity": { "name": "hio.fiscalization", "version": "dev", "reference": null },
      "providerMetadata": null
    }
  }
  ```

  ```json 200 Rejeitado theme={null}
  {
    "success": true,
    "data": {
      "fiscalRequestId": "1d10c5b9-9f1b-4c62-a425-238110ce9cd6",
      "orderCode": "EC-UIO-9-1786580272803",
      "reused": false,
      "countryCode": "EC",
      "requestStatus": "FAILED_FINAL",
      "documentStatus": "PENDING",
      "retryable": false,
      "environment": "PRODUCTION",
      "document": null,
      "countryData": null,
      "graphic": null,
      "policy": {
        "numberingFailure": {
          "action": "REFUND",
          "lostSaleReason": "FISCAL_NUMBERING_FAILED",
          "resolvedAt": "2026-08-21T21:59:56.203Z",
          "configVersion": "fnv1a:d096701f",
          "resolvedFrom": {
            "retryable": "false",
            "operation": "INVOICE",
            "requestStatus": "FAILED_FINAL",
            "failureScope": "FUNCTIONAL",
            "failureCode": "FISCAL_BUSINESS_RULE",
            "storeCode": "UIO"
          }
        }
      },
      "printing": {
        "printable": false,
        "mode": "PROVISIONAL_RECEIPT",
        "reason": "FISCAL_REJECTED"
      },
      "failure": {
        "code": "FISCAL_BUSINESS_RULE",
        "scope": "FUNCTIONAL",
        "message": "identidad fiscal de tienda no configurada: EC / tienda EC-UIO-001"
      },
      "providerCode": "hio",
      "providerIdentity": { "name": "hio.fiscalization", "version": "dev", "reference": null },
      "providerMetadata": null
    }
  }
  ```

  ```json 200 Loja sem numeração theme={null}
  {
    "success": true,
    "data": {
      "fiscalRequestId": null,
      "orderCode": "EC-K000-42-1786579046934",
      "idempotencyKey": null,
      "reused": false,
      "countryCode": "EC",
      "requestStatus": "NOT_APPLICABLE",
      "documentStatus": null,
      "retryable": false,
      "environment": null,
      "document": null,
      "countryData": null,
      "graphic": null,
      "policy": {
        "numberingFailure": {
          "action": "CONTINUE",
          "lostSaleReason": null,
          "resolvedAt": "2026-08-21T21:59:56.203Z",
          "configVersion": null,
          "resolvedFrom": { "requestStatus": "NOT_APPLICABLE" }
        }
      },
      "printing": { "printable": false, "mode": "NONE", "reason": "NUMBERING_DISABLED" },
      "failure": null,
      "store": {
        "code": "K000",
        "name": "Laboratorio Ecuador",
        "govIdType": "RUC",
        "govIdNumber": "1791415132001"
      },
      "company": {
        "legalName": "INT FOOD SERVICES CORP S.A.",
        "tradeName": "KFC",
        "countryLines": [],
        "legends": []
      },
      "timestamps": {
        "requestedAt": "2026-08-14T01:01:14.7Z",
        "respondedAt": "2026-08-14T01:01:14.7Z",
        "providerLatencyMs": null
      },
      "correlationId": null,
      "providerCode": null,
      "providerIdentity": null,
      "providerMetadata": null
    }
  }
  ```

  ```json 409 Conflito theme={null}
  {
    "success": false,
    "error": "CONFLICT",
    "message": "La Idempotency-Key ya fue usada con un cuerpo distinto"
  }
  ```
</ResponseExample>
