Skip to main content
POST
/
api
/
sales
Create Sale
curl --request POST \
  --url https://api.example.com/api/sales \
  --header 'Content-Type: application/json' \
  --data '
{
  "items": [
    {
      "id": {},
      "quantity": 123
    }
  ],
  "subtotal": 123,
  "tipoEntrega": "<string>",
  "medioPago": "<string>",
  "cpDestino": "<string>",
  "direccionEnvio": "<string>",
  "ciudadEnvio": "<string>",
  "provinciaEnvio": "<string>",
  "telefonoEnvio": "<string>",
  "documentoEnvio": "<string>"
}
'
{
  "success": true,
  "data": {
    "id": 123,
    "fecha": "<string>",
    "montoTotal": 123,
    "estado": "<string>",
    "costoEnvio": 123,
    "tipoEntrega": "<string>",
    "medioPago": "<string>",
    "clienteId": 123,
    "lineasVenta": [
      {}
    ]
  },
  "error": "<string>",
  "details": [
    {}
  ]
}

Authentication

This endpoint requires authentication. Include the JWT token in the Authorization header.

Request Body

items
array
required
Array of items to purchase. Each item must contain:
id
string | number
required
Product ID
quantity
number
required
Quantity to purchase (minimum: 1)
subtotal
number
required
Subtotal amount (minimum: 0)
tipoEntrega
string
required
Delivery type. Must be one of:
  • ENVIO - Shipping
  • RETIRO - Pickup at store
medioPago
string
required
Payment method. Must be one of:
  • MERCADOPAGO - MercadoPago payment gateway
  • EFECTIVO - Cash payment
  • VIUMI - Viumi payment
  • TRANSFERENCIA - Bank transfer
  • BINANCE - Binance cryptocurrency payment
cpDestino
string
Destination postal code (minimum 4 characters). Required if tipoEntrega is ENVIO.
direccionEnvio
string
Shipping address. Required if tipoEntrega is ENVIO.
ciudadEnvio
string
Shipping city. Required if tipoEntrega is ENVIO.
provinciaEnvio
string
Shipping province. Required if tipoEntrega is ENVIO.
telefonoEnvio
string
Shipping phone number. Required if tipoEntrega is ENVIO.
documentoEnvio
string
Recipient’s ID document (DNI). Required for shipping services.

Response

success
boolean
Indicates if the request was successful
data
object
The created sale object
id
number
Sale ID
fecha
string
Sale creation date (ISO 8601 timestamp)
montoTotal
number
Total sale amount including shipping
estado
string
Sale status. One of: PENDIENTE_PAGO, PENDIENTE_APROBACION, APROBADO, ENVIADO, ENTREGADO, RECHAZADO, CANCELADO
costoEnvio
number
Shipping cost
tipoEntrega
string
Delivery type: ENVIO or RETIRO
medioPago
string
Payment method selected
clienteId
number
Customer ID
lineasVenta
array
Array of sale line items
error
string
Error message if the request failed
details
array
Validation error details (if validation failed)

Example Request

{
  "items": [
    {
      "id": 123,
      "quantity": 2
    },
    {
      "id": 456,
      "quantity": 1
    }
  ],
  "subtotal": 45000,
  "tipoEntrega": "ENVIO",
  "medioPago": "TRANSFERENCIA",
  "cpDestino": "1414",
  "direccionEnvio": "Av. Corrientes 1234",
  "ciudadEnvio": "Buenos Aires",
  "provinciaEnvio": "Capital Federal",
  "telefonoEnvio": "+5491112345678",
  "documentoEnvio": "12345678"
}

Example Response

{
  "success": true,
  "data": {
    "id": 789,
    "fecha": "2026-03-05T10:30:00.000Z",
    "montoTotal": 50000,
    "estado": "PENDIENTE_PAGO",
    "costoEnvio": 5000,
    "tipoEntrega": "ENVIO",
    "medioPago": "TRANSFERENCIA",
    "clienteId": 42,
    "direccionEnvio": "Av. Corrientes 1234",
    "ciudadEnvio": "Buenos Aires",
    "provinciaEnvio": "Capital Federal",
    "cpEnvio": "1414",
    "telefonoEnvio": "+5491112345678",
    "documentoEnvio": "12345678",
    "lineasVenta": [
      {
        "id": 1,
        "productoId": 123,
        "cantidad": 2,
        "subTotal": 30000
      },
      {
        "id": 2,
        "productoId": 456,
        "cantidad": 1,
        "subTotal": 15000
      }
    ]
  }
}

Error Responses

Validation Error (400)

{
  "success": false,
  "error": "Datos de venta inválidos",
  "details": [
    {
      "code": "invalid_type",
      "expected": "number",
      "received": "string",
      "path": ["subtotal"],
      "message": "Expected number, received string"
    }
  ]
}

Product Not Found or Insufficient Stock (400)

{
  "success": false,
  "error": "Producto no encontrado"
}
{
  "success": false,
  "error": "Stock insuficiente"
}

Unauthorized (401)

{
  "success": false,
  "error": "Unauthorized"
}

Notes

  • The sale is created with status PENDIENTE_PAGO by default
  • Stock is reserved when the sale is created
  • Shipping cost is automatically calculated based on the postal code for shipments
  • For RETIRO (pickup), no shipping information is required
  • The authenticated user must have an associated customer profile

Build docs developers (and LLMs) love