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
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer token: Bearer <token> |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
workspaceId | string | Yes | Workspace identifier |
invoiceId | string | Yes | POS invoice ID |
Request Body (optional)
| Field | Type | Required | Description |
|---|---|---|---|
paymentMethod | string | No | One of cash, check, bank-transfer, card, other. Stored on the POS invoice when completed. Defaults to cash if omitted. |
createClientInvoice | boolean | No | If true, creates a client financial invoice and optional payment |
amountPaid | number | No | Amount 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
detailsinclude:fieldErrors.stockQuantity: array with a summary messageinsufficientStock(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