themsaid/nova-cashier-manager
A Laravel Nova tool for managing Laravel Cashier subscriptions. Browse and administer customers, subscriptions, plans, and billing details from a clean Nova dashboard, simplifying recurring Stripe billing management without leaving your admin panel.
composer show laravel/nova — if you're on Nova 4 or 5, stop here. There is no upgrade path; port the tool's handful of queries into a Nova Resource or Action instead.subscriptions, and subscription_items if you're on Cashier 7+), your billable model (App\User) using Laravel\Cashier\Billable, and valid STRIPE_KEY / STRIPE_SECRET in .env.composer require themsaid/nova-cashier-manager. Expect dependency constraints to drag old Cashier/Nova versions — pin them and confirm with composer why laravel/nova.app/Providers/NovaServiceProvider.php:
public function tools()
{
return [
new \Themsaid\CashierManager\CashierManager,
];
}
Then php artisan nova:publish / view:clear if the menu doesn't show up.subscriptions table, not as source of truth. The tool reads the local DB. The DB is only correct if your Stripe webhook endpoint and Cashier's WebhookController are wired up. Get webhooks healthy first, or the UI will lie to you.public function tools()
{
return auth()->user()?->isAdmin()
? [new \Themsaid\CashierManager\CashierManager]
: [];
}
This is the minimum bar — the default registration exposes cancel/resume to every Nova user who can load the panel.User resource that call $user->subscription('default')->cancel() / ->resume(). You get audit trails, confirmation modals, and queueing for free.price_1H..., add a lookup (config array or a plans table) and surface friendly names.HasMany (Laravel\Nova\Fields\HasMany::make('Subscriptions')) on the billable model so people reach the tool from a customer record instead of hunting through a global list.$user->subscriptions and calls asStripeSubscription() to resync stripe_status / ends_at. The tool can't do this for you, and drift between Stripe and your DB is the #1 source of confusing UI states.canSee/tool registration before it goes near production.stripe_plan → stripe_price and added stripe_status. Any query or display in the tool that assumes the 2018 column names will silently return nulls or throw. Same for subscription_items vs the old single-plan model.App\User-style billable. If you have model_type polymorphism or per-model Stripe accounts (Cashier 12+), you'll need to fork the queries.active(), onGracePeriod() (cancelled but still paid through ends_at), and canceled() (period over). Bugs happen when cancel/resume buttons are shown for the wrong state — check ends_at is in the future before offering "Resume", and be explicit about ends_at timezones (stored UTC, displayed in app timezone).subscriptions.user_id and subscriptions.stripe_id if they're missing; the listing screens are unpaginated-ish and will crawl at scale.php artisan route:list | grep nova-vendor to confirm the tool's endpoints registered; browser Network tab for failing AJAX (usually a 500 from a missing Cashier column); storage/logs/laravel.log for the Stripe-side exception. If the menu entry is missing entirely, it's almost always a cached Nova service provider or a canSee returning false.nova-resource over subscriptions plus two Actions covers 90% of this package's surface area with Nova 4/5 support and no archived dependency. For a new project, do that instead.How can I help you explore Laravel packages today?