Skip to content

Foysal50x/tashil

Repository files navigation

Tashil – Subscription Management for Laravel

Tashil (تسهيل) is a comprehensive subscription management package for Laravel with built-in Redis caching, feature-gated access, usage tracking, billing, and analytics.


Table of Contents


Installation

Requirements

  • PHP 8.2+
  • Laravel 10.x, 11.x, or 12.x
  • Redis (for caching layer)

Install via Composer

composer require foysal50x/tashil

Publish configuration and run migrations

php artisan vendor:publish --tag=tashil-config
php artisan vendor:publish --tag=tashil-migrations
php artisan migrate

Configuration

After publishing, update config/tashil.php as needed:

return [
    /*
    |--------------------------------------------------------------------------
    | Database Configuration
    |--------------------------------------------------------------------------
    */
    'database' => [
        // The database connection to use for Tashil tables.
        // If null, the default application connection will be used.
        'connection' => env('TASHIL_DB_CONNECTION', null),

        // Table prefix for all Tashil tables.
        'prefix' => 'tashil_',

        // Customise table names used by the package.
        'tables' => [
            'packages'           => 'packages',
            'features'           => 'features',
            'package_feature'    => 'package_feature',
            'subscriptions'      => 'subscriptions',
            'subscription_items' => 'subscription_items',
            'usage_logs'         => 'usage_logs',
            'invoices'           => 'invoices',
            'transactions'       => 'transactions',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Invoice Configuration
    |--------------------------------------------------------------------------
    */
    'invoice' => [
        'prefix'    => 'INV',
        'format'    => '#-YYMMDD-NNNNNN', // #=Prefix, YY/MM/DD=Date, N=Digit, S=Letter, A=AlphaNumeric
        'generator' => Foysal50x\Tashil\Services\Generators\InvoiceNumberGenerator::class,
    ],

    /*
    |--------------------------------------------------------------------------
    | Default Currency
    |--------------------------------------------------------------------------
    */
    'currency' => env('TASHIL_CURRENCY', 'USD'),

    /*
    |--------------------------------------------------------------------------
    | Redis Configuration
    |--------------------------------------------------------------------------
    */
    'redis' => [
        'host'     => env('TASHIL_REDIS_HOST', env('REDIS_HOST', '127.0.0.1')),
        'password' => env('TASHIL_REDIS_PASSWORD', env('REDIS_PASSWORD', null)),
        'port'     => env('TASHIL_REDIS_PORT', env('REDIS_PORT', 6379)),
        'database' => env('TASHIL_REDIS_DB', 5),
    ],

    /*
    |--------------------------------------------------------------------------
    | Cache Configuration
    |--------------------------------------------------------------------------
    */
    'cache' => [
        // Prefix for all cache keys generated by Tashil.
        'prefix' => env('TASHIL_CACHE_PREFIX', 'tashil_cache:'),

        // Default Time To Live (TTL) in seconds for cached items.
        'ttl' => 3600,

        // Whether to enable the caching layer globally.
        'enabled' => env('TASHIL_CACHE_ENABLED', true),
    ],
];

Quick Start

use Foysal50x\Tashil\Facades\Tashil;

// 1. Create features
$apiCalls = Tashil::feature('api-calls')
    ->name('API Calls')
    ->limit()
    ->create();

$darkMode = Tashil::feature('dark-mode')
    ->name('Dark Mode')
    ->boolean()
    ->create();

// 2. Create a package with features
$proPlan = Tashil::package('pro')
    ->name('Pro Plan')
    ->price(29.99)
    ->monthly()
    ->trialDays(14)
    ->feature($apiCalls, value: '10000')
    ->feature($darkMode, value: 'true')
    ->create();

// 3. Subscribe a user
$subscription = Tashil::subscription()->subscribe($user, $proPlan, withTrial: true);

// 4. Check feature access & track usage
if ($user->canUseFeature('api-calls')) {
    $user->incrementUsage('api-calls');
}

// 5. Get analytics
$summary = Tashil::analytics()->dashboardSummary();

Features

📦 Subscription Management

  • Flexible Plans: Create unlimited packages with custom billing intervals (daily, weekly, monthly, yearly) or lifetime access.
  • Trial Periods: Configurable trial days per package.
  • Lifecycle Management: Subscribe, cancel (gracefully or immediately), resume, and switch plans with prorated handling.
  • State Management: Robust status handling (Active, OnTrial, Cancelled, Expired) using Enums.

💰 Billing & Invoices

  • Automated Invoicing: Generates invoices for subscriptions and renewals.
  • Custom Currencies: Support for package-specific currencies.
  • Proration: Handles plan switching calculations.
  • Grace Periods: Configurable due dates and overdue handling.

⚡ Feature Access & Usage Tracking

  • Granular Permissions:
    • Boolean: Simple on/off access (e.g., "Pro Dashboard").
    • Limit: Numerical quotas (e.g., "10 Projects").
    • Consumable: One-time use tokens (e.g., "5 AI Credits").
  • Usage Tracking: Real-time tracking of feature usage.
  • Limit Enforcement: Automatically blocks actions when limits are exceeded.
  • Usage Warnings: Dispatches events when usage hits thresholds (e.g., 80%).
  • Resets: Reset limits manually or automatically on renewal.

📊 Analytics & Reporting

  • Dashboard Summary: All-in-one KPI method for quick admin dashboards (uses batch queries — only 2 DB queries).
  • Revenue Metrics:
    • MRR (Monthly Recurring Revenue) & ARPU (Average Revenue Per User).
    • Total Revenue & Revenue by Package.
    • Revenue trends over time.
  • Growth Metrics:
    • New Subscriptions trend.
    • Trial Conversion Rates.
    • Churn Rate & Churn Trends (batch-optimized — 2 queries instead of 24).
  • Operational Metrics:
    • Pending & Overdue Invoice counts.
    • Active vs. Inactive Subscriber breakdowns.
  • Cross-Database Compatibility: All analytics queries use tpetry/laravel-query-expressions — no raw SQL.

🛠️ Developer Experience

  • Trait-based Integration: Add use HasSubscriptions to any model (User, Team, etc.).
  • Fluent API:
    • $user->subscribe($package)
    • $user->onPlan('pro')
    • $user->canUseFeature('api-calls')
  • Events: Rich event system (SubscriptionCreated, SubscriptionRenewed, UsageLimitWarning) for custom hook integration.
  • Repository Pattern: Swappable repositories for caching and database abstraction.
  • High Performance: In-memory subscription caching, batch queries, and Redis caching support.

Feature Types

Tashil supports four feature types:

Type Enum Description
Boolean FeatureType::Boolean On/off toggle (e.g. dark mode)
Limit FeatureType::Limit Numeric limit with enforcement (e.g. 10,000 API calls)
Consumable FeatureType::Consumable Trackable usage without hard limit
Enum FeatureType::Enum Named option value

Creating Features with FeatureBuilder

use Foysal50x\Tashil\Facades\Tashil;

// Boolean feature
$feature = Tashil::feature('priority-support')
    ->name('Priority Support')
    ->description('Access to priority support channels')
    ->boolean()
    ->create();

// Limit feature
$feature = Tashil::feature('api-calls')
    ->name('API Calls')
    ->limit()
    ->metadata(['reset_period' => 'monthly'])
    ->create();

// Consumable feature
$feature = Tashil::feature('storage')
    ->name('Storage (GB)')
    ->consumable()
    ->create();

// Create or update (idempotent by slug)
$feature = Tashil::feature('api-calls')
    ->name('API Calls (Updated)')
    ->limit()
    ->createOrUpdate();

Creating Packages with PackageBuilder

use Foysal50x\Tashil\Facades\Tashil;

$package = Tashil::package('pro')
    ->name('Pro Plan')
    ->description('For growing teams')
    ->price(29.99)
    ->originalPrice(49.99)         // strike-through price
    ->monthly()                     // or ->yearly(), ->quarterly(), ->lifetime()
    ->trialDays(14)
    ->featured()                    // mark as featured plan
    ->sortOrder(2)
    ->feature($apiCalls, value: '10000')
    ->feature($darkMode, value: 'true')
    ->feature($storage, value: '50')
    ->create();

// Attach multiple features at once
$package = Tashil::package('enterprise')
    ->name('Enterprise')
    ->price(99.99)
    ->yearly()
    ->features([
        $apiCalls  => ['value' => '100000'],
        $darkMode  => ['value' => 'true'],
        $storage   => ['value' => '500'],
    ])
    ->create();

Billing Periods

Period Enum Example
Daily Period::Day ->billingPeriod(Period::Day, 1)
Weekly Period::Week ->billingPeriod(Period::Week, 1)
Monthly Period::Month ->monthly()
Quarterly ->quarterly()
Yearly Period::Year ->yearly()
Lifetime Period::Lifetime ->lifetime()

Subscriptions

Subscription Lifecycle

subscribe() ──▶ OnTrial ──▶ Active ──▶ cancel() ──▶ Cancelled
                  │                        │
                  └─ (trial ends) ─────────┘        resume()
                                                      │
                                               ◀──────┘

Subscription Statuses

Status Enum Meaning
Pending SubscriptionStatus::Pending Awaiting activation
Active SubscriptionStatus::Active Currently active
On Trial SubscriptionStatus::OnTrial In free trial period
Past Due SubscriptionStatus::PastDue Payment overdue
Cancelled SubscriptionStatus::Cancelled User cancelled
Expired SubscriptionStatus::Expired Subscription period ended
Suspended SubscriptionStatus::Suspended Admin-suspended

Creating Subscriptions

use Foysal50x\Tashil\Facades\Tashil;

// Subscribe without trial
$subscription = Tashil::subscription()->subscribe($user, $package);

// Subscribe with trial (uses package's trial_days)
$subscription = Tashil::subscription()->subscribe($user, $package, withTrial: true);

When a subscription is created:

  1. The subscription record is persisted with calculated ends_at
  2. Feature items from the package are synced to the subscription
  3. A SubscriptionCreated event is dispatched

Cancelling

// Cancel at end of billing period (grace period)
Tashil::subscription()->cancel($subscription, reason: 'Too expensive');

// Cancel immediately
Tashil::subscription()->cancel($subscription, immediate: true);

Resuming

// Resume a cancelled subscription (only if ends_at is in the future)
Tashil::subscription()->resume($subscription);

Switching Plans

// Switch to a different package (cancels old, creates new)
$newSubscription = Tashil::subscription()->switchPlan($subscription, $newPackage);

Checking Subscription Status

$subscription->isActive();    // true if status is Active
$subscription->isOnTrial();   // true if status is OnTrial
$subscription->isCancelled(); // true if status is Cancelled
$subscription->isExpired();   // true if status is Expired
$subscription->isPastDue();   // true if status is PastDue
$subscription->isValid();     // true if Active or OnTrial

Usage Tracking

Incrementing Usage

use Foysal50x\Tashil\Facades\Tashil;

// Increment by 1
Tashil::usage()->increment($subscription, 'api-calls');

// Increment by custom amount
Tashil::usage()->increment($subscription, 'storage', amount: 2.5);

Returns false if:

  • The feature doesn't exist on the subscription
  • The usage would exceed the feature's limit

Checking Access

// Can the feature be consumed?
$canUse = Tashil::usage()->check($subscription, 'api-calls');

// Check a specific amount
$canUse = Tashil::usage()->check($subscription, 'storage', amount: 10);

Resetting Usage

// Reset a single feature
Tashil::usage()->resetUsage($subscription, 'api-calls');

// Reset all features
Tashil::usage()->resetAllUsage($subscription);

Usage Warnings

When a feature reaches 80% usage, a UsageLimitWarning event is dispatched automatically. Listen for this in your EventServiceProvider:

use Foysal50x\Tashil\Events\UsageLimitWarning;

protected $listen = [
    UsageLimitWarning::class => [
        SendUsageWarningNotification::class,
    ],
];

Billing & Invoices

Generating Invoices

use Foysal50x\Tashil\Facades\Tashil;

// Generate invoice using the package price
$invoice = Tashil::billing()->generateInvoice($subscription);

// Generate with custom amount
$invoice = Tashil::billing()->generateInvoice($subscription, amount: 39.99);

Each invoice gets a unique number in the format INV-YYYYMMDD-XXXXXX.

Invoice Statuses

Status Enum
Draft InvoiceStatus::Draft
Pending InvoiceStatus::Pending
Paid InvoiceStatus::Paid
Void InvoiceStatus::Void
Refunded InvoiceStatus::Refunded

Managing Invoices

// Mark invoice as paid
$invoice->markAsPaid();

// Void an invoice
$invoice->markAsVoid();

Console Commands

Process Subscriptions

Automates subscription renewals and expirations. Suggested to run daily.

php artisan tahsil:process-subscriptions
  • Renewals: Creates invoices for auto-renewing subscriptions expiring today.
  • Expirations: Marks non-renewing subscriptions as expired.
// app/Console/Kernel.php or routes/console.php
$schedule->command('tashil:process-subscriptions')->daily();

Analytics & Reporting

The AnalyticsService provides comprehensive subscription, revenue, and usage analytics. Access it via the facade:

$analytics = Tashil::analytics();

Subscription Metrics

// Total subscriptions (all statuses)
$analytics->totalSubscriptionCount();        // 1,250

// Active subscriptions only (active + on_trial)
$analytics->activeSubscriptionCount();       // 980

// Breakdown by status
$analytics->subscriptionCountByStatus();
// ['active' => 800, 'on_trial' => 180, 'cancelled' => 150, 'expired' => 120]

// Subscribers per package
$analytics->subscribersByPackage();
// [['package_id' => 1, 'package_name' => 'Pro', 'count' => 600], ...]

// Trial conversion rate (% of trials that became active)
$analytics->trialConversionRate();           // 72.50

// Subscription growth over time (chart data)
$analytics->subscriptionGrowth(months: 12);
// [['month' => '2025-01', 'count' => 85], ['month' => '2025-02', 'count' => 92], ...]

Revenue Metrics

// Monthly Recurring Revenue
$analytics->calculateMRR();                  // 28,560.00

// Average Revenue Per User
$analytics->averageRevenuePerUser();         // 29.14

// Lifetime total revenue
$analytics->totalRevenue();                  // 342,720.00

// Monthly revenue trend (chart data)
$analytics->revenueByPeriod(months: 12);
// [['month' => '2025-01', 'revenue' => 25430.00], ...]

// Revenue per package
$analytics->revenueByPackage();
// [['package_id' => 1, 'package_name' => 'Pro', 'revenue' => 180000.00], ...]

Invoice Metrics

// Pending invoices
$analytics->pendingInvoiceCount();           // 45

// Overdue invoices (pending + past due date)
$analytics->overdueInvoiceCount();           // 12

Churn Metrics

// Churn rate for last 30 days
$analytics->churnRate(days: 30);             // 4.25

// Churn trend over 12 months (chart data)
$analytics->churnTrend(months: 12, windowDays: 30);
// [['month' => '2025-01', 'churn_rate' => 3.80], ...]

Usage Analytics

// Daily usage for a feature over the last 30 days
$analytics->getDailyUsage($subscription, featureId: 1, days: 30);
// [['date' => '2025-02-01', 'total' => 245], ...]

Dashboard Summary

Get all KPIs in a single call:

$summary = Tashil::analytics()->dashboardSummary();

// Returns:
// [
//     'total_subscriptions'     => 1250,
//     'active_subscriptions'    => 980,
//     'subscriptions_by_status' => ['active' => 800, 'on_trial' => 180, ...],
//     'mrr'                     => 28560.00,
//     'arpu'                    => 29.14,
//     'total_revenue'           => 342720.00,
//     'churn_rate'              => 4.25,
//     'trial_conversion_rate'   => 72.50,
//     'pending_invoices'        => 45,
//     'overdue_invoices'        => 12,
//     'pending_invoices'        => 45,
//     'overdue_invoices'        => 12,
// ]

Per-Package Analytics

Get a detailed breakdown of metrics for each package:

$packageStats = Tashil::analytics()->packageAnalytics();

// Returns array of packages with stats:
// [
//     [
//         'package_id'            => 1,
//         'package_name'          => 'Pro Plan',
//         'total_subscribers'     => 150,
//         'active_subscribers'    => 120,
//         'mrr'                   => 3599.80,
//         'average_mrr'           => 29.99,
//         'trial_conversion_rate' => 75.00,
//         'cancelled_count'       => 10,
//         'pending_invoices'      => 5,
//         'overdue_invoices'      => 2,
//         'total_revenue'         => 45000.00,
//     ],
//     ...
// ]

HasSubscriptions Trait

Add subscription capabilities to any Eloquent model:

use Foysal50x\Tashil\Traits\HasSubscriptions;

class User extends Authenticatable
{
    use HasSubscriptions;
}

Available Methods

// Subscription management
$user->subscribe($package);
$user->subscribe($package, withTrial: true);
$user->cancelSubscription(immediate: false);
$user->resumeSubscription();
$user->switchPlan($newPackage);

// Status checks
$user->isSubscribed();                   // has any valid subscription
$user->isSubscribedTo($package);         // subscribed to specific package (model or slug)
$user->onPlan('pro');                    // alias for subscribedTo by slug
$user->isOnTrial();                      // currently on trial
$user->subscription();                   // get current valid subscription (always queries DB)
$user->loadSubscription();               // get cached subscription (avoids redundant queries)

// Feature access
$user->hasFeature('dark-mode');          // boolean feature check
$user->canUseFeature('api-calls');       // has access + within limits
$user->featureValue('api-calls');        // get raw feature value
$user->featureUsage('api-calls');        // current usage count
$user->featureRemaining('api-calls');    // remaining allowance
$user->useFeature('api-calls');          // increment and log usage
$user->dailyUsageFor('api-calls', 30);  // daily usage breakdown for last N days

// Invoices
$user->invoices();                       // invoices relationship
$user->allInvoices();                    // flattened collection of all invoices

// Cache management
$user->clearSubscriptionCache();         // force re-fetch on next access

Note

Performance: Methods like hasFeature(), featureValue(), featureUsage(), featureRemaining(), dailyUsageFor(), and useFeature() all use loadSubscription() internally, which caches the active subscription for the model's lifetime. This eliminates redundant queries when multiple methods are called on the same model instance. The cache is automatically cleared after subscribe(), cancelSubscription(), resumeSubscription(), and switchPlan().


Events

Tashil dispatches events that you can listen to in your application:

SubscriptionCreated

Fired when a new subscription is created.

use Foysal50x\Tashil\Events\SubscriptionCreated;

class HandleNewSubscription
{
    public function handle(SubscriptionCreated $event): void
    {
        $subscription = $event->subscription;
        // Send welcome email, provision resources, etc.
    }
}

UsageLimitWarning

Fired when feature usage crosses the 80% threshold.

use Foysal50x\Tashil\Events\UsageLimitWarning;

class HandleUsageWarning
{
    public function handle(UsageLimitWarning $event): void
    {
        $subscription = $event->subscription;
        $feature      = $event->feature;
        $usage        = $event->usage;   // current usage
        $limit        = $event->limit;   // maximum allowed

        // Notify user they're approaching their limit
    }
}

Caching Architecture

Tashil implements a decorator-based caching layer using the Repository pattern:

Service Layer
    └── CacheRepository (decorator)
            └── EloquentRepository (implementation)
                    └── Database

How It Works

  • Read operations are cached with configurable TTL
  • Write operations automatically invalidate related cache entries
  • The cache layer can be disabled entirely via config
  • Aggregate values (active count, MRR, etc.) are selectively cached

Cache Keys

Key Pattern Data
subscription:{id} Single subscription
subscription:{Model}:{id}:valid Subscriber's valid subscription
subscription:aggregate:active_count Active subscription count
subscription:aggregate:mrr Monthly Recurring Revenue
subscription:aggregate:total_count Total subscription count
subscription:aggregate:count_by_status Status breakdown
subscription:aggregate:by_package Subscribers per package
subscription:aggregate:revenue_by_package Revenue per package
subscription:aggregate:dashboard_stats Batched dashboard KPIs
invoice:aggregate:pending_count Pending invoice count
invoice:aggregate:total_revenue Total revenue

Disabling Cache

Set in config/tashil.php:

'cache' => [
    'enabled' => false,
],

Or in .env:

TASHIL_CACHE_ENABLED=false

API Reference

Tashil Facade

Tashil::subscription()  // → SubscriptionService
Tashil::usage()          // → UsageService
Tashil::analytics()      // → AnalyticsService
Tashil::billing()        // → BillingService
Tashil::feature($slug)   // → FeatureBuilder
Tashil::package($slug)   // → PackageBuilder

SubscriptionService

Method Return Description
subscribe(Model $subscriber, Package $package, bool $withTrial = false) Subscription Create subscription
cancel(Subscription $sub, bool $immediate = false, ?string $reason = null) Subscription Cancel subscription
resume(Subscription $sub) Subscription Resume cancelled subscription
switchPlan(Subscription $sub, Package $newPackage) Subscription Switch to different package

UsageService

Method Return Description
increment(Subscription $sub, string $featureSlug, float $amount = 1) bool Increment feature usage
check(Subscription $sub, string $featureSlug, float $amount = 1) bool Check if feature can be used
resetUsage(Subscription $sub, string $featureSlug) bool Reset single feature usage
resetAllUsage(Subscription $sub) void Reset all feature usage

BillingService

Method Return Description
generateInvoice(Subscription $sub, ?float $amount = null) Invoice Generate invoice

AnalyticsService

Method Return Description
dashboardSummary() array All-in-one KPI summary
packageAnalytics() array Detailed stats per package
calculateMRR() float Monthly Recurring Revenue
churnRate(int $days) float Churn percentage
trialConversionRate() float Trial conversion percentage
totalSubscriptionCount() int All subscriptions
activeSubscriptionCount() int Active + on-trial
subscriptionCountByStatus() array Count per status
subscribersByPackage() array Distribution per package
trialConversionRate() float Trial→active %
subscriptionGrowth(int $months = 12) array Monthly growth data
calculateMRR() float Monthly Recurring Revenue
averageRevenuePerUser() float ARPU
totalRevenue() float Lifetime revenue
revenueByPeriod(int $months = 12) array Monthly revenue trend
revenueByPackage() array Revenue per package
pendingInvoiceCount() int Pending invoices
overdueInvoiceCount() int Overdue invoices
churnRate(int $days = 30) float Churn %
churnTrend(int $months = 12, int $windowDays = 30) array Churn over time
getDailyUsage(Subscription $sub, int $featureId, int $days = 30) array Daily usage data
getDailyUsage(Subscription $sub, int $featureId, int $days = 30) array Daily usage data
dashboardSummary() array All KPIs in one call
packageAnalytics() array Detailed stats per package

FeatureBuilder

Method Return Description
name(string $name) self Set display name
description(string $desc) self Set description
boolean() self Set type to boolean
limit() self Set type to limit
consumable() self Set type to consumable
type(FeatureType $type) self Set type explicitly
active(bool $active = true) self Set active status
inactive() self Mark as inactive
sortOrder(int $order) self Set display order
metadata(array $data) self Attach metadata
create() Feature Persist to database
createOrUpdate() Feature Upsert by slug

PackageBuilder

Method Return Description
name(string $name) self Set display name
description(string $desc) self Set description
price(float $price) self Set price
originalPrice(float $price) self Set original/strike-through price
currency(string $currency) self Set currency
monthly() self Bill monthly
quarterly() self Bill quarterly
yearly() self Bill yearly
lifetime() self One-time payment
billingPeriod(Period $period, int $interval = 1) self Custom billing cycle
trialDays(int $days) self Set trial duration
featured(bool $featured = true) self Mark as featured
sortOrder(int $order) self Set display order
metadata(array $data) self Attach metadata
feature(Feature|int $feature, ...) self Attach single feature
features(array $features) self Attach multiple features
create() Package Persist to database
createOrUpdate() Package Upsert by slug

Eloquent Models

Subscription

Relationship Type Target
package() BelongsTo Package
items() HasMany SubscriptionItem
usageLogs() HasMany UsageLog
invoices() HasMany Invoice
Method Return Description
isActive() bool Status is Active
isOnTrial() bool Status is OnTrial
isCancelled() bool Status is Cancelled
isExpired() bool Status is Expired
isPastDue() bool Status is PastDue
isValid() bool Active or OnTrial

Package

Relationship Type Target
features() BelongsToMany Feature
subscriptions() HasMany Subscription
Scope Description
active() Only active packages
featured() Only featured packages
ordered() Ordered by sort_order

Invoice

Relationship Type Target
subscription() BelongsTo Subscription
transactions() HasMany Transaction
Method Description
markAsPaid() Set status to Paid
markAsVoid() Set status to Void

SubscriptionItem

Method Return Description
isOverLimit() bool Usage exceeds value
remainingUsage() float Value minus usage
usagePercentage() float Usage as % of value

Environment Variables

Variable Default Description
TASHIL_DB_CONNECTION null Database connection
TASHIL_CURRENCY USD Default currency
TASHIL_REDIS_HOST REDIS_HOST / 127.0.0.1 Redis host
TASHIL_REDIS_PASSWORD REDIS_PASSWORD / null Redis password
TASHIL_REDIS_PORT REDIS_PORT / 6379 Redis port
TASHIL_REDIS_DB 5 Redis database index
TASHIL_CACHE_PREFIX tashil_cache: Cache key prefix
TASHIL_CACHE_ENABLED true Enable/disable caching

Database Schema

Tashil creates the following tables (all names are configurable):

tashil_packages
tashil_features
tashil_package_feature      (pivot)
tashil_subscriptions
tashil_subscription_items
tashil_usage_logs
tashil_invoices
tashil_transactions

The subscriptions table uses a polymorphic subscriber_type / subscriber_id pattern, so any Eloquent model can be a subscriber.


Examples

For more detailed examples and usage scenarios, check the examples/ directory:

License

MIT

About

A comprehensive subscription management package for Laravel with built-in Redis caching, feature-gated access, usage tracking, billing, and analytics

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages