AstroBaaS

Catalogue & product data

Brand-Customized Invoices

Paid pluginsize Splanned, not built

Indicative price, not an offer: EUR 100-200/year or EUR 250 one-off

Generated from docs/plan/paid/brand-customized-invoices/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

A paid document customization feature for merchants who want branded invoices matching their visual identity and including compliance fields (tax ID, custom terms, custom line item descriptions). Uses HTML template engine to let merchants design invoices without code, then generates PDFs on-demand or at order fulfillment time.

The problem

Our invoices are generic and don’t match our brand. We need to add custom compliance fields (tax ID, customs reference), custom terms, and custom product descriptions for B2B orders. Generating PDF invoices manually is error-prone; we need automatic generation that respects our template.

What it does

  • Invoice template builder: HTML + variable placeholders ({{order.id}}, {{customer.name}}, {{items.product_name}})
  • Pre-built templates: professional invoice layouts (minimalist, corporate, creative) ready to customize
  • Template variables: order ID, date, customer name/address, items (name, qty, price, tax), totals, shop details
  • Custom fields: add merchant-specific fields (tax ID, PO number, custom terms, shipping method, payment terms)
  • PDF generation: templates render as PDF on-demand or automatically on order fulfillment
  • Multi-language invoices: if order is in DE, invoice prints in German (if templates exist per language)
  • Invoice delivery: email invoices to customer when order ships (or on-demand download link)
  • Invoice archive: all generated invoices stored and downloadable from order detail
  • Branding elements: upload custom logo, set colors, set footer text (copyright, contact, website)
  • Compliance: support VAT reverse-charge fields, duty/tax breakdown, payment method, shipping address

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • Packing slips or shipping labels — those are fulfillment documents, a separate feature.
  • Multi-currency invoices — invoices are in order currency; currency conversion is payment module.
  • Invoice numbering sequences (Invoice #1001, #1002, etc.) — core provides order ID only; custom sequencing is optional add-on.
  • Accounts receivable or invoice payment reminders — that is B2B payments, separate paid module.
  • E-invoicing compliance (ZUGFeRD, Peppol, Factur-X formats) — compliance invoicing is regulated, separate paid module.
  • Batch invoice generation for past orders — one-off exports only; automated batch is optional.

Data model

New INVOICE_TEMPLATE table (template_id, merchant_id, name, html_template, variables JSON, logo_url, colors JSON, created_at). New INVOICE_GENERATED table (invoice_id, order_id, generated_at, pdf_file_url, template_version). Migration required: none (new tables).

API

  • POST /admin/invoices/templates (create invoice template with HTML + variables)
  • GET /admin/invoices/templates (list templates)
  • PATCH /admin/invoices/templates/:id (update template)
  • POST /admin/invoices/templates/:id/preview (render template for sample order, return PDF preview)
  • POST /admin/orders/:orderId/invoices/generate (generate invoice PDF for order)
  • GET /admin/orders/:orderId/invoices (list all invoices for order)

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

Invoice Templates page with template editor (HTML WYSIWYG or raw HTML). Logo uploader, color picker. Template variables helper (copy-paste {{order.id}} etc.). Preview button shows rendered invoice for sample order. Orders page: invoices section with list of generated PDFs, download links, regenerate button.

The seam — why this is paid

Paid invoice module owns template editor, PDF generation, and storage. Core provides order data (order ID, customer, items, totals) via API. Paid module consumes order API and renders PDFs. No seam distinction needed; entire feature is paid.

Paid professional feature beyond basic invoicing. Merchants choose to customize documents for brand and tax compliance.

Dependencies

  • Order management (core, existing)
  • PDF rendering library (assumed to exist or be integrated)
  • Email system (core, for invoice delivery)

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • Invoice template ‘Corporate’ created with HTML template containing {{order.id}}, {{customer.name}}, {{items}}, {{order.total}}
  • Template logo uploaded; colors set to brand primary/secondary. Template preview shows rendered PDF with logo and colors.
  • Custom field ‘tax_id’ added to template; value set to merchant tax ID in admin; invoice includes tax ID on render.
  • Invoice generated for order #12345; PDF created and stored; download link appears in order detail
  • Invoice emailed to customer when order ships; email contains PDF attachment or download link
  • Multi-language: invoice for DE order generated using German template (if it exists); includes German terms
  • Regenerate button: if template is updated, old invoice can be regenerated with new template on-demand

Risks

If HTML template is user-editable without sandboxing, XSS or script injection is possible (malicious template renders in PDF viewer). Mitigate: validate HTML, use safe templating engine (no script tags allowed), render PDF server-side only. If invoice URLs are publicly accessible without auth, invoice PDF enumeration is possible (attacker guesses invoice IDs). Mitigate: require merchant auth to access invoices, or use signed URLs with expiry. If PDF generation is slow, order fulfillment is blocked. Mitigate: generate PDFs async in background, notify merchant when ready.

Commercial context

Suggested priceEUR 100-200/year or EUR 250 one-off
Rival anchorFooman PDF Customiser

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.