Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Bt Cashier Manager Laravel Package

shuyi/nova-bt-cashier-manager

A Laravel Nova tool for managing Cashier billing directly from your admin panel, giving you a convenient interface to review and handle subscriptions, customers, and payment-related records without leaving Nova.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this package as a reference implementation more than a dependency — it targets the Laravel Nova 1.x/2.x era (last release October 2018, 2 stars, 0 dependents) and has not tracked Nova's tool API, Vue 2→3 migration, or Cashier Braintree changes since. Budget time to vendor/fork it rather than expecting a clean composer require.

Minimum viable setup order:

  1. Confirm your stack first. You need Laravel with Nova installed, plus laravel/cashier-braintree already working against your Billable model. If Cashier Braintree isn't configured (API keys, BRAINTREE_* env vars, Billable trait on User), the tool has nothing to read and you'll be debugging two moving parts at once.
  2. Read the package's composer.json before installing. The laravel/nova and laravel/cashier-braintree constraints are your compatibility answer — if it pins nova: ~1.0|~2.0 and you're on Nova 4 or 5, stop and plan a fork.
  3. Install from source, not Packagist, if the constraints block you: clone into packages/ (or nova-components/) and add a path repository in composer.json.
  4. Register the tool in app/Providers/NovaServiceProvider.php inside the tools() array — this is the universal Nova tool entry point:
    public function tools()
    {
        return [
            new \Shuyi\NovaBtCashierManager\NovaBtCashierManager(),
        ];
    }
    
  5. Publish anything publishable. Nova tools from this period usually ship a config/ file and prebuilt assets under dist/:
    php artisan vendor:publish --provider="Shuyi\NovaBtCashierManager\ToolServiceProvider"
    
  6. Where to look first in the source: the ToolServiceProvider (for published config, routes, and asset registration), then the tool's main Vue component — that's where the actual subscription queries and API endpoints live, and it tells you instantly whether this is a "dumb list view" or something with actions.

First real use case: log into /nova, click the tool in the left sidebar, and confirm you see subscriptions with plan names, status, and a cancel affordance. Do this in Braintree sandbox with a handful of seeded subscribers. If the sidebar entry 404s or renders blank, that's almost always an asset-publish or Nova-version problem, not a data problem.

Implementation Patterns

Gate on the Billable model, not on the tool. The tool has to know which Eloquent model owns subscriptions. Cashier Braintree stores subscriptions on the model using the Billable trait; a Nova tool can only resolve that via a configurable class name or a hardcoded App\User. Check the config for a model / billable key and set it explicitly rather than relying on the default — this is the single most common reason a fork "works" for the original author and not for you.

Pair it with Nova resources rather than replacing them. The pragmatic architecture is: this tool owns the Braintree-specific view (plan swaps, cancel-with-reason, raw gateway status), while a normal NovaResource for your Subscription model owns CRUD and search. Don't try to make the tool the source of truth for subscription lifecycle — Braintree is, and Cashier's webhook handlers sync it down.

Let webhooks drive state; treat the tool as a control panel. The healthiest workflow is: Braintree webhook → cashier-braintree updates the subscriptions table → the tool reads that table. Anything that mutates Braintree directly from the tool (cancel, swap) should call the Cashier API ($user->subscription('default')->cancel()) rather than hitting the Braintree SDK, so local state stays consistent and the same code path is covered by your tests.

Standard admin workflows worth wiring up:

  • Support triage: filter by status (active, past_due, canceled) to answer "why is this customer locked out" — usually past_due from a failed charge.
  • Goodwill cancel: cancel at period end from the tool, log the Nova action against the admin user for audit.
  • Refund/credit: keep this out of the tool and in a queued job with an audit trail; destructive Braintree operations from a Nova button are a compliance liability.
  • Plan migration: swap plan at period end, then verify the webhook round-trip lands the new braintree_plan on the local row.

Wrap it in a job for anything irreversible. A Nova action handler runs in the request cycle; a Braintree timeout leaves you with an ambiguous UI. Dispatch a job, return an optimistic "queued" state, and let the webhook resolve reality.

Fork it into nova-components/ for longevity. Given the package's age, the realistic integration is: copy the tool's Vue components and controller logic into a locally-maintained Nova tool you control, keeping the original namespace or renaming it cleanly. That way Nova upgrades are a migration you own, not a blocked dependency.

Gotchas and Tips

Nova version compatibility is the headline risk. Nova's tool API and frontend stack moved substantially after 2.x (Vue 3, Vite, changed Tool base class contracts, Nova::script/Nova::style signatures). A 2018 tool on a modern Nova install will typically fail at one of: service provider boot, asset registration, or blank component render. Check composer.json constraints before you spend an afternoon on a "broken" install.

Prebuilt dist/ assets are a trap. Old Nova tools ship compiled JS built with an old laravel-nova npm mixin. Rebuilding requires matching the original laravel-nova dev dependency, which may no longer resolve. If you must rebuild, pin the laravel-nova package to the version matching your Nova installation, and expect to fix Vue 2→3 breakage.

Credentials, not just config. cashier-braintree reads from braintree config keys (environment, merchant_id, public_key, private_key). A tool that "shows no subscriptions" is frequently pointed at production keys while your Nova test data is sandbox, or vice versa. Log the resolved environment on boot when debugging.

Cache config aggressively bites. php artisan config:cache after editing the published config will hold stale values — especially the billable model class. config:clear is the reflex fix for "I changed the config and nothing happened."

Authorization is not included by default in tools of this vintage. Add an explicit gate in NovaServiceProvider (Gate::define('viewBtCashierManager', ...)) or in the tool's boot, and check canSee/authorizedToView equivalents. Shipping a subscription-cancellation panel to every Nova user is a real incident.

Customer ID drift. If a user is deleted/recreated, the braintree_id on the local model and the customer in Braintree can diverge. Any "customer not found" from the Braintree API is almost always this — reconcile by searching Braintree on email before assuming a package bug.

Ambiguous cancel semantics. cancel() in Cashier Braintree means "cancel at period end" (onGracePeriod()), not immediate. If your admins expect instant termination, you need cancelNow() explicitly — and that's a support-ticket generator if the UI doesn't label it.

No webhook handling in the tool itself. It displays state; it does not receive Braintree webhooks. Your app must already have the Cashier Braintree webhook route configured and excluded from CSRF, or the tool will happily show stale active subscriptions indefinitely.

Debugging checklist when the panel is empty: config('cashier-braintree.model') resolves correctly → the resolved model actually uses Billable → subscriptions table has rows with matching braintree_id → Braintree keys are the same environment those rows were created in → tool assets are published and APP_URL/asset paths are correct behind a proxy.

Extension points worth using: the published config (billable model, per-page counts), Nova actions attached to the tool's component for cancel/swap, and Nova lenses on your Subscription resource if you need richer filtering than the tool offers — extending via Nova's own primitives is far cheaper than patching the tool's Vue.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin