goldnead/statamic-invoices
A Statamic addon for creating and managing invoices in your control panel. Define invoice data and line items, render branded templates, and keep billing documents alongside your content. A lightweight option for Laravel and Statamic sites needing simple invoicing without an external billing platfor...
delivery.retry.max_attempts, after_minutes, schedule), a terminal failed_final state, and a manual escape hatch (invoices:release). v2.8.0 does not change those mechanics — it changes whose settings they run under.invoices:retry, invoices:recheck-vat-ids, invoices:export and invoices:pending previously read the package's config values (often empty) instead of the values saved on the settings page. They now read the saved settings. Treat the settings UI as a product surface with real blast radius: an admin lowering retry attempts to 1, or editing tax/text settings, now changes scheduled and console behaviour, not just the web UI. Add role restrictions or an audit trail on that page if finance or support can reach it.--brand=<handle|id> scopes a run. If per-brand seller identity, subject lines, file names or tax settings were the reason you were going to build your own command layer, that reason is gone. Budget adoption effort instead.invoices:pending run from console could write invoices with the package's (usually empty) seller rather than the brand's saved seller, and VAT re-checks used the wrong tax settings. In many jurisdictions a VAT invoice missing seller name/address/VAT ID is not a valid invoice — this is a reissue-and-reconcile exercise, not a bug-fix ticket. Plan: identify console-created invoices on multi-brand hosts, re-run invoices:recheck-vat-ids --brand=… per brand, and decide with finance/legal whether affected documents need reissuing.invoices:export output shape. On a multi-brand host without --brand you now get one export per brand; with --output, belege.csv becomes belege_marke-2.csv; CSV to stdout requires --brand. Anything downstream that watches a fixed filename (SFTP drop, BI ingest, a nightly reconciliation job) breaks silently by picking up a stale or wrong file. This is a migration with a cutover date, not a version bump — inventory every consumer of the export filename first.brand_id names no brand are reported with exit code 1. Schedulers and CI that treat exit 0 as "everything is fine" need review: a partially failed multi-brand run can still look actionable only if your alerting reads non-zero correctly. Confirm your monitor fires on non-zero rather than on log text.invoices:held and invoices:brand-check deliberately stay cross-brand, which is what you want: one finance-ops query for failed_final across all brands, not one per brand. Keep the thin monitor on failed_final as the roadmap item; do not fork it per brand.invoices:release now sends under the invoice's own brand, so subject and attachment filename are that brand's saved ones. One data-hygiene decision follows: invoices with brand_id 0 fall back to the default brand — check whether any rows are mis-branded, because they will now be sent under the default brand's identity rather than whatever was configured globally.invoices:export pdf --queue workers see the brand's saved settings. If you had any workaround injecting brand context into queue payloads, delete it — but verify first, since two mechanisms setting brand is worse than one.buyer.name falling back to the email local part is still worth a look if you are B2B or brand-sensitive.Consider it when:
--brand to scope a single run.invoices:retry every five minutes and depends on schedule:run firing every minute. Note that the retry cadence and attempt count it uses now come from the settings page, so scheduler health and settings hygiene are two separate things to monitor.attempts and last_error on invoice_deliveries. Upgrade order still matters — migration first, scheduler verified second, otherwise failed sends stick in sending.Look elsewhere (or plan a wrapper) when:
INVOICES_RETRY_SCHEDULE=false and drive invoices:retry from your own orchestrator — now per brand, which means one orchestrator entry per brand handle.To executives: A correctness release with two halves. First, a fix: on hosts serving more than one brand, background and command-line runs were using generic package settings instead of each brand's saved seller details, tax settings and text — meaning invoices generated from the command line could carry the wrong or an empty seller identity. That is now corrected and each brand runs on its own settings, which matters legally and reputationally for invoicing. Second, multi-brand support: you can now operate several brands from one install without a custom command layer, and exports, subjects and filenames are per brand. Cost is scheduling a remediation pass over already-issued invoices and updating any system that consumes export files — no new infrastructure, no new vendor.
To engineering: v2.8.0 is a behaviour change on multi-brand hosts, not a patch. Console and scheduled commands resolve per-brand settings instead of package config; invoices:pending, invoices:retry, invoices:recheck-vat-ids and invoices:export now iterate brands, with --brand to restrict; a failing brand does not stop the run and the exit code is the first failure. invoices:release sends under the invoice's brand (brand_id 0 → default brand). Jobs queued from these commands carry brand context into the worker. invoices:brand-check and invoices:held remain cross-brand by design. Export output changed: one file per brand under --output with a _<brand> suffix, CSV to stdout requires --brand, unknown brand_id documents are reported and exit 1. Single-brand installs are unaffected in command topology, but still benefit from the settings-resolution fix — verify that, and re-run VAT checks. No migration in this release; the v2.7.0 migration prerequisite still applies. Rollout order: inventory export consumers, audit console-created invoices on multi-brand hosts, deploy, re-run per-brand VAT checks, then flip any filename-dependent automation.
To finance/support ops: Background retries and exports now use the settings saved on the settings page, per brand — so changes made there affect scheduled runs, not just what you see in the browser. On accounts with more than one brand, commands process each brand separately and exports arrive as one file per brand. Permanently failed invoices still appear under invoices:held across all brands in a single view, so your working queue is unchanged. Expect a one-off cleanup: some invoices produced from the command line earlier may carry the wrong or a blank seller, and the finance/legal call on reissuing those is the main open item from this release.
How can I help you explore Laravel packages today?