Laravel Soulbscription

repository·main·Indexed 20 days ago

https://github.com/lucasdotvin/laravel-soulbscription

A Laravel package providing an interface for managing user subscriptions and tracking the consumption of specific features. It supports consumable, non-consumable, postpaid, and quota-based features, as well as periodic or permanent plans with grace periods. Key functionality includes plan switching, subscription lifecycle management (renew, cancel, suppress), and Feature Tickets for pre-paid charges.

Tokens
6.5K
Snippets
29
Records
29
Agent score
72%

What's inside laravel-soulbscription

  1. Upgrade Soulbsubscription to version 2.x

    main

    If you are upgrading an existing installation to version 2.x, you must publish and run the specific upgrade migrations to ensure your database schema is updated correctly:

    php artisan vendor:publish --tag="soulbscription-migrations-upgrades-1.x-2.x"
    php artisan migrate
  2. Associate features with plans

    main

    Use the features() relationship on a Plan instance to attach features. When attaching a consumable feature, you must provide the charges value in the pivot data to define how many units the plan grants.

    $deployMinutes = Feature::whereName('deploy-minutes')->first();
    $subdomains    = Feature::whereName('subdomains')->first();
    
    // Silver plan gets 15 minutes
    $silver->features()->attach($deployMinutes, ['charges' => 15]);
    
    // Gold plan gets 25 minutes and subdomain access
    $gold->features()->attach($deployMinutes, ['charges' => 25]);
    $gold->features()->attach($subdomains);
  3. Define and configure features

    main

    Features are the individual capabilities or limits offered to users. You can create them using the Feature model with several configuration options:

    • Consumable Features: Set consumable => true. These have a limited number of uses or amounts. You can define periodicity_type (e.g., PeriodicityType::Day) and periodicity (e.g., 1) to make them renew automatically.
    • Non-Consumable Features: Set consumable => false. These simply grant access to a capability (e.g., custom-domain).
    • Postpaid Features: Set postpaid => true. Users can use these even if they don't have enough charges, allowing you to bill them later.
    • Quota Features: Set quota => true. These represent a constant value (like disk storage) that you manually sync using setConsumedQuota().
    // Consumable, renewing daily
    $deployMinutes = Feature::create([
        'consumable'       => true,
        'name'             => 'deploy-minutes',
        'periodicity_type' => PeriodicityType::Day,
        'periodicity'      => 1,
    ]);
    
    // Non-consumable
    $customDomain = Feature::create([
        'consumable' => false,
        'name'       => 'custom-domain',
    ]);
    
    // Postpaid
    $cpuUsage = Feature::create([
        'consumable' => true,
        'postpaid'   => true,
        'name'       => 'cpu-usage',
    ]);
    
    // Quota
    $storage = Feature::create([
        'consumable' => true,
        'quota'      => true,
        'name'       => 'storage',
    ]);
  4. Use Feature Tickets for pre-paid charges

    main

    Feature Tickets allow users to acquire extra charges for a feature independently of their subscription. This can be used for one-off purchases or building a pre-paid service.

    Setup:

    1. Publish config: php artisan vendor:publish --tag="soulbscription-config".
    2. In soulbscription.php, set 'feature_tickets' => true.

    Usage:

    • giveTicketFor(string $featureName, ?DateTimeInterface $expiration, ?float $charges): Grants the user a ticket.
      • If $expiration is null, the ticket never expires.
      • For non-consumable features, the ticket grants temporary access for the specified duration.

    Note: Remember to manually remove tickets when a user cancels their subscription if you want to prevent them from consuming charges forever.

    // Grant 10 minutes of deploy time expiring in one month
    $subscriber->giveTicketFor('deploy-minutes', today()->addMonth(), 10);
    
    // Grant a non-expiring ticket
    $subscriber->giveTicketFor('deploy-minutes', null, 10);
    
    // Grant temporary access to a non-consumable feature
    $user->giveTicketFor($featureName, $expiration);
  5. Create and configure subscription plans

    main

    Plans define the subscription terms. Use the Plan model to create them:

    • Periodic Plans: Define periodicity_type and periodicity (e.g., Monthly).
    • Permanent/Free Plans: Set periodicity_type and periodicity to null.
    • Grace Days: Set grace_days to allow users to retain access for a specific number of days after their plan expires before access is suspended.
    // Monthly plan with 7 days grace period
    $gold = Plan::create([
        'name'             => 'gold',
        'periodicity_type' => PeriodicityType::Month,
        'periodicity'      => 1,
        'grace_days'       => 7,
    ]);
    
    // Permanent/Free plan
    $free = Plan::create([
        'name'             => 'free',
        'periodicity_type' => null,
        'periodicity'      => null,
    ]);
  6. Publish Soulbscription configuration and migrations

    main

    You can publish the package's configuration file and database migrations to your application's directories using the Artisan vendor:publish command. This allows you to customize the package behavior and manage your database schema.

    Use the following tags to publish specific assets:

    • soulbscription-config: Publishes the soulbscription.php configuration file to config/soulbscription.php.
    • soulbsubscription-migrations: Publishes the base migrations to your database/migrations directory.
    • soulbsubscription-migrations-upgrades-1.x-2.x: Publishes upgrade migrations for version 1.x to 2.x.
    • soulbsubscription-migrations-upgrades-2.1-2.2: Publishes upgrade migrations for version 2.1 to 2.2.
    • soulbsubscription-migrations-upgrades-2.4-2.5: Publishes upgrade migrations for version 2.4 to 2.5.
    • soulbsubscription-migrations-upgrades-2.5-2.6: Publishes upgrade migrations for version 2.5 to 2.6.
    • soulbsubscription-migrations-upgrades-4.0-4.1: Publishes upgrade migrations for version 4.0 to 4.1.
    # Publish configuration
    php artisan vendor:publish --tag=soulbscription-config
    
    # Publish base migrations
    php artisan vendor:publish --tag=soulbsubscription-migrations
    
    # Publish specific upgrade migrations (example)
    php artisan vendor:publish --tag=soulbsubscription-migrations-upgrades-4.0-4.1
  7. Run Composer and PHP via Docker Compose

    main

    The project provides a docker-compose.yml file to facilitate development using Docker. You can use the defined services to run Composer commands or PHP scripts within a containerized environment that mirrors the project's requirements.

    Services

    • composer: A service using the composer/composer image. It is configured to run composer install by default and mounts the current directory to /app inside the container.
    • php: A service built from the local Dockerfile located at .docker/php/Dockerfile. It mounts the current directory to /app and uses php as the entrypoint.
    # Example: Install dependencies using the composer service
    docker-compose run --rm composer
    
    # Example: Run a PHP command (e.g., artisan) using the php service
    docker-compose run --rm php artisan migrate
  8. Manage quota consumption

    main

    For features marked as quota => true, use the setConsumedQuota() method on the subscriber to reflect the current state of the resource (e.g., total disk space used).

    // Example: Updating storage quota in a controller
    $usedSpace = collect(Storage::allFiles($userFolder))
        ->map(fn (string $subFile) => Storage::size($subFile))
        ->sum();
    
    auth()->user()->setConsumedQuota('storage', $usedSpace);
  9. Switch plans

    main

    Use the switchTo() method to change a user's current plan.

    • Immediate Switch: Calling $user->switchTo($newPlan) suppresses the current subscription and starts the new one immediately. This fires a SubscriptionStarted event.
    • Scheduled Switch: Calling $user->switchTo($newPlan, immediately: false) keeps the current plan active until its expiration, then starts the new one. This fires a SubscriptionScheduled event.
    // Switch immediately
    $student->switchTo($newPlan);
    
    // Switch at the end of the current period
    $user->switchTo($primeYearly, immediately: false);