Skip to main content

Complete POS Invoice (v1)

Method & Path

POST /v1/workspace/:workspaceId/pos/invoices/:invoiceId/complete

Actual backend path: /v1/workspace/:workspaceId/pos/invoices/:invoiceId/complete

Description

Complete a draft POS invoice. This sets the invoice status to completed, deducts product stock for line items whose product has trackInventory enabled (using the same storefront stock service as storefront orders), and sets stockDeductedAt. Products with trackInventory: false are not deducted. The invoice can no longer be modified.

The paymentMethod on the POS invoice itself is always set when the invoice is completed (defaults to cash if omitted in the request). It is stored on the completed POS invoice independently of whether a client financial invoice is created.

When createClientInvoice is used, the same paymentMethod is used for the initial client payment record (when amountPaid > 0). The linked client invoice issueDate (and payment date when applicable) is derived from the invoice’s businessDate and the workspace timezone (not only wall-clock time), so overnight shifts stay under one operational day in financial reports.

Authentication

Required: JWT in Authorization header.

Required permissions: store.orders.manage

Persona: Workspace Owner, Staff (store.orders.manage)

Headers

HeaderTypeRequiredDescription
AuthorizationstringYesBearer token: Bearer <token>

Path Parameters

ParameterTypeRequiredDescription
workspaceIdstringYesWorkspace identifier
invoiceIdstringYesPOS invoice ID

Request Body (optional)

FieldTypeRequiredDescription
paymentMethodstringNoOne of cash, check, bank-transfer, card, other. Stored on the POS invoice when completed. Defaults to cash if omitted.
createClientInvoicebooleanNoIf true, creates a client financial invoice and optional payment
amountPaidnumberNoAmount applied to the client payment when createClientInvoice is true (capped to invoice total; defaults to total)

Example (POS only, no client invoice)

{
"paymentMethod": "card"
}

Example (with client financial invoice)

{
"paymentMethod": "cash",
"createClientInvoice": true,
"amountPaid": 110
}

Response 200 OK

{
"invoice": {
"id": "507f1f77bcf86cd799439012",
"workspaceId": "507f1f77bcf86cd799439010",
"storeId": "507f1f77bcf86cd799439013",
"clientId": "507f1f77bcf86cd799439011",
"publicId": "POS-001",
"status": "completed",
"items": [...],
"subtotal": 110,
"discounts": [],
"total": 110,
"paymentMethod": "cash",
"stockDeductedAt": "2024-01-15T10:05:00.000Z",
"createdBy": { "type": "staff", "id": "...", "name": "...", "email": "..." },
"createdAt": "2024-01-15T10:00:00.000Z",
"updatedAt": "2024-01-15T10:05:00.000Z"
}
}

Common Errors

  • 400 Bad Request: Invalid invoice identifier
  • 401 Unauthorized: Missing or invalid authentication token
  • 403 Forbidden: Insufficient permissions (requires store.orders.manage)
  • 404 Not Found: Workspace or invoice not found
  • 422 Unprocessable Entity: Validation failed. Common cases:
    • Invoice is not in draft status
    • Invoice has no items
    • Stock has already been deducted for this invoice
    • Insufficient stock: One or more products that track inventory have insufficient stock. The response details include:
      • fieldErrors.stockQuantity: array with a summary message
      • insufficientStock (single product): { productId, productName, availableStock, requestedQuantity }
      • insufficientStockProducts (multiple products): array of { productId, productName, availableStock, requestedQuantity }
    • Product not found for an invoice item
  • 500 Internal Server Error: Server error