biterp
APIGuias

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)
  • draft ou confirmed → cancelled (cancelar)
  • confirmed → draft é bloqueado

Um pedido cancelled não é editável.

Conceitos e campos-chave

CampoTipoObrigatórioObservações
customer_idUUIDSim**Ou o objeto customer inline — envie um dos dois (ver abaixo)
product_typeenumSimgoods, service ou mixed
order_datedateSim
itemsarraySim1 a 200 itens
statusenumNãodraft ou confirmed (padrão confirmed)
reference_codestringNãoAuto-gerado (SOR-…) se omitido
operation_typestringNãoTipo de operação (padrão sale)
quote_idUUIDNãoOrçamento de origem (product_type deve casar)
delivery_datedateNão
salesperson_namestringNão
discount_amountstringNãoDesconto em valor (≥ 0) — decimal numeric(18,6) como string
discount_ratestringNãoDesconto em percentual (0 a 100) — decimal numeric(9,6) como string
receivablesarrayNãoGera 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 o tax_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

quantity e unit_price sã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 paymentTipoObrigatórioObservações
payment_datedate-timeNãoData/hora do recebimento (sem offset = horário local do tenant). Default: agora
amountstringNãoValor recebido (> 0). Default: amount do título (quitação integral)
payment_method_idUUIDNãoDefault: payment_method_id do título
notesstringNãoAté 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.

En esta página