gerardojbaez/laraplans
LaraPlans is a Laravel package for adding subscription plans and feature limits to your application. Define plans, subscribe users, manage renewals, and gate features through a clean, configurable API.
Architecture fit. laraplans is a lightweight entitlement and plan-management layer for Laravel: Plan, Feature, and Subscription models, HasPlans/CanSubscribe traits on the user model, and a feature manager for metering and consuming feature usage (limit-style and charging-style features). It is not a billing engine — it does not process payments, prorate invoices, or reconcile against a PSP. That is the single most important architectural fact for a TPM: it composes with Cashier/Paddle/Stripe rather than replacing them. If the product needs a plan catalog plus feature gating and usage counters, the package fits directly inside a Laravel monolith. If the product is multi-tenant with per-workspace subscriptions, or needs tax, invoicing, dunning, and revenue recognition, this package covers only the entitlement half and must be paired with a billing system of record.
Integration feasibility. High for a standard Laravel app: composer require, publish and run migrations, add traits to the User model, seed plans and features, and gate routes/policies on feature checks. The public surface is small enough to wrap behind an internal EntitlementService interface, which is the key de-risking move — it lets the team swap the package for a first-party implementation or a commercial alternative later without touching call sites. Effort is typically days, not weeks, for the happy path; the real cost sits in designing the plan/feature taxonomy and in reconciling it with whatever the PSP considers a subscription.
Technical risk. Several concrete concerns:
Subscription rows vs. PSP subscription state) will drift without a webhook-driven reconciliation job. This is the most likely source of production incidents.Key questions for the maintainer/team. Does it support team/organization-level subscriptions or only user-level? How are quota resets scheduled and made idempotent? Is feature consumption transactional and safe under concurrent requests? What is the upgrade/downgrade model, and does it emit events we can hook to the PSP? Is there a documented extension path for custom feature types? What is the maintainer's stated support commitment and release cadence?
Stack fit. Strong for a Laravel-first SaaS where the team already runs Eloquent, queued jobs, and a scheduler. It presumes the app owns its relational schema and is comfortable with trait-based model extension. It is a poor fit for polyglot service architectures or teams already standardized on a billing platform's native entitlement model (e.g., Stripe entitlements), where it would be a redundant abstraction.
Migration path. Greenfield: adopt early, before plan data has business meaning. Brownfield: introduce behind a feature flag with a shadow read path — compute entitlements from both the existing mechanism and laraplans, log divergences, and only flip the enforcement switch once divergence is near zero. Backfill plans/features from the current pricing config via a one-off seeder, not manual admin entry.
Compatibility and sequencing.
EntitlementService and BillingGateway boundary; no package types leak into controllers or UI.created/updated/canceled/payment_failed events.Sequencing rule of thumb: never let the package's subscription records become authoritative for money. PSP is the billing source of truth; laraplans is the derived entitlement cache, rebuildable from PSP events at any time. That single design constraint makes the rest of the risk manageable.
Maintenance. Low ongoing code churn — the surface is small — but a non-trivial watch burden: the team effectively owns the fork. Assign a named owner, pin the version, and budget a half-day per quarter to review upstream commits and Laravel major-version compatibility. The internal EntitlementService wrapper is what keeps a future fork or replacement cheap.
Support. Community-only, no SLA, no vendor escalation. For a revenue-critical entitlement path, that means incidents are resolved by the team. Mitigation: keep the package's usage concentrated in a thin layer with tests, so a broken release can be rolled back without data loss (since data is rebuildable from the PSP).
Scaling. Fine for tens of thousands of subscriptions; the pressure point is usage-event volume if metered features are consumed per request. Plan for an append-only usage table, indexes on (subscription_id, feature_id, period), and periodic aggregation into per-period counters. Read entitlements from cache (per-request memoization plus a short-TTL cache keyed by subscription) to keep gating off the hot query path.
Failure modes to instrument.
lockForUpdate, plus tests simulating parallel consumption.Ramp-up. Low for any Laravel developer — a day to be productive, two to three days to be confident in the consumption and concurrency semantics. The real ramp-up is domain, not API: the team must internalize the plan/feature taxonomy and the bill-vs-entitle boundary. Write a one-page internal contract ("PSP owns money, laraplans owns access, reconciliation owns truth") and put it in the ADR. Also budget product/ops onboarding for whoever administers plan changes — the absence of a built-in admin UI is a gap that will surface as either a small internal back-office task or a seeder-driven release process, and that decision should be made explicitly rather than by default.
How can I help you explore Laravel packages today?