Pedidos de venda
Como criar pedidos de venda na API de Integrações, vinculá-los a orçamentos e gerar contas a receber.
Um pedido de venda (/sales-orders) é a venda confirmada — a etapa central do fluxo de vendas. Ele pode nascer de um orçamento, gerar contas a receber e ser faturado por uma nota.
Permissão exigida: sales-orders (ações create, read, update, delete).
Ciclo de vida
O status de um pedido é draft, confirmed ou cancelled. Na criação, só draft ou confirmed são aceitos — o padrão é confirmed. As transições permitidas via PATCH:
draft→confirmed(confirmar)draftouconfirmed→cancelled(cancelar)confirmed→drafté bloqueado
Um pedido cancelled não é editável.
Conceitos e campos-chave
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
customer_id | UUID | Sim* | *Ou o objeto customer inline — envie um dos dois (ver abaixo) |
product_type | enum | Sim | goods, service ou mixed |
order_date | date | Sim | |
items | array | Sim | 1 a 200 itens |
status | enum | Não | draft ou confirmed (padrão confirmed) |
reference_code | string | Não | Auto-gerado (SOR-…) se omitido |
operation_type | string | Não | Tipo de operação (padrão sale) |
quote_id | UUID | Não | Orçamento de origem (product_type deve casar) |
delivery_date | date | Não | |
salesperson_name | string | Não | |
discount_amount | string | Não | Desconto em valor (≥ 0) — decimal numeric(18,6) como string |
discount_rate | string | Não | Desconto em percentual (0 a 100) — decimal numeric(9,6) como string |
receivables | array | Não | Gera contas a receber (ver abaixo) |
metadata, br_data, notes, description | — | Não |
Cliente inline (customer)
Em vez de customer_id, você pode enviar o objeto customer com os dados do cliente. Ele aceita os mesmos campos de POST /customers, inclusive o endereço completo: address_street, address_number, address_complement, address_district, cidade, estado e CEP (ver Endereço e geografia). Só type e legal_name são obrigatórios.
- Com
tax_id, a API procura no tenant um cliente com esse documento. Se encontrar, o pedido usa esse cliente como ele está: os demais dados do objeto não atualizam o cadastro. Para corrigir o endereço de um cliente existente, use Atualizar cliente. - Sem
tax_id, ou quando nenhum cliente tem esse documento, a API cria o cliente e vincula o pedido a ele. Sem o documento, a API não tem como reaproveitar um cadastro e tenta criar um cliente novo a cada pedido. Por isso, envie sempre otax_id.
Os nomes antigos de endereço (address_line1, address_line2, br_data.address_number e br_data.address_district) são recusados com 400, tanto aqui quanto em /customers. Ver o changelog.
Itens do pedido
quantityeunit_pricesão strings decimais (ex.:"2.000000","450.000000"), como em todos os campos decimais da API.
Cada item referencia um product_id (com item_description, quantity e unit_price) ou traz um objeto product inline, que reaproveita/cria o produto pelo reference_code. quantity é ≥ "0.000001" e unit_price ≥ "0".
Gerando contas a receber
Inclua um array receivables[] para já criar os recebíveis do pedido. Cada item exige amount (decimal como string), due_date (date-time) e financial_account_id (ativo); opcionalmente payment_method_id, financial_category_id, description e payment (recebimento já realizado — ver abaixo). A resposta traz has_active_receivables e o array receivables do pedido.
Recebimento no ato (payment)
Quando a venda já foi paga no checkout (e-commerce, PDV), envie o objeto opcional payment no item de receivables[]. A presença do objeto significa que o título deve nascer já baixado (baixa manual), na mesma transação da confirmação do pedido.
Campo em payment | Tipo | Obrigatório | Observações |
|---|---|---|---|
payment_date | date-time | Não | Data/hora do recebimento (sem offset = horário local do tenant). Default: agora |
amount | string | Não | Valor recebido (> 0). Default: amount do título (quitação integral) |
payment_method_id | UUID | Não | Default: payment_method_id do título |
notes | string | Não | Até 1024 caracteres |
payment: {} equivale a recebimento integral agora. Só é permitido quando o pedido é criado como confirmed (padrão); com status: "draft" a API retorna 422. A baixa usa a financial_account_id do próprio título (não há override de conta em payment). Regras: conta de ativo (não cartão de crédito/passivo), payment.amount ≤ amount do título, soma de receivables[].amount = total do pedido.
A baixa gera uma transação financeira source=manual na conta, conciliável depois com o extrato. Se a conta também recebe movimentações por integração nativa (ex.: gateway), uma baixa manual adicional pode duplicar saldo — use a conta correta.
# Pedido confirmado já pago (um título quitado)
"receivables": [
{
"amount": "2100.000000",
"due_date": "2026-08-06T00:00:00.000Z",
"financial_account_id": "9c8b7a6d-5e4f-4321-8b0a-1d2c3e4f5a6b",
"payment": {}
}
]Criar um pedido (a partir de um orçamento, com recebível)
curl -X POST https://api.biterp.ai/sales-orders \
-H "Authorization: Bearer sk_xxx_yyy" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "8f2c1e4a-9b3d-4c7e-a1f2-6d5b8e0c3a71",
"quote_id": "b1d2f3a4-5c6e-4718-9a0b-2c3d4e5f6a7b",
"product_type": "goods",
"order_date": "2026-07-06",
"status": "confirmed",
"salesperson_name": "Ana Souza",
"items": [
{
"product_id": "3a7b9c2d-1e4f-4a6b-8c0d-2f5e7a9b1c3d",
"item_description": "Cadeira ergonômica",
"quantity": "2.000000",
"unit_price": "450.000000"
},
{
"product_id": "5d8e1f3a-6b2c-4d7e-9a0f-1c3b5e7d9a2f",
"item_description": "Mesa de escritório",
"quantity": "1.000000",
"unit_price": "1200.000000"
}
],
"receivables": [
{
"amount": "2100.000000",
"due_date": "2026-08-06T00:00:00.000Z",
"financial_account_id": "9c8b7a6d-5e4f-4321-8b0a-1d2c3e4f5a6b"
}
]
}'Criar um pedido com cliente inline
curl -X POST https://api.biterp.ai/sales-orders \
-H "Authorization: Bearer sk_xxx_yyy" \
-H "Content-Type: application/json" \
-d '{
"customer": {
"type": "company",
"tax_id": "12.345.678/0001-95",
"tax_id_type": "CNPJ",
"legal_name": "Comercial Exemplo LTDA",
"emails": ["financeiro@exemplo.com.br"],
"address_street": "Av. Paulista",
"address_number": "1000",
"address_complement": "Conj. 12",
"address_district": "Bela Vista",
"city": "São Paulo",
"state": "SP",
"postal_code": "01310-100",
"country_code": "BR"
},
"product_type": "service",
"order_date": "2026-10-25",
"items": [
{
"product_id": "3a7b9c2d-1e4f-4a6b-8c0d-2f5e7a9b1c3d",
"item_description": "Consultoria mensal",
"quantity": "1.000000",
"unit_price": "1500.000000"
}
]
}'Na resposta, o customer embutido traz só id, legal_name, trade_name e tax_id. Guarde o id e use customer_id nos próximos pedidos desse cliente.
Atualizar
Na operação Atualizar pedido, os campos customer_id, quote_id, receivables e operation_type não são editáveis. Além disso, você não pode alterar itens nem descontos quando há recebíveis ativos vinculados ao pedido — cancele/ajuste os recebíveis primeiro.
Buscar pelo número do pedido
Além do UUID, cada pedido recebe um record_number — um inteiro sequencial por tenant, visível para o usuário e distinto do reference_code. É também o critério de ordenação padrão da listagem.
curl "https://api.biterp.ai/sales-orders/by-record-number/2087" \
-H "Authorization: Bearer sk_xxx_yyy"Um record_number que não seja inteiro positivo retorna 400; um número inexistente no tenant retorna 404.
Remover
A operação Remover pedido faz soft delete e responde 204 No Content. Não há endpoint de restauração — ver DELETE é de mão única.
Consulte a referência OpenAPI de pedidos de venda para todos os endpoints disponíveis.

