Sales

Record transactions, process payments, and manage refunds. Sales endpoints handle the core POS transaction lifecycle.

Completed

Transaction finalized and paid

Voided

Entire sale cancelled

Refunded

Full or partial refund issued

GET/api/v1/sales

List all sales/transactions

Query Parameters

ParameterTypeDescription
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20)
fromdateStart date filter (ISO 8601)
todateEnd date filter (ISO 8601)
statusstringFilter by status: completed, voided, refunded
payment_methodstringFilter by payment method: cash, card, mobile
cashier_iduuidFilter by cashier
customer_iduuidFilter by customer

Response

[
  {
    "id": "uuid",
    "receipt_number": "REC-20250518-001",
    "items": [
      {
        "product_id": "uuid",
        "product_name": "Organic Coffee",
        "quantity": 2,
        "price": 1499,
        "discount": 0,
        "total": 2998
      }
    ],
    "subtotal": 2998,
    "tax": 210,
    "discount": 0,
    "total": 3208,
    "payment_method": "card",
    "status": "completed",
    "customer_id": "uuid",
    "customer": { "id": "uuid", "name": "Jane Doe" },
    "cashier_id": "uuid",
    "cashier": { "id": "uuid", "name": "John" },
    "notes": "",
    "created_at": "2025-05-18T14:30:00Z"
  }
]
GET/api/v1/sales/:id

Get a single sale by ID

Response

{
  "id": "uuid",
  "receipt_number": "REC-20250518-001",
  "items": [...],
  "subtotal": 2998,
  "tax": 210,
  "discount": 0,
  "total": 3208,
  "payment_method": "card",
  "status": "completed",
  "customer_id": "uuid",
  "customer": { "id": "uuid", "name": "Jane Doe" },
  "cashier_id": "uuid",
  "notes": "",
  "created_at": "2025-05-18T14:30:00Z"
}
POST/api/v1/sales

Create a new sale (complete a transaction)

Request Body

{
  "items": [
    {
      "product_id": "uuid",
      "quantity": 2,
      "price": 1499,
      "discount": 0
    },
    {
      "product_id": "uuid",
      "quantity": 1,
      "price": 999,
      "discount": 100
    }
  ],
  "payment_method": "cash",
  "amount_received": 5000,
  "customer_id": "uuid",
  "discount": 0,
  "notes": "Regular customer"
}

Response

{
  "id": "uuid",
  "receipt_number": "REC-20250518-002",
  "items": [...],
  "subtotal": 3997,
  "tax": 280,
  "discount": 100,
  "total": 4177,
  "change": 823,
  "payment_method": "cash",
  "status": "completed",
  "created_at": "2025-05-18T15:00:00Z"
}

Stock is automatically decremented for each item. If customer_id is provided, loyalty points are awarded. amount_received is required for cash payments to calculate change.

POST/api/v1/sales/:id/void

Void a completed sale

Request Body

{
  "reason": "Customer returned all items"
}

Response

{
  "id": "uuid",
  "status": "voided",
  "voided_at": "2025-05-18T15:30:00Z",
  "voided_by": "uuid",
  "void_reason": "Customer returned all items"
}

Voids the entire sale and restores stock. Only admin and manager roles can void sales. A reason is required.

POST/api/v1/sales/:id/refund

Refund specific items from a sale

Request Body

{
  "items": [
    {
      "product_id": "uuid",
      "quantity": 1,
      "reason": "Defective item"
    }
  ]
}

Response

{
  "id": "uuid",
  "refund_amount": 1499,
  "refunded_items": [...],
  "status": "partial_refund",
  "created_at": "2025-05-18T16:00:00Z"
}

Supports partial refunds. Refunded quantities are added back to stock. Creates a refund record linked to the original sale.