Vendas de balcão
Registra uma venda de balcão com NFC-e, lista as vendas do período e cancela uma venda.
Três operações cobrem o ciclo da venda: registrar, listar e cancelar. Todas exigem o módulo fiscal ligado; vender e listar pedem manage_pos ou manage_settings, e cancelar pede manage_nfe ou manage_settings.
Registrar uma venda
Cria o pedido de balcão (já pago), grava a venda e tenta emitir a NFC-e na hora, esperando até 15 segundos. Os preços são relidos do catálogo. Ao final, um evento de venda concluída é publicado para integrações internas.
/api/v1/admin/pos/salesAdminRegistra uma venda de balcão e emite a NFC-e
Corpo da requisição
establishment_iduuidobrigatórioitemsarrayobrigatórioLinhas da venda. Não pode ser vazia, e o total (soma de preço vezes quantidade menos descontos) precisa ser maior que zero.
product_iduuidobrigatórioquantityintegerobrigatóriounit_price_centsintegerdiscount_centsintegerpadrão: 0customer_cpfstring300000 centavos) ou mais.customer_namestringpayment_methodstringcashcardpixamount_paid_centsintegerpaymentsarrayPagamento dividido (opcional). Quando enviado, substitui payment_method e amount_paid_cents: a forma principal é a de maior valor e o recebido é a soma. A soma precisa cobrir o total.
methodstringobrigatóriocashcardpixamount_centsintegerobrigatórioExemplo de requisição
curl -X POST "$BASE_URL/api/v1/admin/pos/sales" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"establishment_id": "11111111-1111-1111-1111-111111111111",
"items": [
{ "product_id": "4cbcf967-23e0-4705-88f7-a74a9a8c63f3", "quantity": 2, "discount_cents": 100 }
],
"customer_cpf": "123.456.789-09",
"customer_name": "Maria Souza",
"payments": [
{ "method": "cash", "amount_cents": 2000 },
{ "method": "pix", "amount_cents": 1880 }
]
}'Resposta
{
"sale_id": "6f1d6b4e-0a52-4f6a-9d3f-0e1f2a3b4c5d",
"order_id": "a8a3c7a3-5f15-45a8-a385-4f20fbf8b722",
"nfe_record_id": "3b9c1a6e-77a1-4c0e-8f60-2a4d5e6f7a8b",
"emission_status": "authorized",
"danfe_url": "https://exemplo.com/danfe/abc123.pdf"
}Campos da resposta
sale_iduuidorder_iduuidpos, pago).nfe_record_iduuidemission_statusstringpendingauthorizedfaileddanfe_urlstringErros
| Status | Quando | Corpo |
|---|---|---|
| 400 | Corpo que não é JSON | {"error":"invalid body","detail":"..."} |
| 401 / 403 | Sem token, sem privilégio, ou módulo fiscal desligado | {"error":"module_disabled","module":"focusnfe"} |
| 422 | Carrinho vazio ou total zero | {"error":"failed to complete sale","detail":"fiscal: carrinho vazio"} |
| 422 | Quantidade zero ou negativa | {"error":"failed to complete sale","detail":"fiscal: item com quantidade inválida"} |
| 422 | Produto inexistente ou apagado | {"error":"failed to complete sale","detail":"fiscal: produto inválido ou indisponível"} |
| 422 | Total de R$ 3.000,00 ou mais sem CPF | {"error":"failed to complete sale","detail":"fiscal: identificação do consumidor obrigatória acima de R$ 3.000,00"} |
| 422 | Pagamento dividido com forma inválida, parcela menor ou igual a zero, ou soma menor que o total | {"error":"failed to complete sale","detail":"fiscal: soma dos pagamentos é menor que o total da venda"} |
| 422 | NFC-e desabilitada nas configurações | {"error":"failed to complete sale","detail":"fiscal: emissão de NFC-e desabilitada nas configurações"} |
| 422 | Estabelecimento inexistente | {"error":"failed to complete sale","detail":"fiscal: estabelecimento inválido"} |
| 422 | Estabelecimento sem provisionamento | {"error":"establishment not provisioned","detail":"..."} |
| 503 | Serviço fiscal indisponível | {"error":"fiscal service unavailable"} |
As mensagens de detail voltam em português, como mostrado.
Listar vendas
Lista as vendas de balcão, da mais nova para a mais antiga. Sem from e to, devolve só as vendas do dia atual (é a lista "vendas do dia" do caixa). Para um período maior, informe as datas.
/api/v1/admin/pos/salesAdminLista as vendas de balcão
Parâmetros de consulta
fromstringYYYY-MM-DD. Valor ilegível é ignorado.tostringYYYY-MM-DD. Com YYYY-MM-DD o dia inteiro entra.pageintegerpadrão: 1per_pageintegerpadrão: 50Exemplo de requisição
curl "$BASE_URL/api/v1/admin/pos/sales?from=2026-10-01&to=2026-10-11&per_page=20" \
-H "Authorization: Bearer $TOKEN"Resposta
{
"items": [
{
"id": "6f1d6b4e-0a52-4f6a-9d3f-0e1f2a3b4c5d",
"order_id": "a8a3c7a3-5f15-45a8-a385-4f20fbf8b722",
"establishment_id": "11111111-1111-1111-1111-111111111111",
"customer_cpf": "12345678909",
"payment_method": "cash",
"amount_paid_cents": 4000,
"change_cents": 120,
"nfe_record_id": "3b9c1a6e-77a1-4c0e-8f60-2a4d5e6f7a8b",
"status": "completed",
"created_at": "2026-10-11T14:32:10.512Z"
}
],
"total": 1
}Sem nenhuma venda no período, items vem null e total vem 0.
Campos da resposta
items[].iduuiditems[].order_iduuiditems[].establishment_iduuiditems[].customer_cpfstringitems[].payment_methodstringcashcardpixitems[].amount_paid_centsintegeritems[].change_centsintegeritems[].nfe_record_iduuiditems[].statusstringcompletedcancelleditems[].created_atstringtotalintegerErros
| Status | Quando | Corpo |
|---|---|---|
| 401 / 403 | Sem token, sem privilégio, ou módulo fiscal desligado | {"error":"module_disabled","module":"focusnfe"} |
| 500 | Falha interna | {"error":"failed to list sales","detail":"..."} |
Cancelar uma venda
Cancela a NFC-e no provedor fiscal e, se isso deu certo, cancela o pedido de balcão e marca a venda como cancelled. A ordem importa: a venda só muda para cancelled depois que o provedor confirma. O cancelamento de NFC-e só é aceito dentro do prazo da SEFAZ (a secretaria da Fazenda do estado); passado o prazo, o provedor recusa e a venda continua completed.
/api/v1/admin/pos/sales/{id}/cancelAdminCancela uma venda de balcão
Parâmetros de caminho
iduuidobrigatóriosale_id, não o do pedido).Corpo da requisição
justificationstringpos_sale_cancelled.Exemplo de requisição
curl -X POST "$BASE_URL/api/v1/admin/pos/sales/6f1d6b4e-0a52-4f6a-9d3f-0e1f2a3b4c5d/cancel" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"justification": "Cliente desistiu da compra no caixa"}'Resposta
{ "id": "6f1d6b4e-0a52-4f6a-9d3f-0e1f2a3b4c5d", "status": "cancelled" }Erros
| Status | Quando | Corpo |
|---|---|---|
| 401 / 403 | Sem token, sem privilégio, ou módulo fiscal desligado | {"error":"module_disabled","module":"focusnfe"} |
| 422 | Venda inexistente | {"error":"failed to cancel","detail":"sql: no rows in result set"} |
| 422 | O provedor fiscal recusou o cancelamento (por exemplo, fora do prazo) ou o pedido não pôde ser cancelado | {"error":"failed to cancel","detail":"..."} |