Invoice PDFs
Every order in Distribu can be downloaded as a PDF invoice — US Letter size, single page, generated on demand. No setup, no third-party invoicing tool, nothing to configure. If you've placed an order, you can grab its invoice.
Getting an invoice
From the dashboard
On any order detail page (/dashboard/orders/{id}), click the Download
Invoice button in the top-right. You'll get a file named:
invoice-A1B2C3D4.pdf
…where A1B2C3D4 is the last 8 characters of the order's ID, uppercased —
matching the short ID shown in the UI.
Direct URL: /dashboard/orders/{id}/invoice. It's a GET endpoint — safe
to bookmark, share with staff, or paste into a PDF viewer.
From the storefront
Customers can download their own invoices at
/store/{slug}/orders/{id}/invoice. The order detail page on the
storefront has a matching button. Invoice access is gated to the logged-in
customer — the endpoint returns 404 if the order doesn't belong to them.
Via the REST API
There's no REST API endpoint for the invoice PDF right now. If you need programmatic access, hit the dashboard endpoint with a session cookie — the auth is standard staff auth.
What's on the invoice
The layout is deliberately compact and readable — nothing fancy, just the information you (and your customer) need:
┌────────────────────────────────────────────────────────────────────┐
│ Your Company INVOICE │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ BILL TO Invoice # INV-A1B2C3D4 │
│ Acme Restaurant Date April 16, 2026 │
│ billing@acme.com PO # PO-12345 │
│ │
│ SHIP TO │
│ 123 Main Street │
│ Brooklyn, NY 11201 │
│ United States │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Product SKU Unit Price Qty Subtotal │ │
│ ├──────────────────────────────────────────────────────────────┤ │
│ │ Widget Blue WDG-001 $8.50/each 10 $85.00 │ │
│ │ Widget Red WDG-002 $9.25/each 5 $46.25 │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ TOTAL $131.25 │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ Notes │
│ Deliver before noon on Thursday. │
│ │
│ Generated by Distribu · Order clxx... │
└────────────────────────────────────────────────────────────────────┘
Header
- Your company name — pulled from
Company.name, what you set in Settings → Company. - "INVOICE" label in blue.
- A thin accent bar in the brand blue.
Meta (right side)
- Invoice # — format
INV-{last 8 chars of order id, uppercase}. Same thing as the filename suffix. Stable — an order's invoice number doesn't change over time. - Date — the order's creation date, formatted like "April 16, 2026".
- PO # — only shown if the order has a
poNumber. Otherwise omitted.
Bill to
Pulled from the linked customer row:
- Customer name (falls back to email if no name is set).
- Customer email underneath, in gray.
Dashboard-created orders (which have no customerId) don't show a Bill
To block — that section is simply omitted.
Ship to
Pulled from the frozen snapshot on the order, not the live address. This is intentional: if a customer later edits their address or deletes it, the invoice still reflects where the order was actually shipped.
Storefront orders always have a shipping address — the cart requires picking one. Dashboard and API orders may or may not have one; the Ship To section is omitted if the order has no snapshot.
Line items table
One row per line item with:
- Product name — truncated with
...if it doesn't fit. - SKU — or
—if the product has no SKU. - Unit price — formatted
$X.XX/unit(e.g.$8.50/each). - Quantity.
- Subtotal —
unitPrice × quantity, right-aligned.
Alternating rows have a light background for readability.
If an order has more line items than fit on one page (roughly 20+ depending on product name length), the overflow rows are dropped — the PDF is single-page today, no multi-page pagination. For orders that large, grab the data via the REST API instead.
Total row
A blue band at the bottom of the items table with TOTAL label and the order total, bold white text.
Notes
If the order has a notes field, it's rendered below the total, word-wrapped
to fit the page. Up to 6 lines — anything beyond that is dropped.
Footer
A small gray line at the bottom with Generated by Distribu · Order {full id}.
What's NOT on the invoice
- Tax — Distribu doesn't calculate tax. If you need tax lines, they
have to live in the
notesfield today or be handled in your accounting system. - Shipping — no separate shipping line. Same workaround via
notes. - Payment terms — same (
Net 30,Due on receipt, etc.). Add them to the notes field on the order, or put them in your customer's account notes. - Your address or contact info — the invoice shows your company name but not a physical address, phone, or logo. A richer letterhead is on the roadmap; if you need to emboss something, most PDF viewers let you overlay or export to an external template.
- Payment status — invoices show the order total as a single line. There's no "Balance due" / "Paid" concept in Distribu right now.
Caching
The invoice endpoint returns Cache-Control: no-store. Every download
regenerates fresh, which means:
- Always the latest data. If you update an order's notes or PO number (via the API), the next PDF download reflects it.
- No stale invoices. Some PDF viewers cache aggressively — if you're surprised by an out-of-date invoice, clear your browser/viewer cache or append a cache-buster query param.
Audit
Downloading an invoice does not write an audit log entry right now. If you need to see who downloaded what and when, email us — we can pull it from our server access logs.
Next: Exporting orders.
