LA SUBSCRIPTION is a robust package designed to simplify the implementation and management of subscription-based services within Laravel applications. It provides a flexible approach to handle various subscription plans, making it ideal for SaaS applications, membership sites, and any system requiring recurring billing.
You can install the package via composer:
composer require aldeebhasan/la-subscription
You can publish and run the migrations with:
php artisan vendor:publish --tag="la-subscription-migrations"
php artisan migrate
You can publish the config file with:
php artisan vendor:publish --tag="la-subscription-config"
This is the contents of the published config file:
return [
'prefix' => env("LA_SUBSCRIPTION_PREFIX", "la"),
'grace_period' => env("LA_GRACE_PERIOD", 7),
'path' => env("LA_PATH", 'la-subscriptions'),
'middleware' => ['web'],
];
Optionally, you can publish the views using
php artisan vendor:publish --tag="la-subscription-views"
Tip
As soon as you install this package, you can access the package dashboard through the path initialized in the configuration file.
By default it is http://*/la-subscriptions
. If you are working on the local environment, it will be http://127.0.0.1:8000/la-subscriptions/dashboard
To start using this package you need first to add HasSubscription
Trait to the model you want to handle the subscription for it.
namespace App\Models;
use Aldeebhasan\LaSubscription\Traits\HasSubscription;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use HasSubscriptions;
}
The basic unit of any subscription is the features, you can group them under specific groups according to there type.
You can create features either using the package dashboard
or manually
as follow:
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Aldeebhasan\LaSubscription\Models\Feature;
use Aldeebhasan\LaSubscription\Models\Group;
use Aldeebhasan\LaSubscription\Enums\GroupTypeEnum;
class FeatureSeeder extends Seeder
{
public function run()
{
$group = Group::create([
'name' => "Sales",
'type' => GroupTypeEnum::FEATURE
]);
$feature_1 = Feature::create([
'limited' => false,
'name' => 'Invoice Managements',
'code' => 'invoices',
'group_id' => $group->id,
]);
$feature_2 = Feature::create([
'limited' => true,
'name' => 'User Managements',
'code' => 'users',
'group_id' => $group->id,
]);
}
}
The features can be limited/unlimited. The limited feature has specific quota need to be specified, and the subnscriber can't use more that the specified quota.
On the other hand, the unlimited feature has unlimited number of usage quota. This can be identified using the limited
param.
Plans work like a group of features that will be available to the subscriber.
You can define a new plan either using the package dashboard
or manually
as follow:
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Aldeebhasan\LaSubscription\Enums\BillingCycleEnum;
use Aldeebhasan\LaSubscription\Models\Feature;
use Aldeebhasan\LaSubscription\Models\Product;
use Aldeebhasan\LaSubscription\Models\Group;
use Aldeebhasan\LaSubscription\Enums\GroupTypeEnum;
class PlanSeeder extends Seeder
{
public function run()
{
$group = Group::create([
'name' => "Premium Plans",
'type' => GroupTypeEnum::PLAN
]);
$plan = Product::create([
'name' => "Starter",
'description' => 'Description of starter plan',
'code' => 'starter',
'group_id' => $group->id,
'price' => 15,
'price_yearly' => 12,
]);
$feature_1 = Feature::whereCode('users')->first();
$feature_2 = Feature::whereCode('users')->first();
$plan->features()->attach($feature_1, ['value' => 20]);
$plan->features()->attach($feature_2);
}
}
Now everything is ready to create a new subscription for the subscribing model :
$subscriber = User::create(['name'=>'Subscriber']);
$plan = \Aldeebhasan\LaSubscription\Models\Product::firstWhere('code','starter');
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->subscribeTo($plan)
//OR
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->subscribeTo($plan, now()->endOfMonth())
//OR
$period = 12; // in months
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->subscribeTo($plan, now()->endOfMonth(), $period)
If you already subscribed to a plan you want to change the subscription plan to another one (like upgrade the subscription), you can use switchTo
.
Note that you can switch the plan at a specific time in the future and with different billing cycle.
$newPlan = \Aldeebhasan\LaSubscription\Models\Product::firstWhere('code','silver');
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->switchTo($newPlan)
//OR
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->switchTo($newPlan, now()->endOfMonth())
//OR
$period = 6; // in months
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->switchTo($plan, now()->endOfMonth(), $period)
Note
By switching subscription , the old subscription will be set at suppressed status, and the suppressed date will be stored.
Note
The switchTo
function has an optional parameter named as $withPlugins
. This param indicate if you want to install the current installed plugins with the switched plan or not.
"we will talk about the Plugins later"
In case you want to renew the current subscription you can do it as follow:
$period = 6; // in months
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->renew($period)
Note
The renew
function has an optional parameter named as $withPlugins
. This param indicate if you want to renew the plugins with the plan or not.
"we will talk about the Plugins later"
At any point of time, if you want to bypass all the subscription features check for specific subscriber, you can enable Unlimited access
for him.
The will enable him to access to all the features with out any limitations.
$period = 6; // in months
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->setUnlimitedAccess(true)
// OR
$subscriber->setUnlimitedAccess(true)
At any point of time, if you want to cancel the user subscription or resumed canceled one, you can do it as follow:
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->cancel()
// OR
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->cancel(now()->endOfMonth())
//To resume
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->resume()
Plugins in this package represent a set of figures that can be added to the subscription along with the plan. As example, the user at the starter plan may want to enable a plugin that give him access to specific features that are not enabled in his plan. Plugins can be considered as a small plans with limited set of features.
Plugins can be RECURRING/NON_RECURRING,
- The RECURRING plugin will follow the same subscription billing cycle, if not renewed, the subscriber will loss the access to its features.
- The NON_RECURRING plugins will be enabled forever, there is no need to renew it at all.
You can define new plugins either using the package dashboard
or manually
as follow:
$group = Group::create([
'name' => "Accounting Plugins",
'type' => GroupTypeEnum::PLUGIN
]);
$plugin = Product::create([
'name' => "Advanced reports",
'description' => 'Description of Advanced reports',
'code' => 'advanced-reports',
'group_id' => $group->id,
'type' => BillingCycleEnum::RECURRING, // Or Un-Recurring
'price' => 15;
'price_yearly' => 12;
]);
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->addPlugin($plugin);
//OR as specific time
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->addPlugin($plugin, now()->endOfMonth());
//OR you can specify the model that caused this addition (ex: the Invoice item or a manager user), by default it will be the subscriber himself.
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->addPlugin($plugin, now()->endOfMonth(), $manager);
At any point of time you can cancel any plugin or resume it as follow:
$causative = $subscriber->manager; // optional
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->cancelPlugin($plugin , $causative)
//To resume
\Aldeebhasan\LaSubscription\LaSubscription::make($subscriber)->resumePlugin($plugin , $causative)
Warning
When a plugin is cancelled, it will not be renewed with the plan any more.
You can check if the subscriber can consume feature/features as follow:
$code = "feature-code" // or ["feature-1-code" ,"feature-2-code" ]
$subscriber->canConsume($code );
You can check if the subscriber can consume any feature/features as follow:
$code = ["feature-1-code" ,"feature-2-code" ]
$subscriber->canConsumeAny($code);
For the features that has limited quotas, you can register the consumption of that feature as follow
$code = 'feature-code';
$amount = 1; // 1 is the default value
$subscriber->consume($code, $amount);
For any reason that require you to return the consumption value to the subscriber you can do that with the follow:
$code = 'feature-code';
$amount = 1; // 1 is the default value
$subscriber->retrieve($code, $amount);
To retrieve the current consumption of specific feature
$subscriber->getCurrentConsumption('feature-code');
To retrieve the remaining balance of limited features
$subscriber->getBalance('feature-code');
composer test
Please see CHANGELOG for more information on what has changed recently.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.