PrintModule renders a record for printing: a full-page PDF, or a line tree for a thermal (ESC/POS) receipt printer. Staff screens call it to print orders, invoices, receipts and the like. Getting output to physical hardware is device integrations and the Device Hub.
Routes
/print/templatesJWT/print/:datatype/:id/pdfJWT/print/:datatype/:id/thermalJWT/print/:datatype/:idJWTThe whole controller is @StaffOnly() — it renders any record, so the site's app token is refused (see how a request is authorized).
templates— each printable datatype with itstitleand which templates it has.pdf— returnsapplication/pdfinline, named<datatype>-<id>.pdf.thermal— returns{ datatype, id, width: 32, lines }.POST— body{ format: 'pdf' | 'thermal', width? };pdfis the default, andwidth(thermal characters per line) defaults to 32.
A datatype not in the registry answers 400 not printable; one without the requested format answers 400 too.
What is printable
| Datatype | Title | Thermal | |
|---|---|---|---|
sf_order | Order | yes | yes |
sf_invoice | Invoice | yes | yes |
sf_transaction | Payment | yes | yes |
sf_product | Product | yes | |
event | Event | yes | |
ticket | Support Ticket | yes | |
reservation | Reservation | yes |
Templates ship with the server under resources/print-templates/ — Handlebars HTML for PDFs (rendered by headless Chromium to A4), JSON line trees for thermal. Adding a document means a registry entry plus its template files.
What a template sees
doc— the record'sdataplussk;title;now.company— name, legal name, DBA, EIN, logo, email, phone, website and address, from the org and its business profile.scanUriandqr— a scan link of the formappmint://<datatype>/<sk>and a QR code PNG of it, so a printed page scans back to its record.- For orders and invoices: normalised
items(quantity,name,price,lineTotal,note),subtotal,tax,discount,total,currency,number. For payments:amount,currency,method,status,reference.
Other modules use the same service to render computed documents — ones not backed by a single record — from a template file and their own context.