Ir para o conteúdo

Registrar Venda

Registra a venda finalizada. É a terceira operação do fluxo de PDV, chamada ao fechar a compra. Responde 202 Accepted imediatamente; a gravação é assíncrona.

Processamento assíncrono

O 202 Accepted significa que a venda foi recebida (status = RECEIVED), não necessariamente processada. O PDV não deve esperar por processamento síncrono.

Item Valor
URL POST /api/v1/tenants/{tenantId}/sales
Método POST
Autenticação Basic Auth
Content-Type application/json

Request

{
  "protocol": "ROCK_V1",
  "customer": { "id": "10098075012", "type": "CPF" },
  "sale": {
    "id": 45821,
    "store": { "id": "LOJA-001", "posId": "PDV-01", "employeeId": "OP001", "sellerId": "VEND01" },
    "channel": "1",
    "posProvider": "ROCK",
    "date": "2024-06-15T14:30:00Z",
    "amount": 45.90,
    "amountPayable": 40.90,
    "discountAmount": 5.00,
    "items": [
      {
        "id": "1",
        "gtin": "7891234567890",
        "description": "Leite Integral 1L",
        "unitPrice": 7.50,
        "quantity": 2,
        "unitMeasure": "UN",
        "discounts": [
          { "promotionId": "100", "partnerPromotionId": "PROMO-EXT-001", "quantity": 2, "unitDiscount": 2.50 }
        ]
      },
      {
        "id": "2",
        "gtin": "7899876543210",
        "description": "Arroz 5kg",
        "unitPrice": 30.90,
        "quantity": 1
      }
    ],
    "payments": [
      { "id": 1, "amount": 40.90, "method": "PIX", "bin": "411111", "nsu": "123456789", "installments": 1 }
    ],
    "fiscalDocument": {
      "number": "000123456",
      "serialNumber": "001",
      "model": "65",
      "type": "NFC-e",
      "url": "https://nfce.fazenda.gov.br/consulta?chave=123"
    }
  }
}
{
  "protocol": "ROCK_V1",
  "sale": {
    "id": 45822,
    "store": { "id": "LOJA-001", "posId": "PDV-01" },
    "channel": "LOJA",
    "date": "2024-06-15T15:00:00Z",
    "amount": 30.90,
    "amountPayable": 30.90,
    "items": [
      { "id": "1", "gtin": "7899876543210", "description": "Arroz 5kg", "unitPrice": 30.90, "quantity": 1 }
    ],
    "payments": [ { "id": 1, "amount": 30.90, "method": "DINHEIRO" } ]
  }
}

Venda sem cliente

Quando customer é omitido/null, a venda é registrada para o cliente padrão (00000000000), sem reserva de descontos.

Campos do request

Campo Tipo Obrigatório Descrição
protocol string Sim Protocolo (ex: ROCK_V1)
customer object Não Omitido/null → cliente não identificado (00000000000)
customer.id string Não CPF/CNPJ. Null/vazio → não identificado
customer.type string Não CPF ou CNPJ
sale.id number (Long) Sim Número do cupom/recibo
sale.store.id string Sim Código externo da loja
sale.store.posId string Sim Identificador do PDV
sale.channel string Sim Canal de venda
sale.date Instant Sim Data/hora da venda (ISO 8601)
sale.amount number Sim Valor bruto total (positivo)
sale.amountPayable number Sim Valor a pagar após descontos (positivo)
sale.discountAmount number Não Valor total de desconto
sale.items array Sim (não vazio) Itens da venda
sale.items[].id string Sim ID sequencial do item
sale.items[].gtin string Sim GTIN/EAN
sale.items[].description string Sim Descrição do produto
sale.items[].unitPrice number Sim Preço unitário (positivo)
sale.items[].quantity number Sim Quantidade (positiva)
sale.items[].discounts[].promotionId string Sim (se houver desconto) ID do desconto Rock
sale.items[].discounts[].quantity number Sim (se houver desconto) Quantidade com desconto
sale.items[].discounts[].unitDiscount number Sim (se houver desconto) Valor do desconto por unidade
sale.payments array Sim (não vazio) Pagamentos
sale.payments[].id number (Long) Sim ID do pagamento
sale.payments[].amount number Sim Valor pago (positivo)
sale.payments[].method string Sim Forma de pagamento
sale.fiscalDocument object Não Documento fiscal (opcional)

Preserve os descontos autorizados

Reenvie os descontos obtidos na Operação 2 mantendo o promotionId, para que a venda seja registrada com os benefícios corretos.


Response 202 Accepted

{
  "customer": { "id": "10098075012", "type": "CPF" },
  "sale": { "id": 45821, "status": "RECEIVED" },
  "messages": [ { "type": "SUCCESS", "content": "Venda registrada com sucesso." } ]
}
Campo Descrição
customer.id CPF/CNPJ do cliente. 00000000000 quando não identificado
customer.type CPF/CNPJ, ou null quando não identificado
sale.id Ecoado do request
sale.status RECEIVED — venda recebida para processamento assíncrono
messages Mensagens de retorno da operação

Status codes

HTTP Tipo Causa
202 — Venda recebida com sucesso
400 validation-error Campos obrigatórios ausentes/inválidos, ou CPF 00000000000 enviado com descontos
401 unauthorized Credenciais inválidas
404 resource-not-found Loja não encontrada pelo código externo
422 sale-value-inconsistency Divergência entre total dos itens e valor da venda além da tolerância
503 sale-notification-disabled Recurso de registro de venda desativado para o tenant

Detalhes do formato de erro em Tratamento de Erros.


Exemplo — curl

curl -X POST "https://<BASE_URL>/api/v1/tenants/<TENANT_ID>/sales" \
  -u "<CLIENT_ID>:<CLIENT_SECRET>" \
  -H "Content-Type: application/json" \
  -d '{ "protocol": "ROCK_V1", "customer": { "id": "10098075012", "type": "CPF" }, "sale": { "id": 45821, "store": { "id": "LOJA-001", "posId": "PDV-01" }, "channel": "1", "date": "2024-06-15T14:30:00Z", "amount": 25.00, "amountPayable": 25.00, "items": [ { "id": "1", "gtin": "7891234567890", "description": "Produto", "unitPrice": 25.00, "quantity": 1 } ], "payments": [ { "id": 1, "amount": 25.00, "method": "PIX" } ] } }'

Referências