basemkhirat / smartech-subscriptions by smartech

Manage users subscriptions for Laravel/Lumen apps
33
0
2
Package Data
Maintainer Username: smartech
Maintainer Contact: basemkhirat@smartech.online (Smartech)
Package Create Date: 2023-04-05
Package Last Update: 2023-04-19
Language: PHP
License: MIT
Last Refreshed: 2024-11-19 03:23:30
Package Statistics
Total Downloads: 33
Monthly Downloads: 4
Daily Downloads: 0
Total Stars: 0
Total Watchers: 2
Total Forks: 0
Total Open Issues: 0

Smartech Subscriptions

Manage user subscriptions for Laravel/Lumen apps

Requirements

  • php >= 5.6.6
  • laravel/laravel >= 5.* or laravel/lumen >= 5.*

Installation

Laravel Installation

1) Install package using composer.
$ composer require smartech/subscriptions
2) Add package service provider (< laravel 5.5).
Smartech\Subscriptions\SubscriptionServiceProvider::class
3) Publishing the configuration file (Optional).
$ php artisan vendor:publish --provider="Smartech\Subscriptions\SubscriptionServiceProvider"
4) Migrate tables.
$ php artisan subscriptions:migrate

Lumen Installation

1) Install package using composer.
$ composer require Smartech\Subscriptions
2) Add package service provider in bootstrap/app.php.
$app->register(Smartech\Subscriptions\SubscriptionServiceProvider::class);
3) Publishing the configuration file (Optional)
  • Copy the config file: vendor/smartech/subscriptions/config/subscriptions.php to the application config directory.

  • Setting Lumen to parse the configuration file.

$app->configure('subscriptions');
4) Migrate tables.
$ php artisan subscriptions:migrate

Configuration

use the HasSubscription trait with the User model.

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Smartech\Subscriptions\Traits\HasSubscription;

class User extends Authenticatable 
{
    use HasSubscription;

    //
}

Usage

Subscribe to a plan

  • To subscribe to a plan, you must either specify the pricing or request a trial period (if the plan supports requesting a trial period)
  • Setting the pricing by defining the period and its price for each plan, and each plan can have multiple pricings (monthly, yearly or others).
$user = auth("api")->user();

try {
    $user->setPlan("premium") // the plan slug
        ->setPricing(1) // the pricing ID
        ->subscribe(); // return bool

    // user subscribed successfully

}  catch (SubscriptionException $error) {

    // All available exceptions

    if ($error instanceof PlanNotFoundException) {
        return response()->json("Plan not found");
    }

    if ($error instanceof PricingNotFoundException) {
        return response()->json("Pricing not found");
    }

    if ($error instanceof SubscriptionExistException) {
        return response()->json("User has already subscribed to a plan");
    }
}

Subscribe to a a plan with trial period

  • If the requested plan supports requesting a trial period, the following code will subscribe the user to this plan with the period defined for each plan in the plans table.
  • setPricing should not be called here as trial period is always free.

$user = auth("api")->user();

try {

$user->setPlan("premium")
    ->setTrial()
    ->subscribe(); // return bool

    // user subscribed successfully

}  catch (SubscriptionException $error) {

    // All available exceptions

    if ($error instanceof PlanNotFoundException) {
        return response()->json("Plan not found");
    }

    if ($error instanceof TrialNotSupportedException) {
        return response()->json("Trial is not supported for this plan");
    }

    if ($error instanceof TrialExistException) {
        return response()->json("Trial period has already been requested before.");
    }
}

Change the subscription plan

  • Changing the plan will set a new plan to the user and set a new period (started_at, ended_at) based on the pricing ID.

try {
    $user = auth("api")->user();
    
    $user->setPlan("premium") // the new plan slug
        ->setPricing(2) // the pricing ID
        ->change();

}  catch (SubscriptionException $error) {

    if ($error instanceof PlanNotFoundException) {
        return response()->json("Plan not found");
    }

    if ($error instanceof PricingNotFoundException) {
        return response()->json("Pricing not found");
    }
}

Renew the subscription

  • Renewing the subscription will only set a new period (started_at, ended_at) based on the current pricing ID.
/*
* can_be_renewed will check if:
* - The subscription is ended.
* - The subscription is not trial.
* - The subscribed plan is not default.
*/
if($user->subscription->can_be_renewed) {
    $user->subscription->renew();
}

Cancel the subscription

  • Canceling the subscription will set the canceled_at field
  • By default, the subscription will still valid until the end of the current period.
/*
* can_be_renewed will check if:
* - The subscription is not trial.
* - The subscribed plan is not default as it can not be canceled.
*/

if($user->subscription->can_be_canceled) {
    $user->subscription->cancel();
}
  • If we want to cancel the subscription immediately, just call $user->subscription->cancel(true).

Activate/Deactivate the subscription

  • Activating/Deactivating the subscription will set the is_active field.
$user->subscription->activate();
$user->subscription->deactivate();

Models

Subscription Model

$user = auth("api")->user();

// Getting user subscription

$subscription = $user->subscription;

// Getting user subscription plan 

$plan = $user->subscription->plan;

// Getting the user subscription pricing

$pricing = $user->subscription->pricing;

// Check if the user subscription is trial

$subscription->is_trial; // return bool

// Check if the user subscription is activated

$subscription->is_active; // return bool

// Check if the user subscription is ended

$subscription->is_ended; // return bool

// Check if the user is valid (activated and not ended)

$subscription->is_valid; // return bool

// Check if the user has canceled his subscription

$subscription->is_canceled; // return bool

/// Fetch all trial subscriptions

$subscriptions = app("subscriptions.models.subscription")->trial()->get();

// Fetch all valid/invalid subscriptions
// The valid subscription means both (activated and the period is not ended)

$subscriptions = app("subscriptions.models.subscription")->valid()->get();
$subscriptions = app("subscriptions.models.subscription")->invalid()->get();

// Fetch only active/inactive subscriptions

$subscriptions = app("subscriptions.models.subscription")->active()->get();
$subscriptions = app("subscriptions.models.subscription")->inactive()->get();

// Fetch only current/expired subscriptions

$subscriptions = app("subscriptions.models.subscription")->inPeriod()->get();
$subscriptions = app("subscriptions.models.subscription")->notInPeriod()->get();
// 

Plan Modal

// Getting user subscription plan.

auth("api")->user()->subscription->plan

// Getting the default plan

$plan = app("subscriptions.models.plan")->default()->first();

// Query the plan model

$plan = app("subscriptions.models.plan")->where("slug", "premium")->first();

// check if there is a trial support for this plan

$plan->has_trial; // return bool


// check if this plan is the default plan

$plan->is_default; // return bool

// Getting all plan pricings
// the pricings determine what price to pay for a period of time (monthly, yearly or a custom period)

$plan->pricings;

// Getting all plan features

$plan->features;

// Getting all available translations of all languages

$plan->translations;

// Getting the current translation based on user language

$plan->translation;

User Model

Get user subscription

auth("api")->user()->subscription;

check if user has specific plan

auth("api")->user()->hasPlan("premium"); // return bool

check if user has specific feature

auth("api")->user()->hasFeature("ad_free"); // return bool

Extending Models

All models are binded into IOC and listed in config/subscription.php.

As example, we want to extend the Plan model.

  1. Edit config/subscription.php and set the models.plan to have the new plan model class \App\Models\Plan::class.

  2. define the new class extends the parent plan class

<?php

namespace App\Models;

class Plan extends \Smartech\Subscriptions\Models\Plan
{
    // we can override model attributes/methods or create new methods here.
}

  1. Now you can call it from app("subscriptions.models.plan") or from \App\Models\Plan.