A standalone page at /invoice/{portal_token}. It renders the builder's logo and business details, a Bill To block, line items with quantity, rate and amount, totals with tax, payments received, payment instructions and terms. It always renders in light mode because it is a document. It is deliberately a separate implementation from the admin viewer so the print output is identical wherever it is opened.
Also called: invoice link · online invoice · send an invoice the customer can open
The invoice has its own link, and nothing stands in front of it
A branded document at its own token URL: your logo and business details, a Bill To block, line items with quantity, rate and amount, totals with tax, payments received, payment instructions and terms. The customer can reopen it any time instead of hunting for an attachment in a six-month-old email. Status is computed rather than trusted, so an invoice past its due date says overdue on the customer's screen too.
They can pay it from the document they already have open
A Pay button opens hosted checkout for the balance and confirms server-side on return, then re-polls so the status and balance catch up without a refresh. The button does not render at all when you have no payment provider connected, so it can never fail in front of a customer. Deposits and draws get paid while the invoice is open, rather than after a cheque and a week in the post.
The Bill To comes from the intake they legally signed
Legal name, mailing address, email and phone from the customer's own signed form, plus a co-signer line and a lender line with the loan number where those apply, rather than whatever name happens to be sitting in the CRM. City, state and ZIP are joined the way an address is actually written — the sort of detail a customer notices on a bill and a lender notices on a draw request.
Outstanding invoices lead; paid ones fold away but stay reachable
The dashboard's invoices card heads with the outstanding total, or All paid in full, sorts unpaid oldest-due first, and folds settled invoices behind a toggle that names how many are back there. On a job billed six times, five settled invoices used to bury the one bill that needed paying. Folded never means gone: a paid invoice is the customer's receipt and they come back for it at tax time. Drafts are excluded on the server, so nothing half-written is ever visible.
Opening a document does not cost them their place
Invoices, agreements and change orders open in a modal over the dashboard with their own page chrome suppressed — backdrop click and Escape close it, print stays available. Download PDF prints the document and not the buttons, and the same layout renders identically on screen, inside the modal and on paper.
- 1The portal token in the URL is the authorisation; no session is involved
- 2GET /api/client-portal/invoice returns the invoice, line items, payments, branding and whether payments are enabled
- 3Status is computed rather than trusted, so an overdue invoice reads overdue
- 4Browser print is the PDF mechanism; print styles hide the action bar
- 5?embed=1 renders it inside the dashboard modal, ?print=1 auto-fires the print dialog
An invoice a customer opens from their dashboard has to be the same document the builder sees in the office, or the two parties end up arguing over different pieces of paper. The customer's copy renders the identical layout without depending on anything that only exists behind a login. It is locked to a light theme whatever the customer's device is set to, because an invoice is a document that gets printed and filed, not a screen.
- Invoices trapped in email attachments
- Two invoice renderers producing different documents
- Dark mode rendering a document meant to be printed
See it on your own jobs
Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.
or keep browsing features →