Check your stack first v5 requires Filament v5, Laravel 12/13, and PHP 8.2+. If you're still on Filament v4, pin the previous major instead of upgrading:
composer require tomatophp/filament-invoices:"^4.0"
Otherwise, on Filament v5:
composer require tomatophp/filament-invoices:"^5.0"
Publish assets and config
php artisan vendor:publish --provider="TomatoPHP\FilamentInvoices\FilamentInvoicesServiceProvider" --tag="filament-invoices-config"
php artisan vendor:publish --provider="TomatoPHP\FilamentInvoices\FilamentInvoicesServiceProvider" --tag="filament-invoices-assets"
Run migrations
php artisan migrate
Register the plugin in app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\TomatoPHP\FilamentInvoices\FilamentInvoicesPlugin::make(),
]);
}
First use case
config/filament-invoices.php — defaults, templates, settings, mail.resources/views/vendor/filament-invoices/ — the published Blade views you'll override.\TomatoPHP\FilamentInvoices\Facades\FilamentInvoices — programmatic creation.InvoiceStatsWidget and friends).use TomatoPHP\FilamentInvoices\Facades\FilamentInvoices;
$invoice = FilamentInvoices::create([
'client_id' => $customer->id,
'currency' => 'USD',
'items' => [
['name' => 'Product A', 'quantity' => 2, 'unit_price' => 10.00],
],
'template' => 'modern',
]);
// app/Models/Order.php
public function invoice()
{
return $this->morphOne(Invoice::class, 'invoiceable');
}
$order->invoice()->create([...]);
Since v5 the invoice page no longer assumes the billed model exposes a locations() relation, so attaching to plain models (orders, subscriptions, projects) works without stubbing relationship methods.
$invoice->payments()->create([
'amount' => 50.00,
'method' => 'credit_card',
'status' => 'completed',
]);
Invoices created without a currency can now accept payments instead of throwing — useful when you generate an invoice before the customer's billing currency is known.
$invoice->sendEmail([
'to' => $client->email,
'subject' => 'Your Invoice #'.$invoice->number,
]);
Invoice settings can be saved with optional fields left blank. Build your own settings forms the same way — don't add required validation on fields the package's settings page treats as optional, or you'll reintroduce the failure v5 fixed.
resources/views/vendor/filament-invoices/templates/.'templates' => [
'custom' => 'filament-invoices::templates.custom',
],
'statuses' => [
'draft' => ['label' => 'Draft', 'color' => 'gray'],
'sent' => ['label' => 'Sent', 'color' => 'blue'],
'paid' => ['label' => 'Paid', 'color' => 'green'],
],
'currency' => [
'default' => 'USD',
'rates' => [
'EUR' => 0.85,
'GBP' => 0.75,
],
],
use TomatoPHP\FilamentInvoices\Widgets\InvoiceStatsWidget;
public function getWidgets(): array
{
return [InvoiceStatsWidget::class];
}
Treat this as a real major upgrade: bump Filament to v5, Laravel to 12/13, and PHP to 8.2 in the same PR. Regenerate published assets and re-publish the config (back up your customizations first), then clear caches. If you're not ready to move the whole panel to Filament v5, stay on the v4 branch rather than mixing versions.
Version mismatch is the number one failure mode
filament-invoices:^5 against Filament v4 will install but blow up at runtime on Filament API changes. Lock both together in composer.json and note the branch policy: Filament v4 → 4.x branch. Also confirm PHP 8.2+ in composer.json and CI; v5 will not run on 8.1.
Republish after upgrading Published views and assets from 4.x are stale on a v5 upgrade. Diff them against the package's views before overwriting your customizations, and re-run the asset publish tag.
Migration conflicts
If you hand-rolled invoices / invoice_items tables, drop them before migrating (and confirm the morph columns invoiceable_type / invoiceable_id exist).
Empty item rows v5 tolerates empty item rows on save. If you build custom item repeaters, don't assume every row is populated — filter empty rows before doing totals math in your own code.
Template overrides and PDFs
Custom templates must extend the base layout (@extends('filament-invoices::layouts.invoice')) or PDF generation breaks.
DomPDF dependency
If PDFs fail, check dompdf/dompdf is present:
composer require dompdf/dompdf
Email attachments Ensure storage is writable and configure the sender:
'email' => [
'from' => '[email protected]',
'pdf_path' => storage_path('app/invoices'),
],
'debug' => env('FILAMENT_INVOICES_DEBUG', false).$pdf = $invoice->generatePdf();
Storage::disk('local')->put('test.pdf', $pdf);
php artisan config:clear && php artisan view:clear.locations(), so remaining failures are usually a missing record or a soft-deleted parent.Custom invoice model
use TomatoPHP\FilamentInvoices\Models\Invoice as BaseInvoice;
class Invoice extends BaseInvoice
{
protected $casts = ['tax_exempt' => 'boolean'];
}
Events for pre/post actions
InvoiceCreated::listen(fn ($invoice) => /* notify admin */);
API endpoints — expose invoice data with your own controller/routes and policies.
Localization — override labels in resources/lang/en/filament-invoices.php.
How can I help you explore Laravel packages today?