Invoices — Reference
The Invoices surface is the billing-document plane for every SGEN ecommerce site. It owns the invoice record, the line-item structure that drives the totals, the tax breakdown, the send-to-customer artifact, and the paid / unpaid lifecycle. Anything that represents a billing obligation between the operator and a customer — separate from the order capture itself — traces back to a record managed here.
This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or reconciling against an external accounting system. Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.
Overview
Invoices live under the Invoices module in SG-Admin, inside the ecommerce sub-tree. The module renders four primary views — the invoice list, the invoice detail page, the invoice composer (create / edit), and the send-to-customer composer — and exposes a small set of write operations for create, edit, send, mark paid, mark unpaid, void, and soft delete.
The module is paired by convention with the Orders surface but is intentionally distinct. An order is the customer-facing transactional record (catalog snapshot, fulfillment workflow, payment-capture lifecycle); an invoice is the billing document (line items, tax breakdown, due date, send-to-customer artifact, paid status). One order can produce zero, one, or many invoices; one invoice can carry line items that do not correspond to any order (manual billing, service fees, deposit invoices).
A second surface — invoice templates — lives adjacent to the Invoices module. Operators define the visual and structural template that renders each invoice for download and email delivery. The template surface is shared with packing slips and other transactional documents; this page covers only the invoice record and the operations that act on it.
Where it lives in SG-Admin:
- Sidebar: SG-Admin → Ecommerce → Invoices
- URL prefix:
/sg-admin/invoices/ - View templates:
application/views/Admin/Invoices/
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Ecommerce → Invoices [+ New invoice] │├──────────────────────────────────────────────────────────────────────┤│ # Customer Total Status Due ││ ───── ─────────────────── ──────── ────────────── ──────────────││ INV-1043 Maria Reyes $148.00 Paid — paid 2d ago ││ INV-1042 Sandbox Buyer $ 32.50 Sent in 12 days ││ INV-1041 Jerome Cruz $612.75 Overdue 7 days ago ││ INV-1040 James Compton $ 89.00 Draft — ││ INV-1039 Anonymous $ 14.99 Void — ││ ││ Filter: [Status ▼] [Date range] [Customer] Bulk: [Send reminder] │└──────────────────────────────────────────────────────────────────────┘Actions
The Invoices surface exposes the following operations. Each is described by what it does to the data, not by its internal method name.
List and search
Returns the invoice records visible to the current operator, paginated, with invoice number, customer, total, status, and due-date columns. Supports column sort, free-text filter, status filter, date-range filter, and an overdue filter. Driven by the data-table contract used across SG-Admin modules — responses arrive as a row collection plus a total count, suitable for direct binding to a paged grid.
Engineering note: the overdue filter is computed against the configured site time zone, not the visitor's locale. Operators reconciling against an external accounting system should align time zones before reconciling.
View invoice detail
Loads the full invoice record into a read-mostly detail page — customer block, line items, tax breakdown, totals, due date, status history, payment events, and the rendered preview of the customer-facing document. Editable fields are gated behind separate actions; the detail page itself does not write.
Create invoice (manual)
Opens an empty invoice composer for operator-entered billing. Required at minimum: customer (or guest contact), at least one line item, currency, and due date. Optional fields cover purchase-order reference, customer note, internal note, tax override per line, and an attached order reference. On submit, the surface validates customer existence, computes line totals, applies the configured tax rules, computes the grand total, and persists the record with status draft until explicitly advanced.
Generate invoice from order
A focused write path. Accepts an order identifier and an optional line-item subset; the surface copies the relevant line snapshots from the order, applies any configured tax overrides, sets the customer block from the order's customer record, and persists a new invoice in draft status linked back to the source order. Useful for partial-fulfillment billing and for separating invoicing from the order itself.
Edit invoice
Loads an existing record into the same composer used for create, pre-populated. Line items, customer block, due date, tax overrides, and notes are editable while status is draft. Once an invoice has been sent or marked paid, only the customer note and internal note are editable; structural edits require voiding and reissuing.
Engineering note: structural edits on a sent invoice would change the document the customer already received. The surface intentionally blocks this rather than silently rewriting history. Void-and-reissue produces a new invoice number and a clear audit trail.
Send to customer
Renders the invoice against the configured template and delivers it to the customer's email. The surface records the delivery event (timestamp, target address, send result) and advances the invoice status from draft to sent. Re-sending an already-sent invoice records another delivery event but does not change status.
Mark paid
A focused write path. Operator records a payment against the invoice — amount, method, reference, and date. Marking paid for the full grand total advances status to paid; marking paid for a partial amount advances to partially-paid and records the remaining balance. Multiple partial payments accumulate; the surface tracks the running paid total and updates status on full payment.
Mark unpaid
Reverses a paid or partially-paid status back to sent. Used to correct accounting errors or to roll back a payment that was recorded against the wrong invoice. The original payment event is preserved in the event ledger with a paired reversal entry.
Void
Cancels the invoice without deleting the record. Voided invoices retain their full structure and customer-facing document but no longer count toward outstanding receivables. Used to retract an invoice issued in error before it has been paid. Voided invoices cannot be re-sent or marked paid; correcting the underlying billing requires creating a new invoice.
Send reminder
Sends a reminder email referencing an unpaid or overdue invoice. The reminder uses a configurable template distinct from the original send. Reminders are tracked in the event ledger so operators can see how many touches have been made.
Soft delete
Marks the record void-archived without removing it from the database. Soft-deleted invoices disappear from the default list view but remain queryable via the archive filter and continue to back reporting queries. Available only for invoices in draft or void status; sent or paid invoices must be voided first.
Data model
An invoice record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.
| Field | Type | Notes |
|---|---|---|
id | integer | Primary key. Stable across edits. |
invoice_number | string | Customer-facing identifier. Configurable prefix. |
customer_id | integer | References the customer record. Nullable for guest invoices. |
customer_snapshot | object | Frozen contact and billing-address block at invoice time. |
order_id | integer | Optional. Set when invoice was generated from an order. |
line_items | array | Each item — description, qty, unit_price, line_total, tax_rate, tax_total. |
currency | string | ISO 4217 code. Set at create, immutable. |
subtotal | decimal | Sum of line totals before tax. |
tax_total | decimal | Sum of per-line tax totals. |
discount_total | decimal | From the applied discount, if any. |
grand_total | decimal | Final amount due. |
paid_total | decimal | Running sum of recorded payments. |
balance_due | decimal | Computed as grand_total - paid_total. |
status | enum | draft, sent, partially-paid, paid, overdue, void, or void-archived. |
issued_at | timestamp | Set when the invoice leaves draft. |
due_at | timestamp | Required at create. Drives overdue status. |
paid_at | timestamp | Set when status reaches paid. |
payment_events | array | Append-only ledger — payments, refunds, reversals. |
delivery_events | array | Append-only ledger — original send + reminders. |
status_history | array | Append-only ledger — every transition with operator id. |
created_at | timestamp | Set on create, immutable. |
updated_at | timestamp | Touched on any edit. |
order_id is optional. When present, the invoice references the source order; the order's totals do not auto-sync with the invoice (the invoice can be edited independently). When absent, the invoice is a standalone billing document.Status semantics: draft allows full editing; sent locks structural fields; partially-paid and paid track payment progress; overdue is computed from due_at and the current paid total; void is a terminal-but-visible state; void-archived is the soft-deleted state.
Tax breakdown: tax is computed per line at the line's effective tax rate. The aggregate tax_total is the sum of per-line tax totals, not a recomputation against the subtotal. This matters for split-tax invoices (mixed taxable / non-taxable items) and for jurisdictions with multiple stacked tax rates.
INVOICE RECORD├── id integer primary key├── invoice_number string customer-facing, configurable prefix├── customer_id integer nullable for guest invoices├── customer_snapshot object frozen contact + billing address├── order_id integer optional link to source order├── line_items array per-line desc, qty, unit, line_total, tax├── totals decimal × 6 subtotal/tax/discount/grand/paid/balance├── status enum draft → sent → paid (with void + overdue)├── timestamps issued_at, due_at, paid_at, created_at, updated_at├── payment_events append-only payments, refunds, reversals├── delivery_events append-only original send + reminders└── status_history append-only every transition + operator id↓ links to (optional)ORDER RECORD (see Orders — Reference)invoice can be standalone OR order-derivedPermissions
Access to the Invoices surface is gated at two layers.
Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Invoices surface.
Layer 2 — per-action capability. Within SG-Admin, each Invoices action checks a capability associated with the calling operator's role. The default role configuration ships with three billing-adjacent roles — Billing Manager, Accounts Receivable, Read-only Auditor — layered on top of the platform's base roles. The capability map is:
| Capability | Administrator | Billing Manager | A/R | Auditor |
|---|---|---|---|---|
| List invoices | ✔ | ✔ | ✔ | ✔ |
| View detail | ✔ | ✔ | ✔ | ✔ |
| Create manual invoice | ✔ | ✔ | — | — |
| Generate from order | ✔ | ✔ | ✔ | — |
| Edit invoice (draft) | ✔ | ✔ | — | — |
| Edit notes (sent / paid) | ✔ | ✔ | ✔ | — |
| Send to customer | ✔ | ✔ | ✔ | — |
| Mark paid | ✔ | ✔ | ✔ | — |
| Mark unpaid | ✔ | ✔ | — | — |
| Void | ✔ | ✔ | — | — |
| Send reminder | ✔ | ✔ | ✔ | — |
| Soft delete | ✔ | ✔ | — | — |
| Export | ✔ | ✔ | ✔ | ✔ |
Self-protection rules. Paid invoices cannot be edited structurally without first being marked unpaid. Voided invoices cannot be re-sent, marked paid, or edited. Marking paid for an amount exceeding the balance due is rejected. Soft delete is blocked on any invoice in sent, partially-paid, or paid status; the surface returns a structured rejection naming the rule that fired.
Audit. Every write — create, edit, send, mark paid, mark unpaid, void, send reminder, soft delete — emits an Activity Log entry and an entry to the invoice's own append-only status history. The log records the acting operator, the target invoice, and the change shape (field-level diff for edits, amount and method for payments). Activity Log retention is governed by the site's general settings.
REQUEST│▼┌───────────────────────────┐│ Admin gate │ unauth → reject└─────────────┬─────────────┘│ authed▼┌───────────────────────────┐│ Capability check │ role lacks cap → reject│ (per-action, per-role) │└─────────────┬─────────────┘│ allowed▼┌───────────────────────────┐│ Status + financial guards │ edit-sent → block;│ │ overpayment → reject└─────────────┬─────────────┘│ passes▼action executes│▼Append-only ledgers updatedActivity Log entry writtenRelated references
- Orders — Reference. The transactional surface that invoices can be generated from. An order can produce many invoices (partial billing); an invoice can stand alone with no order reference.
- Refunds — Reference. Refunds against paid invoices are recorded in the invoice's payment-event ledger and update the paid total downward.
- Users — Reference. Customer records — invoice
customer_idreferences this surface. Re-attribution rules apply on permanent customer delete. - Settings — Reference. Owns the invoice number prefix, the default due-date interval, the invoice template selection, the tax rules, and the reminder schedule defaults.
- Custom Codes — Reference. The invoice document template — visual layout, fields rendered, branding — is themed through the template surfaces.
- Forms — Reference. Some checkout flows produce invoices instead of (or alongside) orders, depending on the payment flow configured on the form.
/docs/invoices.