lara-zeus/pontus
Lara Zeus Pontus is a Laravel/PHP package that adds a focused, configurable feature set to Laravel applications. It follows framework conventions, installs cleanly, and integrates with the broader Lara Zeus ecosystem for maintainable, extensible projects.
Pontus is a Lara Zeus / Filament plugin for back-office CRUD over plans, subscriptions, invoices, and feature flags. Read that sentence carefully before you type composer require: it is an admin surface, not a billing engine. The day-to-day value is "support can look up a customer's plan and invoice status without a SQL console" — not "money moves correctly."
Before installing, spend 30 minutes reading the repo, not the docs. The published description is generic Zeus-ecosystem boilerplate ("publishable assets… Blade-ready views…") and tells you nothing about the actual data model. Open these in order:
composer.json — the exact Laravel / Filament / PHP constraints. v2.0.1 targets Filament 4; that is your hard gate.src/ — measure the surface area. A few thousand lines means fork-and-own is credible; something large means archiving is disqualifying.database/migrations/ — this is the real documentation. Enumerate every table, every foreign key into users, and whether anything is tenant-scoped.config/pontus.php — what is actually configurable vs. hardcoded.stripe, cashier, paddle, invoice->pay, charge — this answers the only architectural question that matters: does it own subscription state, or is it a UI over rows someone else produced?Install (pin exactly, never float):
composer require lara-zeus/pontus:2.0.1
php artisan vendor:publish --provider="LaraZeus\Pontus\PontusServiceProvider"
php artisan migrate
Publish-tag names follow the pontus-* convention (pontus-config, pontus-migrations, pontus-translations); confirm the exact strings from the publishes() calls in the service provider rather than guessing, since you will be maintaining this yourself.
Register the plugin on a panel in app/Providers/Filament/AdminPanelProvider.php:
use LaraZeus\Pontus\PontusPlugin;
->plugin(PontusPlugin::make())
Your first use case should be a throwaway project, not your app. Spin up a fresh Filament 4 panel matching production's PHP/Laravel minors, install, migrate, and click through every advertised feature. Record the composer.lock delta and any published-view drift. This is a one-day spike whose entire output is a go/no-go memo — "it resolves in Composer" and "it works on Filament 4" are different claims, and 2.0.1 is a one-line version-constraint bump with no test evidence behind it.
If the spike passes, the first thing to build is read-only: a subscription lookup page for support. Ship that before you let anyone write to these tables from a UI.
Treat Pontus as a projection, not a source of truth. The pattern that survives contact with production is: your payment provider (Stripe Billing, Paddle, Lemon Squeezy) owns money and subscription state; a webhook handler writes the resulting plan/subscription/invoice rows into Pontus's tables; Filament gives you free CRUD over that projection. This keeps the archived package on the read path, where its lack of maintenance is survivable, and keeps reconciliation logic in code you own.
// app/Listeners/SyncSubscriptionFromStripe.php
public function handle(WebhookReceived $event): void
{
$subscription = PontusSubscription::updateOrCreate(
['provider_id' => $event->payload['id']],
[
'user_id' => $this->resolveUserId($event->payload),
'plan_id' => $this->resolvePlan($event->payload['plan']),
'status' => $event->payload['status'],
'ends_at' => $event->payload['current_period_end'] ?? null,
],
);
}
Put your own abstraction in front of entitlement checks on day one. Never let $user->hasFeature('x') spread through the codebase. Wrap it:
// app/Support/Features.php
final class Features
{
public function allows(User $user, string $feature): bool
{
// pontus lookup today; swap the implementation later without touching callers
return once(fn () => $user->subscription?->plan
?->features()->where('key', $feature)->exists() ?? false);
}
}
This is the single highest-leverage decision in the whole adoption. It converts "we forked an archived package" from an architectural commitment into an implementation detail, and it means the eventual reimplementation is a swap of one class rather than an archaeology project.
Extend Filament resources rather than editing vendor. Pontus ships resources; if you need a column or a filter, register your own resource in your panel namespace and point it at the same models, or subclass. Keeping overrides outside vendor/ (or outside your vendored copy) is what makes the exit path cheap.
Seed plans from config, not from the admin UI, in non-production. Plan definitions are pricing decisions and belong in version control as a seeder so staging environments are reproducible. Reserve the admin CRUD for editing subscriptions and reading invoices.
Scope the panel. If Pontus's resources register on your main admin panel, every Filament user sees billing data. Guard with canAccess() on the resources or register the plugin on a dedicated BillingPanelProvider with a narrower policy. With no upstream to patch a leak, this is on you.
Test the entitlement path, not the CRUD. Filament resources are self-testing in practice — you will notice if a table breaks. Silent entitlement bugs are the ones that cost you money. A Pest test that asserts "plan A allows feature X, expired subscription does not, downgrade revokes within the period" is worth more than full coverage of the resources.
This package is archived. Adjust every instinct accordingly. There is no v3, no Filament 5 path, no security response, no one to file an issue with. The only two adoptions that survive scrutiny are fork it into your monorepo with a named internal owner or harvest the schema as a design input and reimplement. Plain composer require and move on produces a production dependency with no maintainer — the worst of both worlds.
"Resolves" ≠ "works" on Filament 4. The 2.0.1 changelog is literally update versions for filament 4. Filament 4 restructured schemas, actions, and panel APIs; a passing composer install proves only that the version constraint is satisfied. If your spike shows broken forms, that is expected, not surprising — and it is precisely why the spike is one day and not one sprint.
Do not adopt from Filament 3. It bundles a Filament major upgrade into a billing decision. Two unrelated risks in one changeset is how a two-week task becomes a quarter.
Never let this touch money movement. Checkout, proration, dunning, tax, and customer-facing invoices stay with the provider. Billing bugs are financial and reputational; you cannot absorb that risk on a 4-star, zero-dependent, single-maintainer package. If someone proposes storing a card token or computing tax here, that is the moment to stop.
Enumerate what you now own, in writing. After the spike, list every table created, every view and config published, and every Filament resource registered. Add it to your dependency register flagged unmaintained so the next Filament upgrade surfaces it as a known follow-up rather than a mystery failure at 5pm on a Friday.
Debugging the panel, when nothing renders:
php artisan about and php artisan filament:about — confirm the panel and plugin actually loaded.php artisan optimize:clear — config/route/view caches are the usual culprit after publishing.bootstrap/providers.php / config/app.php for the service provider and the panel provider for ->plugin(...).php artisan vendor:publish --list (or dump the provider's publishes()) to get exact tags — don't trust memorized Zeus conventions.php artisan migrate --pretend shows exactly what will run before it runs.Extension points are the whole safety net. Published config, published views, and subclassable Filament resources mean you can customize without patching vendor. Deliberately constrain yourself to those seams — the moment you edit vendor/lara-zeus/pontus/src/... directly, your fork becomes archaeology and the cheap exit path disappears.
Write the exit path down while you still remember it. For a package this scope, reimplementing the admin resources directly in Filament is bounded work — a week, not a quarter, if your entitlement checks go through one class and your overrides live in your own namespace. The assessment should name the trigger ("next Filament major" or "first correctness bug in entitlements") and the owner, and then the archived status stops being a latent risk and becomes a scheduled task.
How can I help you explore Laravel packages today?