Emissão assíncrona e polling
A emissão de documentos fiscais é, em geral, assíncrona: a API aceita a requisição (HTTP 202) e segue processando. Esta página explica o contrato de retorno, os dois tipos de resultado e como acompanhar o processamento até um estado terminal.
O contrato HTTP 202
Quando a API responde 202 Accepted, o documento ainda não foi
materializado — ela apenas aceitou o pedido. Quando responde 201/200, o
documento já está pronto. O create traduz isso em um resultado discriminado:
um de dois tipos.
| Resposta HTTP | Tipo de resultado | Significado |
|---|---|---|
| 202 Accepted | Nfe::*Pending | Em processamento; reconsulte depois. |
| 201 / 200 | Nfe::*Issued | Documento já materializado. |
*Pending e *Issued por recursoCada recurso expõe seu par de resultados (por exemplo,
Nfe::Resources::ServiceInvoicePending e Nfe::Resources::ServiceInvoiceIssued).
O tipo base Nfe::Pending carrega invoice_id e location; o Nfe::Issued
carrega resource.
Os dois tipos de resultado
*Pending (202)
#invoice_id— id extraído do último segmento do headerLocation; use-o para reconsultar enquanto processa.#location— o valor bruto do headerLocation.#pending?→true.
*Issued (201/200)
#resource— o documento já materializado (DTO hidratado).#issued?→true.
Distinguindo o resultado
Você pode discriminar com os predicados pending? / issued? ou com pattern
matching:
result = client.service_invoices.create(
company_id: "55df4dc6b6cd9007e4f13ee8",
data: { cityServiceCode: "2690", servicesAmount: 100.0, description: "Suporte" }
)
case result
in Nfe::Resources::ServiceInvoicePending => pending
pending.invoice_id # reconsulte com este id
in Nfe::Resources::ServiceInvoiceIssued => issued
issued.resource # NFS-e já pronta
end
Com predicados:
invoice_id = result.pending? ? result.invoice_id : result.resource.id
Loop de polling manual
Faça polling com retrieve até um estado terminal, decidido por
Nfe::FlowStatus.terminal?:
company_id = "55df4dc6b6cd9007e4f13ee8"
invoice_id = result.pending? ? result.invoice_id : result.resource.id
invoice =
loop do
current = client.service_invoices.retrieve(
company_id: company_id,
invoice_id: invoice_id
)
break current if Nfe::FlowStatus.terminal?(current.flow_status)
sleep 2
end
# `invoice.flow_status` agora é um estado terminal.
Estados de fluxo (flow_status)
Estados terminais (encerram o polling):
| Status | Significado |
|---|---|
Issued | Emitido com sucesso. |
IssueFailed | Falha na emissão. |
Cancelled | Cancelado. |
CancelFailed | Falha no cancelamento. |
Nfe::FlowStatus.terminal? aceita String ou Symbol e retorna true apenas
para os quatro acima; qualquer outro valor (como WaitingSend ou
PullFromCityHall) retorna false.
get_status em service_invoicesO recurso service_invoices oferece get_status, derivado do retrieve (sem
HTTP extra), como atalho para inspecionar o estado atual.
Por que não existe create_and_wait?
A v1.0 não implementa create_and_wait, create_batch nem
poll_until_complete. O contrato discriminado *Pending / *Issued somado a
Nfe::FlowStatus.terminal? é suficiente para escrever loops de polling manuais,
e esses auxiliares ficam deliberadamente adiados para uma versão futura — sem
quebrar o contrato público.
Referenciar client.poll_until_complete(...) ou resource.create_and_wait(...)
na v1.0 levanta NoMethodError, pois o método não está definido.
Próximos passos
- Tratamento de erros — trate falhas durante o polling.
- Configuração — ajuste
timeoutemax_retries. - Primeiros passos — a primeira emissão de ponta a ponta.