Skip to main content

Invoice lifecycle and corrections

An invoice is not a single event — it is a lifecycle. Nox-Billings centralises that lifecycle so every transition is validated, recorded, and safe to correct. This guide explains the states, the corrections that are allowed, and the guarantees behind them.

The states

StateWhat it means
DRAFTBeing built; editable and not yet a legal document.
HELDA completed sale that is pending an approval or a payment decision.
COMPLETEDA valid invoice with its payment state recorded (paid, partial, or unpaid).
CANCELLEDThe invoice is voided with a recorded reason; it remains in history.
REFUNDEDMoney (or line items) have been returned; the original record stays visible.

Payment status is tracked separately: PAID, UNPAID, PARTIAL, or REFUNDED. An invoice can be completed but unpaid, or paid in part — the payment state is not the same as the document state.

Issuing an invoice

Issuing turns a draft (or a direct sale) into a completed invoice. The issuance step:

  1. Creates the invoice with its line items and totals.
  2. Persists a receipt snapshot for the printed or shared receipt.
  3. Publishes an invoice.issued domain event so integrations and webhooks stay in sync.

Issuance is idempotent: retrying the same request with the same idempotency key cannot create a second invoice. If the receipt snapshot fails, the invoice is still created and the failure is surfaced to the caller rather than silently lost.

Editing a draft

Only DRAFT invoices are editable. Once an invoice is issued (completed), it becomes immutable: use cancellation, refunds, returns, or accounting adjustment documents for corrections — never edit a completed invoice in place.

Cancelling an invoice

Cancellation is a recorded action, not a deletion:

  • A cancellation requires a reason and the actor who performed it.
  • The invoice stays in history with status CANCELLED — the sequence and the audit trail are preserved.
  • A cancelled invoice cannot be re-issued as the same document; create a new draft if the sale still stands.

Refunding an invoice

A refund references the original invoice:

  • Refunds can be full or partial (line-item quantities).
  • A refund requires a reason and is recorded against the actor who performed it.
  • Payment status moves to REFUNDED for a full refund, or PARTIAL when only some money returns.
  • The day-end report surfaces refunds and cancellations separately so the close matches the drawer.

Discount approvals within the lifecycle

A sale can enter HELD when a discount exceeds the cashier's limit:

  • The manager approves the discount to continue the sale, or rejects it.
  • Rejecting a discount cancels the held invoice with the recorded decision.
  • Both decisions are stored so the discount impact at day-end is explainable.

Why the lifecycle matters

The lifecycle exists so the books can be reconstructed. Every invoice has a state, a reason for corrective actions, and an actor. When the day-end report, the audit log, and the ledger all describe the same lifecycle, the owner can answer "what happened to this invoice?" — not just "what was the total?"