Skip to content

PDF Invoices and Packing Slips

What it does

Generates a real PDF invoice and (optionally) a packing slip for every WooCommerce order. Customers download from the My Account → Orders list, the single-order detail page, or a button injected into the order confirmation email. Admins get a dedicated PDF column on the orders list (HPOS and legacy), a per-order metabox for invoice number overrides and per-order notes, and bulk-print actions that combine many orders into one multi-page PDF with page breaks between them. PDFs can also be auto-attached to the Completed, Processing, Manual Invoice, and Refunded customer emails as real .pdf attachments.

Numbering is sequential and gap-free using an atomic SQL counter (race-condition safe), with prefix and zero-padding controls. If the Sequential Order Numbers module is active, invoice numbers stay aligned with the order number. Rendering is handled by Dompdf via Asteris\Core\PDF_Generator; if Dompdf is unavailable, the module falls back to a printable HTML page so the feature degrades gracefully. This module replaces WP Overnight PDF Invoices Premium ($79/yr) and WooCommerce PDF Invoices by Skyverge ($79/yr).

Quick start

  1. Activate the PDF Invoices and Packing Slips module from Asteris → Dashboard.
  2. Go to Asteris → PDF Invoices and pick one of the five designs (Modern, Classic, Minimal, Branded, Compact).
  3. Fill in Company details (name, address, Tax ID / ABN / VAT, email, phone, website) and upload your Logo.
  4. Set your Number prefix (e.g. INV-), Starting number (default 1001), and Number padding (default 4).
  5. Under PDF email attachments, tick the WooCommerce emails you want the PDF auto-attached to. The Completed email is on by default.
  6. Save settings, then open any order in WooCommerce and click View Invoice in the order data box, or click the PDF icon on the orders list.

Settings reference

All options are stored under the prefix asteris_pdf_invoices_* (one update_option per field, BOM-free admin-post.php save handler — not Settings API).

SettingWhat it doesDefaultValid values
templateDesign used for invoice and packing slip outputmodernmodern, classic, minimal, branded, compact
doc_title_invoiceHeader title on invoice documentsTax InvoiceAny string
doc_title_packingHeader title on packing slip documentsPacking SlipAny string
company_nameCompany name printed in the headerSite nameAny string
company_addressMulti-line address blockEmptyMulti-line string
company_tax_idABN / VAT / Tax ID lineEmptyAny string
company_emailContact email shown on the documentadmin_emailValid email
company_phoneContact phone numberEmptyAny string
company_websiteURL shown on the documenthome_url()Valid URL
logo_idWP attachment ID of the logo (embedded as base64 data URI for reliable Dompdf rendering)0Positive integer
accent_colorHex colour for headings, totals, and the customer email button#1a3a6cHex colour
footer_textFooter line on every invoiceThank you for your order!Multi-line string
show_packingShow the Packing Slip button on admin order screens10 / 1
packing_show_notesInclude customer notes on the packing slip10 / 1
invoice_prefixPrefix before the invoice numberINV-Any string
invoice_start_numberFirst sequential invoice number1001Positive integer
invoice_paddingZero-pad width of the number portion (40001)40-10
date_formatPHP date format for dates on the document. Empty = WordPress site defaultEmptyAny date() format
show_generated_onShow the “Generated on” timestamp in the footer10 / 1
attach_completedAttach PDF to Customer Completed Order email10 / 1
attach_processingAttach PDF to Customer Processing Order email00 / 1
attach_invoice_mailAttach PDF to Customer Invoice email10 / 1
attach_refundedAttach PDF to Customer Refunded Order email00 / 1

Per-order overrides (set on the order edit screen, stored as order meta):

Meta keyWhat it does
_asteris_invoice_numberLocks a specific number to the order (blank = auto-assign on first generation)
_asteris_invoice_notePer-order note printed bottom-left of the invoice (independent of the global footer)

Common workflows

Issuing a tax invoice for an Australian GST-registered store

  1. Open Asteris → PDF Invoices.
  2. Set Invoice title to Tax Invoice (required wording under ATO rules for GST-registered businesses).
  3. Enter your ABN under Tax ID / ABN / VAT.
  4. Choose the Classic or Modern template — both present totals and GST lines cleanly.
  5. Tick Attach PDF to Order Completed email.
  6. Place a test order, mark it Completed, and confirm the customer receives the PDF attached to their email.

Bulk-printing packing slips for the warehouse

  1. Go to WooCommerce → Orders (works on both HPOS and legacy screens).
  2. Tick the orders you want to ship.
  3. From the Bulk actions dropdown, choose Print packing slips and click Apply.
  4. A new tab opens with a single multi-page PDF — one packing slip per order, page-break-separated.
  5. Print from your browser. The nonce expires after one minute and the URL is one-time use per session.

Overriding the invoice number on a specific order

  1. Open the order in WooCommerce.
  2. In the right-hand sidebar, find the Asteris — Invoice metabox.
  3. Type a number into Override the invoice number. Leave blank to let the auto-counter take over.
  4. Save the order. The override is stored in _asteris_invoice_number and survives regeneration.

Adding a per-order note (e.g. payment terms)

  1. Open the order edit screen.
  2. In the Asteris — Invoice metabox, fill the Invoice note textarea (e.g. Payment due within 14 days).
  3. Save. The note appears in the bottom-left of the rendered invoice, independent of the global footer text.

Customising a template

  1. Copy the desired template from wp-content/plugins/asteris-for-woocommerce/src/Modules/PDF_Invoices/Templates/{template}.php.
  2. Paste it to wp-content/themes/{your-theme}/asteris/pdf-invoices/{template}.php.
  3. Edit freely — the helper.php template loader picks up theme overrides automatically.
  4. Theme overrides survive plugin updates.

Debugging template output

  1. Append &debug=html to any invoice URL (e.g. /?asteris_invoice=ORDER_KEY&type=invoice&debug=html).
  2. The module returns the raw HTML instead of streaming a PDF, including an HTML comment identifying the active template ID.
  3. Use this to inspect CSS rendering issues before Dompdf converts the HTML.

For developers

Stability commitment. Hooks, filters, REST endpoints, and shortcodes documented below follow semver. Breaking changes happen only on major version bumps, with at least one minor version of deprecation notice in advance. Anything not listed here (internal AJAX handlers, settings save handlers, internal plumbing hooks) is implementation detail — those may change without notice.

This module does not yet expose any custom asteris_* filters, actions, shortcodes, or REST endpoints. The integration points below are public-facing but are not extension hooks:

URL pattern

Public render endpoint (hooked on init):

/?asteris_invoice={order_key}&type={invoice|packing-slip}

Authentication is by WooCommerce order key — the same token used in customer order emails. Admin bulk print uses asteris_invoice=multi with keys=KEY1,KEY2,... and a _wpnonce for the asteris_bulk_invoices action; requires manage_woocommerce capability.

Theme template override path

wp-content/themes/{your-theme}/asteris/pdf-invoices/{template}.php

Where {template} is one of modern, classic, minimal, branded, compact. Theme overrides are a committed extension point and survive plugin updates.

Troubleshooting

The URL uses the WooCommerce order key as its security token (wc_get_order_id_by_order_key). If the order has been deleted, the key has been regenerated, or the link was sent before an order key reset, the lookup fails. Resend the order confirmation email from the order edit screen to issue a fresh URL.

PDF is served as HTML instead of a true PDF

The module checks Asteris\Core\PDF_Generator::is_available() before streaming. If Dompdf cannot be loaded (PHP mbstring or gd missing, server memory limit too low for the bundled library), the fallback is an HTML page printed in-browser. Check Tools → Site Health for missing PHP extensions and raise WP_MEMORY_LIMIT to at least 256M.

Logo missing from the rendered PDF

The module embeds the logo as a base64 data URI by reading the attachment file directly with file_get_contents(). If the attachment file has been moved off disk (e.g. offloaded to S3 with no local copy), the embed fails and the module falls back to the attachment URL — which Dompdf may not be able to fetch over HTTPS. Re-upload the logo or keep a local copy.

Bulk print returns “Permission denied” or “Invalid request”

Bulk print requires the manage_woocommerce capability and a valid asteris_bulk_invoices nonce. The transient that carries the multi-print URL expires after MINUTE_IN_SECONDS (60s). If you wait too long between clicking the bulk action and the new tab opening, retrigger the bulk action.

Invoice numbers skip or duplicate

The counter is incremented via an atomic UPDATE … SET option_value = option_value + 1 on wp_options. Skips can happen if you manually edit the asteris_pdf_invoices_next_number option, restore a database backup, or assign a manual override that collides with the auto sequence. Use the per-order Override the invoice number field to repair gaps; the override is locked into _asteris_invoice_number and won’t be recycled.

Known plugin conflicts

  • WP Overnight PDF Invoices, WooCommerce PDF Invoices by Skyverge, and similar — both this module and theirs hook woocommerce_email_attachments. Deactivate the other plugin to avoid duplicate PDF attachments on customer emails.
  • Caching plugins (WP Rocket, W3 Total Cache, LiteSpeed) — the invoice URL is dynamic (?asteris_invoice=...) but contains a query string that some aggressive setups still cache. Add asteris_invoice to the cache exclusion query-string list.
  • Custom Order Numbers plugins (other than Asteris Sequential Order Numbers) — the module reads _asteris_order_number to keep invoice numbering aligned. Third-party order-number plugins store under different meta keys, so the invoice counter will run independently from your order numbers. No data loss, but the two sequences will diverge.
  • Other compatibility conjectural until reported — submit issues at the support forum if you hit a conflict.

What is in Free vs Paid

A reduced lite version ships in Asteris Free. The full module is paid-tier only.

Free (lite):

  • 1 plain template
  • Customer-only download from the order page

Paid (Pro, Agency, Founder Lifetime) adds:

  • All 5 designs (Modern, Classic, Minimal, Branded, Compact)
  • Auto-attach PDFs to WooCommerce customer emails (Completed, Processing, Manual Invoice, Refunded)
  • Branding controls (logo, accent colour, custom footer, per-order notes)
  • Packing slips with optional customer notes
  • Credit notes for refunded orders
  • Bulk admin print (combined multi-page PDF)
  • Sequential, gap-free invoice numbering with prefix and padding
  • WP Overnight migration adapter

Changelog

VersionDateNotes
1.9.72026-06-01Documented in detail. Previous entries in plugin changelog.