Laravel Magazine
Subscriptionify: Feature-Based Subscription Management for Laravel

Subscriptionify: Feature-Based Subscription Management for Laravel

Eric Van Johnson ·

A new package landed on Laravel News in June called Subscriptionify, and it fills a gap that Laravel Cashier deliberately doesn't address: modelling what features a subscriber gets, not just what they're billed.

The Problem It Solves

Laravel Cashier is excellent at wrapping Stripe or Paddle's billing APIs — it handles charges, invoices, trials, and webhooks. But Cashier doesn't know what a "Pro" plan actually unlocks in your application. That logic ends up scattered across controllers, middleware, and policy files, checked against subscription tier strings you hardcode everywhere.

Subscriptionify takes a different approach. It's entirely gateway-agnostic and focuses purely on: what plans exist, what features those plans include, what quotas apply, and how much of each quota a subscriber has consumed.

How It Works

After installing the package and running the migrations, you define your plans in a config file or through the provided fluent API:

use Subscriptionify\Facades\Subscriptionify;

Subscriptionify::plan('starter')
    ->feature('projects', limit: 3)
    ->feature('team_members', limit: 1)
    ->feature('api_access', enabled: false);

Subscriptionify::plan('pro')
    ->feature('projects', limit: 25)
    ->feature('team_members', limit: 10)
    ->feature('api_access', enabled: true);

Subscriptionify::plan('enterprise')
    ->feature('projects', limit: PHP_INT_MAX)
    ->feature('team_members', limit: PHP_INT_MAX)
    ->feature('api_access', enabled: true);

Add the HasSubscription trait to your User model, then checking feature access is straightforward:

// Check if a feature is enabled
if ($user->subscription()->can('api_access')) {
    // allow access
}

// Check remaining quota
$remaining = $user->subscription()->remaining('projects');

// Record usage
$user->subscription()->consume('projects');

The package also ships with a SubscriptionGate middleware you can attach to routes:

Route::middleware(['auth', 'subscription.feature:api_access'])
    ->prefix('api/v1')
    ->group(function () {
        // API routes
    });

What It Doesn't Do

Subscriptionify intentionally has no billing logic. It won't charge a card, process a webhook, or sync with Stripe. The expectation is that you pair it with Cashier (or any other billing package) and call $user->subscription()->assignPlan('pro') from your own webhook handler or upgrade controller.

This separation of concerns is the package's biggest strength and its main constraint. If you want an all-in-one solution, Cashier + Spark is still your best bet. But if you're already comfortable with billing and just need a clean, testable model for feature entitlements, Subscriptionify is worth a look.

Installation

composer require subscriptionify/laravel

php artisan vendor:publish --tag=subscriptionify-migrations
php artisan migrate

The full documentation is available on Laravel News along with the GitHub repository.

Stay Updated

Subscribe to our newsletter

Get latest news, tutorials, community articles and podcast episodes delivered to your inbox.

Weekly articles
We send a new issue of the newsletter every week on Friday.
No spam
We'll never share your email address and you can opt out at any time.