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

Spike Laravel Package

opcodesio/spike

Spike is a Laravel performance monitoring package that helps you spot bottlenecks by tracking slow requests, queries, and exceptions in a built-in dashboard, making it easier to diagnose issues and keep your application running smoothly.

View on GitHub
Deep Wiki
Context7

Getting Started

Spike is a billing/subscription layer for Laravel: you define plans, mark a model as billable, and gate features or meter usage against a subscription. The free edition (opcodesio/spike-free) is the MIT-licensed core, so treat the Pro edition's marketing pages as documentation for concepts, not for API surface — verify every class and config key against src/ in this repo before you design around it.

Day-one sequence:

composer require opcodesio/spike
php artisan vendor:publish --provider="Opcode\\Spike\\SpikeServiceProvider"
php artisan migrate

Then read, in this order:

  1. config/spike.php — this is the contract. Plans, feature list, currency, payment driver and webhook settings live here. If something is missing from config, it usually isn't supported.
  2. The service provider — shows what is bound in the container and which middleware/route groups are registered for webhooks.
  3. src/Models and src/Traits — tells you exactly which contract your User model must satisfy and what the billable trait gives you.
  4. Migrations — the schema reveals intent faster than any README (e.g. whether usage is stored per-period or as a running counter).

A good first use case is the smallest one that exercises the whole loop: one paid plan, one gated route, one Stripe test-mode checkout. Get subscribe → webhook → entitlement check working end-to-end before you model tiers or usage. Billing packages fail at the seams (webhook delivery, period boundaries), not in the happy path you can read in the source.

Implementation Patterns

Config-driven plan catalogue. Define plans and their features in config/spike.php rather than in the database. It gives you version control, easy diffing between environments, and no seeding step in CI. Keep the plan identifiers stable strings — they will end up in your database and in Stripe metadata, and renaming them later means a data migration.

Entitlement checks at the boundary, not in views. Wrap feature checks in a single application service (e.g. Billing::can($user, 'exports')) or a Gate definition, then call that from middleware, policies and jobs. Never call the package directly from Blade — when you migrate to Pro or swap providers, you want one seam to change. Cache the resolved entitlement per request; a check inside a loop is a query per iteration.

Middleware for tier-gated areas, policies for object-level rules. Route groups get ->middleware('spike.plan:pro')-style guards; per-record limits (seats, projects, API keys) belong in a policy or a creating model observer that throws a domain exception, not a 403 from a controller.

Usage metering as an event, not an increment. If the package exposes a usage recorder, call it from a queued listener on your domain events (ExportGenerated, ApiCallMade) rather than inline in the request. That decouples the write path, lets you retry, and keeps the meter consistent when the main action is retried or rolled back. Use DB::transaction for the business write and dispatch the metering event after commit.

Webhook handling is the real integration. Point the package's webhook route at an excluded-from-CSRF path, keep the secret in .env (never in config committed to git), and forward to a queue. In local dev, use the Stripe CLI to replay events; in staging, replay a captured fixture set. Treat the webhook as the source of truth for subscription state and treat your checkout redirect as merely cosmetic.

Testing. Fake the gateway at the HTTP layer (Http::fake() on the provider's API host) and assert on your state, not the package's internals. Keep a small set of fixture payloads for customer.subscription.updated and invoice.payment_failed — those two events cover most of the bugs people ship.

Gotchas and Tips

  • Free-vs-Pro surface area is the biggest risk. Documentation, screenshots and blog posts describing Spike will largely describe the paid product. Audit the free package's src/ for what's actually implemented before promising a feature; if a capability is missing, plan the workaround (a small custom table keyed on the subscription) rather than assuming an upgrade path.
  • Maturity tax. ~30 stars and no dependents means you are an early adopter. Pin the exact version in composer.json, read the diff of every bump, and avoid extending internal classes — extend via your own wrapper so a refactor upstream doesn't break you.
  • Money in minor units. Assume integers in cents and format only at the edges. Mixing floats into a billing codebase is the classic way to ship off-by-one-cent invoices.
  • Period boundaries and timezones. Subscription periods are computed in the payment provider's timezone, not config('app.timezone'). Any "resets on the 1st" logic you write must align with the provider's period fields, or usage will double-count or vanish for a few hours each month.
  • Webhook idempotency and ordering. Events arrive out of order and more than once. Guard every handler with a processed-events table or an updated_at comparison, and never assume subscription.updated arrives before invoice.paid.
  • Race between redirect and webhook. The user returns from checkout before the webhook lands. Show a "provisioning…" state and poll or use a broadcast, rather than reading subscription state synchronously in the success controller.
  • Proration and downgrades. Decide explicitly what happens to usage on plan change; upstream behaviour here is often the default you least want. Write a test for upgrade-mid-period and downgrade-mid-period before launch.
  • Migrations. The published migrations may collide with existing users columns or indexes. Run them on a fresh copy of production data early, not the week before release.
  • Extension points. The service provider's bindings are your escape hatch: swap the billable model, the plan resolver, or the gateway client via container binding rather than forking. If the provider doesn't bind it, it isn't an extension point — vendor-patch and note it for the next upgrade.
  • Debugging. Log the raw webhook payload (redacting PII) to a dedicated channel for the first few weeks. When state is wrong, the payload is the only artefact that tells you whether the bug is yours or the package's.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect