Invoices
List all invoices with filters and pagination.
Query Parameters
status(optional: draft, issued, paid, overdue, cancelled)payment_status(optional: pending, partial, paid, refunded)payment_method(optional: cash, mpesa, bank, cash_on_delivery)q(optional, search by invoice_number or notes)date_from(optional, filter from date)date_to(optional, filter until date)page,per_page(optional; default 1 / 20)
Example:
GET /invoices?status=paid&payment_method=cash&page=1&per_page=20
200 OK
{
"invoices": [
{
"id": 1,
"invoice_number": "INV-2025-DEC-13A",
"subtotal": "100.00",
"tax_amount": "16.00",
"discount_amount": "0.00",
"total_amount": "116.00",
"status": "paid",
"payment_status": "paid",
"payment_method": "cash",
"payment_reference": null,
"paid_at": "2025-01-15T14:30:22",
"issue_date": "2025-01-15T14:30:22",
"due_date": null,
"notes": null,
"created_at": "2025-01-15T14:30:22",
"updated_at": "2025-01-15T14:30:22"
}
],
"pagination": {
"page": 1,
"per_page": 20,
"total": 1,
"pages": 1,
"has_next": false,
"has_prev": false
}
}
Get invoice detail including associated cash transactions (if any).
200 OK
{
"invoice": {
"id": 1,
"invoice_number": "INV-2025-DEC-13A",
"subtotal": "100.00",
"tax_amount": "16.00",
"discount_amount": "0.00",
"total_amount": "116.00",
"status": "paid",
"payment_status": "paid",
"payment_method": "cash",
"payment_reference": null,
"paid_at": "2025-01-15T14:30:22",
"issue_date": "2025-01-15T14:30:22",
"due_date": null,
"notes": null,
"created_at": "2025-01-15T14:30:22",
"updated_at": "2025-01-15T14:30:22",
"cash_transactions": [
{
"id": 1,
"invoice_id": 1,
"amount_due": "116.00",
"amount_given": "120.00",
"change_amount": "4.00",
"status": "completed",
"processed_by": 1,
"completed_at": "2025-01-15T14:30:25",
"created_at": "2025-01-15T14:30:22",
"updated_at": "2025-01-15T14:30:25"
}
]
}
}
404 Not Found
Create a new invoice. Invoice number is auto-generated if not provided (format: INV-YEAR-MON-DD+letter, e.g., INV-2025-DEC-13A). Tax amount and total amount are automatically calculated based on subtotal, discount, and tax rate from shop settings. Payment methods must be enabled in shop settings - see Payment Method Validation section below.
Request Body (JSON)
invoice_number(optional, unique; auto-generated if not provided)subtotal(optional, default: 0)discount_amount(optional, default: 0)status(optional: draft, issued, paid, overdue, cancelled; default: draft)payment_status(optional: pending, partial, paid, refunded; default: pending)payment_method(optional: must be one of the enabled payment methods. Valid values: cash, mpesa, bank, cash_on_delivery)payment_reference(optional)issue_date(optional, ISO format; default: current datetime)due_date(optional, ISO format)notes(optional)
Example Request:
POST /invoices
Content-Type: application/json
{
"subtotal": "100.00",
"discount_amount": "10.00",
"status": "draft",
"payment_status": "pending",
"notes": "Test invoice"
}
201 Created
400 Invalid date format or payment method not enabled
409 Invoice number already exists
Payment Method Error Example:
{
"message": "Payment method 'mpesa' is not enabled. Enabled methods: cash, bank"
}
Update invoice status, payment status, payment method, payment reference, or notes. Payment methods must be enabled in shop settings - see Payment Method Validation section below.
Request Body (JSON)
status(optional: draft, issued, paid, overdue, cancelled)payment_status(optional: pending, partial, paid, refunded)payment_method(optional: must be one of the enabled payment methods. Valid values: cash, mpesa, bank, cash_on_delivery)payment_reference(optional)notes(optional)
Example Request:
PATCH /invoices/1/status
Content-Type: application/json
{
"status": "paid",
"payment_status": "paid",
"payment_method": "cash"
}
200 OK
400 Invalid status value or payment method not enabled
404 Invoice not found
Payment Method Error Example:
{
"message": "Payment method 'mpesa' is not enabled. Enabled methods: cash, bank"
}
Process payment for an invoice. Currently supports cash payments. The payment method must be enabled in shop settings. For cash payments, creates a cash transaction, calculates change, and updates the invoice to paid status.
Request Body (JSON)
payment_method(required: must be one of the enabled payment methods. Currently supported: cash)amount_given(required for cash payments: the amount given by the customer)
Example Request (Cash Payment):
POST /invoices/1/pay
Content-Type: application/json
{
"payment_method": "cash",
"amount_given": "120.00"
}
200 OK
{
"message": "Invoice paid successfully",
"invoice": {
"id": 1,
"invoice_number": "INV-2025-DEC-13A",
"total_amount": "116.00",
"status": "paid",
"payment_status": "paid",
"payment_method": "cash",
"paid_at": "2025-12-13T14:30:25"
},
"cash_transaction": {
"id": 1,
"invoice_id": 1,
"amount_due": "116.00",
"amount_given": "120.00",
"change_amount": "4.00",
"status": "completed",
"processed_by": 1,
"completed_at": "2025-12-13T14:30:25"
}
}
400 Payment method not provided, payment method not enabled, amount_given required (for cash), amount given less than amount due, invoice already paid
404 Invoice not found
501 Payment method not yet implemented
Error Examples:
{
"message": "Payment method 'mpesa' is not enabled. Enabled methods: cash, bank"
}
{
"message": "amount_given is required for cash payments"
}
{
"message": "Amount given is less than amount due"
}
{
"message": "Invoice is already paid"
}
Delete an invoice. Cannot delete paid invoices. Associated cash transactions are automatically deleted.
200 OK
400 Cannot delete paid invoice
404 Invoice not found
Payment Method Validation
When creating or updating invoices, the payment_method field is validated against the enabled payment methods in shop settings.
How to Check Enabled Payment Methods
To check which payment methods are currently enabled, use the shop settings endpoint:
GET /shop/settings
The response includes payment method flags:
enable_cash- maps to payment_method: "cash"enable_mpesa- maps to payment_method: "mpesa"enable_bank_payments- maps to payment_method: "bank"enable_cash_on_delivery- maps to payment_method: "cash_on_delivery"
Validation Rules
- If
payment_methodisnullor empty, validation is skipped (invoice can be created without a payment method) - If
payment_methodis provided, it must be one of the enabled methods - If a disabled payment method is used, the API returns a 400 error with a list of enabled methods
Example Error Response:
{
"message": "Payment method 'mpesa' is not enabled. Enabled methods: cash, bank"
}
Notes
- Tax amount is automatically calculated based on the tax rate from shop settings when creating or updating invoices.
- Total amount = Subtotal - Discount + Tax
- Invoice numbers are auto-generated if not provided in the format:
INV-YEAR-MON-DD+letter(e.g., INV-2025-DEC-13A, INV-2025-DEC-13B). After Z, continues with ZA, ZB, etc., then AA, AB, etc. - Cash transactions are included in the invoice detail response if available.
- All date fields should be in ISO 8601 format.
- Payment methods must be enabled in shop settings before they can be used in invoices.