Venda
Endpoints para gerenciar vendas: abrir um carrinho, adicionar itens e pagamentos, e finalizar ou cancelar a venda. A venda organiza o que foi vendido — o pagamento financeiro é feito separadamente via POST /transaction.
Autenticação
Todas as requisições exigem Basic Auth. Use as credenciais configuradas no TEF IP (admin / senha definida na instalação).
Fluxo de venda
Uma venda segue a sequência: iniciar → adicionar itens → adicionar pagamentos → finalizar (ou cancelar). Apenas uma venda pode estar ativa por vez.
Ciclo de Vida da Venda
Diferente de uma transação avulsa, uma Venda no TEF IP é uma sessão que acumula itens e pagamentos antes de ser consolidada. O servidor gerencia o estado dessa venda internamente.
Fluxo de Estados
stateDiagram-v2
[*] --> Aberta: POST /sale
Aberta --> Aberta: itens (POST/PATCH/DELETE /sale/item · cancel · clear)
Aberta --> Aberta: pagamentos (POST/PATCH/DELETE /sale/payment · clear)
Aberta --> Aberta: descontos (POST/PATCH/DELETE /sale/discount · clear)
Aberta --> Aberta: acréscimos (POST/PATCH/DELETE /sale/addition · clear)
Aberta --> Finalizada: POST /sale/finalize
Aberta --> Cancelada: POST /sale/cancel
Finalizada --> [*]
Cancelada --> [*]
Regras Importantes
- Exclusividade: Apenas uma venda pode estar ativa por vez no dispositivo. Tentar iniciar uma nova sem encerrar a anterior resulta em erro
409 Conflict. - Sincronização: Operações de venda são síncronas. O servidor retorna a confirmação assim que o estado interno é atualizado.
- Documento Fiscal: Os itens e pagamentos adicionados servem de base para a montagem de cupons fiscais e DANFE.
- Pagamento financeiro: A venda registra o quê foi vendido e como foi pago — mas não processa o débito financeiro. O pagamento no cartão ou PIX é feito separadamente via
POST /transaction. Finalize a venda após confirmar a aprovação da transação. - Limpeza: Ao finalizar ou cancelar, o TEF IP limpa automaticamente qualquer conteúdo que esteja sendo exibido no visor do terminal (pop de displays).
Forma das respostas
As rotas de venda seguem uma convenção consistente:
POST/PATCHde uma entidade (item, pagamento, desconto, acréscimo) retornam a própria entidade criada/atualizada.DELETE/clear/cancele as rotas de cabeçalho (GET/POST/PATCH /sale) retornam o cupom completo (SaleCoupon) — o estado atual da venda.POST /sale/finalizeePOST /sale/cancelretornam apenas{ "message": "..." }.
O cupom completo (SaleCoupon) tem o seguinte formato:
{
"sale": {
"customerDocument": "123.456.789-00",
"customerName": "João Silva",
"sellerName": "Maria",
"additionalInfo": "Balcão 3",
"total": null
},
"items": [],
"payments": [],
"discounts": [],
"additions": [],
"summary": {
"subtotal": 0,
"surcharge": 0,
"discount": 0,
"itemDiscount": 0,
"itemAddition": 0,
"total": 0
}
}
Valores monetários em reais
Todos os valores (unitPrice, total, value, discount, addition, etc.) trafegam em reais decimais (ex.: 10.50), não em centavos. Descontos e acréscimos são armazenados em módulo (valor absoluto): enviar -5.00 é equivalente a 5.00.
GET /sale
Retorna o estado da venda ativa (o cupom completo). Útil para sincronizar o carrinho a qualquer momento.
Resposta — 200
Retorna o cupom completo (SaleCoupon, ver Forma das respostas).
Exemplos de integração
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale')
req = Net::HTTP::Get.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
POST /sale
Inicia uma nova venda. Retorna 409 se já existir uma venda ativa.
Corpo da requisição
{
"customerDocument": "123.456.789-00",
"customerName": "João Silva",
"sellerName": "Maria",
"additionalInfo": "Balcão 3"
}
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
customerDocument |
string | Não | CPF ou CNPJ do cliente |
customerName |
string | Não | Nome do cliente exibido no terminal |
sellerName |
string | Não | Nome do vendedor exibido no terminal |
additionalInfo |
string | Não | Informação adicional exibida no terminal |
total |
number | Não | Valor total a exibir na tela de venda |
Resposta — 200
Retorna o cupom completo (SaleCoupon, ver Forma das respostas).
Resposta — 409 (já existe uma venda ativa)
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ customerName: 'João Silva', sellerName: 'Maria' }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'customerName' => 'João Silva',
'sellerName' => 'Maria',
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { customerName: 'João Silva', sellerName: 'Maria' }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
PATCH /sale
Atualiza os dados da venda ativa (cliente, vendedor, informações adicionais). Usa o mesmo corpo que POST /sale.
Resposta — 200
Retorna o cupom completo (SaleCoupon, ver Forma das respostas).
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale', {
method: 'PATCH',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ customerName: 'Maria Souza' }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['customerName' => 'Maria Souza']));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale')
req = Net::HTTP::Patch.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { customerName: 'Maria Souza' }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
DELETE /sale/clear
Esvazia a venda ativa por completo — remove todos os itens, pagamentos, descontos e acréscimos, preservando o cabeçalho (cliente/vendedor).
Resposta — 200
Retorna o cupom completo (SaleCoupon) já esvaziado (ver Forma das respostas).
Exemplos de integração
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/clear');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/clear')
req = Net::HTTP::Delete.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
POST /sale/item
Adiciona um item ao carrinho da venda ativa.
Corpo da requisição
{
"id": "item-001",
"code": "7891234567890",
"description": "Coca-Cola 350ml",
"canceled": false,
"quantity": 2.0,
"unitPrice": 5.00,
"discount": 0.50,
"addition": null,
"total": 9.50,
"additionalInfo": null
}
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id |
string | Sim | Identificador único do item |
code |
string | Sim | Código do produto (ex.: EAN/código de barras) |
description |
string | Sim | Descrição exibida no terminal |
canceled |
bool | Não | Item marcado como cancelado (padrão: false) |
quantity |
number | Sim | Quantidade |
unitPrice |
number | Sim | Preço unitário (reais) |
discount |
number | Não | Desconto aplicado ao item (módulo) |
addition |
number | Não | Acréscimo aplicado ao item |
total |
number | Sim | Valor total do item (reais) |
additionalInfo |
string | Não | Informação adicional |
Resposta — 200
Retorna o item criado (mesmo formato do corpo da requisição).
{
"id": "item-001",
"code": "7891234567890",
"description": "Coca-Cola 350ml",
"canceled": false,
"quantity": 2.0,
"unitPrice": 5.00,
"discount": 0.50,
"addition": null,
"total": 9.50,
"additionalInfo": null
}
Resposta — 400 (item duplicado)
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/item', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({
id: 'item-001',
code: '7891234567890',
description: 'Coca-Cola 350ml',
quantity: 2,
unitPrice: 5.00,
total: 9.50,
}),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/item');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'id' => 'item-001',
'code' => '7891234567890',
'description' => 'Coca-Cola 350ml',
'quantity' => 2,
'unitPrice' => 5.00,
'total' => 9.50,
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/item')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = {
id: 'item-001', code: '7891234567890', description: 'Coca-Cola 350ml',
quantity: 2, unitPrice: 5.00, total: 9.50,
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
PATCH /sale/item/{itemId}
Atualiza os dados de um item já adicionado à venda. O id no corpo é ignorado — o identificador vem do parâmetro de rota.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
itemId |
string | Identificador do item a atualizar |
Corpo igual ao de POST /sale/item. O id no corpo é ignorado — o identificador vem do parâmetro de rota.
Resposta — 200
Retorna o item atualizado (mesmo formato do corpo da requisição).
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/item/item-001', {
method: 'PATCH',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ code: '7891234567890', description: 'Coca-Cola 350ml', quantity: 3, unitPrice: 5.00, total: 14.50 }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/item/item-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'code' => '7891234567890', 'description' => 'Coca-Cola 350ml',
'quantity' => 3, 'unitPrice' => 5.00, 'total' => 14.50,
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/item/item-001')
req = Net::HTTP::Patch.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { code: '7891234567890', description: 'Coca-Cola 350ml', quantity: 3, unitPrice: 5.00, total: 14.50 }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
DELETE /sale/item/clear
Remove todos os itens da venda ativa, preservando pagamentos, descontos e acréscimos.
Resposta — 200
Retorna o cupom completo (SaleCoupon, ver Forma das respostas).
Exemplos de integração
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/item/clear');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/item/clear')
req = Net::HTTP::Delete.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
DELETE /sale/item/{itemId}
Remove um item permanentemente do carrinho da venda ativa.
Cancel vs Delete
- DELETE
/sale/item/{itemId}— remove o item do carrinho; não aparece mais na venda - POST
/sale/item/{itemId}/cancel— mantém o item no carrinho mas o marca como cancelado (canceled: true); útil para manter o histórico de itens cancelados na nota fiscal ou comprovante
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
itemId |
string | Identificador do item a remover |
Resposta — 200
Retorna o cupom completo (SaleCoupon, ver Forma das respostas).
Exemplos de integração
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/item/item-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/item/item-001')
req = Net::HTTP::Delete.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
POST /sale/item/{itemId}/cancel
Marca um item como cancelado sem removê-lo do carrinho. Útil para manter o histórico da venda.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
itemId |
string | Identificador do item a cancelar |
Resposta — 200
Retorna o cupom completo (SaleCoupon) com o item marcado como canceled: true (ver Forma das respostas).
Exemplos de integração
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/item/item-001/cancel');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/item/item-001/cancel')
req = Net::HTTP::Post.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
POST /sale/payment
Adiciona uma forma de pagamento à venda ativa.
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id |
string | Sim | Identificador único do pagamento |
tPag |
string | Não | Código do tipo de pagamento (ver tabela abaixo; padrão "99") |
description |
string | Não | Descrição exibida no terminal |
value |
number | Sim | Valor do pagamento (reais) |
additionalInfo |
string | Não | Informação adicional |
Valores de tPag (código numérico — o mesmo código da adquirente)
Código (tPag) |
Enum SDK | Descrição |
|---|---|---|
"01" |
money |
Dinheiro |
"03" |
credit |
Crédito |
"04" |
debit |
Débito |
"05" |
gift |
Cartão-presente |
"17" |
pix · veroWallet |
PIX / Carteira digital Vero |
"99" |
unknown · voucher · adm · cancel · cancelDigitalWallet |
Demais tipos |
Envie o código numérico, não o nome
No JSON cru, tPag deve ser o código numérico ("17"), não o nome ("pix"). Um nome não reconhecido é interpretado como "99" (desconhecido). No SDK Dart, use o enum TefIPSalePaymentType.pix — ele converte para o código automaticamente.
Resposta — 200
Retorna o pagamento criado (mesmo formato do corpo, com tPag numérico).
Resposta — 400 (pagamento duplicado)
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/payment', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: 'pgto-001', tPag: '17', value: 50.00 }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/payment');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['id' => 'pgto-001', 'tPag' => '17', 'value' => 50.00]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/payment')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { id: 'pgto-001', tPag: '17', value: 50.00 }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
PATCH /sale/payment/{paymentId}
Atualiza os dados de um pagamento já adicionado à venda.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
paymentId |
string | Identificador do pagamento a atualizar |
Corpo igual ao de POST /sale/payment. O id no corpo é ignorado — vem do parâmetro de rota.
Resposta — 200
Retorna o pagamento atualizado (com tPag numérico).
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/payment/pgto-001', {
method: 'PATCH',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ tPag: '03', value: 50.00 }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/payment/pgto-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['tPag' => '03', 'value' => 50.00]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/payment/pgto-001')
req = Net::HTTP::Patch.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { tPag: '03', value: 50.00 }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
DELETE /sale/payment/clear
Remove todos os pagamentos da venda ativa, preservando itens, descontos e acréscimos.
Resposta — 200
Retorna o cupom completo (SaleCoupon, ver Forma das respostas).
Exemplos de integração
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/payment/clear');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/payment/clear')
req = Net::HTTP::Delete.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
DELETE /sale/payment/{paymentId}
Remove uma forma de pagamento do carrinho da venda ativa.
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
paymentId |
string | Identificador do pagamento a remover |
Resposta — 200
Retorna o cupom completo (SaleCoupon, ver Forma das respostas).
Exemplos de integração
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/payment/pgto-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/payment/pgto-001')
req = Net::HTTP::Delete.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
Descontos da venda
Descontos são valores subtraídos do total da venda, independentes dos descontos por item. Cada desconto tem um id próprio.
POST /sale/discount
Adiciona um desconto à venda ativa.
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id |
string | Sim | Identificador único do desconto |
description |
string | Não | Descrição exibida no terminal |
value |
number | Sim | Valor do desconto em reais (armazenado em módulo) |
additionalInfo |
string | Não | Informação adicional |
Resposta — 200
Retorna o desconto criado (mesmo formato do corpo).
Resposta — 400 (desconto duplicado)
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/discount', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: 'desc-001', description: 'Cupom 10%', value: 5.00 }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/discount');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'id' => 'desc-001', 'description' => 'Cupom 10%', 'value' => 5.00,
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/discount')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { id: 'desc-001', description: 'Cupom 10%', value: 5.00 }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
PATCH /sale/discount/{discountId}
Atualiza um desconto existente. O id no corpo é ignorado — vem do parâmetro de rota. Retorna o desconto atualizado.
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/discount/desc-001', {
method: 'PATCH',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ value: 7.50 }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/discount/desc-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['value' => 7.50]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/discount/desc-001')
req = Net::HTTP::Patch.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { value: 7.50 }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
DELETE /sale/discount/{discountId} · DELETE /sale/discount/clear
DELETE /sale/discount/{discountId} remove um desconto; DELETE /sale/discount/clear remove todos. Ambos retornam o cupom completo (SaleCoupon, ver Forma das respostas).
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/discount/desc-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/discount/desc-001')
req = Net::HTTP::Delete.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
Acréscimos da venda
Acréscimos são valores somados ao total da venda (ex.: taxa de serviço). Simétricos aos descontos, cada um com id próprio.
POST /sale/addition
Adiciona um acréscimo à venda ativa.
Corpo da requisição
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id |
string | Sim | Identificador único do acréscimo |
description |
string | Não | Descrição exibida no terminal |
value |
number | Sim | Valor do acréscimo em reais (armazenado em módulo) |
additionalInfo |
string | Não | Informação adicional |
Resposta — 200
Retorna o acréscimo criado (mesmo formato do corpo).
Resposta — 400 (acréscimo duplicado)
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/addition', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ id: 'acrs-001', description: 'Taxa de serviço 10%', value: 4.50 }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/addition');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'id' => 'acrs-001', 'description' => 'Taxa de serviço 10%', 'value' => 4.50,
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/addition')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { id: 'acrs-001', description: 'Taxa de serviço 10%', value: 4.50 }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
PATCH /sale/addition/{additionId}
Atualiza um acréscimo existente. O id no corpo é ignorado — vem do parâmetro de rota. Retorna o acréscimo atualizado.
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/addition/acrs-001', {
method: 'PATCH',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ value: 6.00 }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/addition/acrs-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['value' => 6.00]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/addition/acrs-001')
req = Net::HTTP::Patch.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { value: 6.00 }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
DELETE /sale/addition/{additionId} · DELETE /sale/addition/clear
DELETE /sale/addition/{additionId} remove um acréscimo; DELETE /sale/addition/clear remove todos. Ambos retornam o cupom completo (SaleCoupon, ver Forma das respostas).
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/addition/acrs-001');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/addition/acrs-001')
req = Net::HTTP::Delete.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
POST /sale/finalize
Finaliza a venda ativa. Todos os itens e pagamentos adicionados são consolidados.
Corpo da requisição (opcional)
{
"message": "Obrigado pela compra!",
"showMessage": true,
"showCloseButton": true,
"showResultScreen": true,
"buttonCloseText": "Fechar",
"messageInterval": 3000
}
| Campo | Tipo | Padrão | Descrição |
|---|---|---|---|
message |
string | null |
Mensagem exibida ao finalizar |
showMessage |
bool | true |
Exibe a mensagem de finalização |
showCloseButton |
bool | true |
Exibe botão para fechar a tela |
showResultScreen |
bool | true |
Exibe a tela de resultado da venda |
buttonCloseText |
string | null |
Texto do botão fechar |
messageInterval |
int | 3000 |
Duração (ms) da mensagem exibida |
Resposta — 200
Exemplos de integração
// TODO: pacote JavaScript ainda não criado — usando fetch diretamente
const res = await fetch('http://localhost:9050/sale/finalize', {
method: 'POST',
headers: {
'Authorization': 'Basic ' + btoa('admin:1234'),
'Content-Type': 'application/json',
},
body: JSON.stringify({ message: 'Obrigado pela compra!', showMessage: true }),
});
const data = await res.json();
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/finalize');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['message' => 'Obrigado pela compra!', 'showMessage' => true]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/finalize')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req.basic_auth('admin', '1234')
req.body = { message: 'Obrigado pela compra!', showMessage: true }.to_json
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)
POST /sale/cancel
Cancela a venda ativa e limpa o carrinho.
Corpo da requisição (opcional)
Mesmo formato de POST /sale/finalize.
Resposta — 200
Exemplos de integração
<?php
// TODO: pacote PHP ainda não criado — usando curl diretamente
$ch = curl_init('http://localhost:9050/sale/cancel');
curl_setopt($ch, CURLOPT_USERPWD, 'admin:1234');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
# TODO: pacote Ruby ainda não criado — usando Net::HTTP diretamente
require 'net/http'
require 'json'
uri = URI('http://localhost:9050/sale/cancel')
req = Net::HTTP::Post.new(uri)
req.basic_auth('admin', '1234')
res = Net::HTTP.start(uri.hostname, uri.port) { |h| h.request(req) }
data = JSON.parse(res.body)