tomatophp/filament-pos
A complete point-of-sale system for FilamentPHP: manage products, orders, payments, and receipts through a fast, intuitive interface. Supports barcode scanning, multiple payment methods, and printable invoices—ready to drop into any Laravel admin panel.
Architecture fit. This is not a standalone POS application — it is a Filament panel plugin that layers a cashier/checkout surface on top of tomatophp/filament-ecommerce (Ecommerce Builder). That is a clean fit only if Ecommerce Builder is already your system of record for products, prices, and orders; the POS then becomes one more panel reading an existing catalog. If it is not, "install the POS" actually means "adopt a two-package commerce schema," which is a platform decision, not a feature decision. A TPM should reframe the question accordingly: the real commitment is the commerce data model, not the register UI.
Integration feasibility. Mechanical effort is low (composer require, publish config, migrate, register the plugin on a panel). Effort certainty is low. Feasibility hinges on four facts that must be established from source, not from the README: (1) do POS sales write into ecommerce_orders or into their own pos_* tables — this single fact determines exit strategy and reporting design; (2) is the payment story "record a tender type" or actual card processing (assume the former); (3) does the plugin wire into Filament tenancy primitives or require a parallel scoping scheme; (4) do receipts, barcodes, and cash drawers work on real target hardware. Timebox a two-week spike with written exit criteria rather than letting scope drift into production by default.
Technical risk. Ranked:
Key questions for the spike to answer. Which tables does a completed sale touch? What is the transaction and locking story at checkout? Are refunds, discounts, tax lines, and cash management implemented or advertised? Are roles/permissions seeded or left to us? Does it support multi-location via Filament tenancy? What is the commit cadence, CI matrix, and open-issue responsiveness? Who owns security triage for a dependency with no downstream users?
Stack fit. Hard prerequisites: Laravel 10/11, PHP 8.2+, Filament v3+, and Ecommerce Builder installed and working. Strong fit for a Laravel/Filament back office wanting an admin-native register; poor fit for headless/API-first POS, non-Filament stacks, or high-volume multi-terminal retail.
Migration path. Phase 0: branch spike with the trio pinned to exact versions, one register, one cashier, a small real catalog, an end-to-end sale through tender and receipt, plus hardware proof. Phase 1: pop-up, event, showroom, or internal staff store — genuinely the right scope for this package. Phase 2: limited production behind an explicit decision gate (adopt / fork-and-own / build on Filament internally / stop). Keep the register layer replaceable throughout.
Compatibility. Give the register its own panel (id('pos'), path('pos')) rather than sharing the admin panel — separate nav, kiosk layout, narrower permissions, and no accidental exposure of back-office resources. Verify namespace and plugin class from src/ before pasting examples; TomatoPHP moves classes between majors and there is no blog/Stack Overflow corpus to fall back on. Budget for rewriting the receipt Blade template — layout, tax lines, register/cashier identifiers, legal footer — as it is the most reliably custom part of any POS.
Sequencing.
database/migrations/ first — data ownership decision gates everything downstream.RouteNotFoundException, duplicate nav entries).TenderRecorder, atomic stock decrement) so a real PSP and safe concurrency can be dropped in later.Maintenance. You will own: the receipt template, the permissions model, the upgrade lockstep across three packages, security triage for a dependency with no downstream users, and any fork you create. Plan for one engineer at fractional capacity post-pilot plus a defined upgrade cadence (all three packages in one PR, on a branch, with a hand-performed sale afterwards). Keep vendor edits at zero so a fork stays a day of work rather than a quarter.
Support. There is no vendor SLA and no community depth to lean on — you are first responder. Build an internal runbook for cashier-facing failures, and train support to check storage/logs/laravel.log first: Filament frequently swallows the real exception behind a toast, and the stack trace is what tells you whether the fault lies in the package, Ecommerce Builder, or your policy layer. Decide now who is on call during trading hours and what the fallback is (paper log, order entry only).
Scaling. Fits one to a handful of registers: an internal store, a pop-up, a showroom. Each cart interaction is a server round trip, so latency is bounded by network quality at the counter — test on site, on the actual tablet. Multi-register is constrained by stock concurrency correctness; multi-location requires verified Filament tenancy support, and a parallel store_id scheme should be treated as a red flag (two authorization models). This is not a platform bet for high-volume, multi-location, offline-first, or audited payment/tax environments.
Failure modes and mitigations.
lockForUpdate at your adapter, load-tested with two terminals.Ramp-up. Cashier training is light — Filament UI, RTL and multi-language support included — but engineering ramp-up is heavier than the composer install implies because there is no documentation corpus; expect source reading. Fund a two-week spike, then a pilot with named owners for hardware, permissions, and reconciliation. Finance needs an explicit note that tender recording is not settlement: reconciling the register against the bank is a separate process you will build.
How can I help you explore Laravel packages today?