npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

laravel-spark-addons

v0.0.2

Published

Grow your revenue by offering multiple add-on subscriptions in your Laravel Spark app.

Downloads

3

Readme

Spark Addons

Grow your revenue by offering multiple add-on subscriptions in your Laravel Spark app.

  • Define "add-on" subscriptions
  • Supported metered (pay as you go) and licensed (monthly fee) usage types
  • Support multiple plans for each add-on
  • Allow users to subscribe and cancel their subscription to an add-on plan
  • Implemented in a similar style to existing Spark functionality

Installation

  1. Include the package
composer require benmag/laravel-spark-addons
  1. Publish and run the migrations
php artisan vendor:publish --tag=spark-addons-migrations && php artisan migrate
  1. Update change your Spark class in config/app.php
[
    'aliases' => [
        'Spark' => \Benmag\SparkAddons\Spark::class,
    ]
]
  1. Switch the use Laravel\Spark\Spark; class in SparkServiceProvider to use Benmag\SparkAddons\Spark;

  2. Add the BillableAddonSubscriptions trait to your Team model

namespace App;

use Laravel\Spark\Team as SparkTeam;
use Benmag\SparkAddons\Traits\BillableAddonSubscriptions;

class Team extends SparkTeam
{
    use BillableAddonSubscriptions; 
    //...
}
  1. Ensure the Vue components for spark-addons get built by adding
require("./../../../vendor/benmag/laravel-spark-addons/resources/assets/js/bootstrap");

To your resources/assets/js/components/bootstrap.js file.

  1. Add your spark-addons config to your global Spark object in your layout file (resources/views/vendor/spark/layouts/app.blade.php)
<!-- Global Spark Object -->
<script>
    window.Spark = <?php echo json_encode(array_merge(
        Spark::scriptVariables(), [
            'spark-addons' => config('spark-addons')
        ]
    )); ?>
</script>
  1. Show current add-on subscriptions in the subscriptions page by adding:
<addon-subscriptions
    :user="user"
    :team="team"
    :billable-type="billableType">
</addon-subscriptions>

To the views/vendor/spark/settings/subscription.blade.php view

  1. Configure your add-on subscriptions! (See the Usage section below)

Usage

You can now define available add-on plans in a similar style to how you define your Spark plans inside your SparkServiceProvider.

// SocketCluster
Spark::addon(new \Benmag\SparkAddons\Addon([
    'id' => 'socketcluster',
    'name' => 'SocketCluster',
    'description' => "A scalable framework for real-time apps and services.",
]));

// SocketCluster - Plan: Hobby
Spark::addonPlan('socketcluster', 'Hobby', 'socketcluster:hobby')
    ->price(19)
    ->trialDays(15)
    ->features([
        "Powered by 512mb RAM",
        "No complicated setup",
        "Email support"
    ])
    ->attributes([
        'description' => "Single 512mb SocketCluster instance, perfect for development",
    ]);
    
    
// Servers
Spark::addon(new \Benmag\SparkAddons\Addon([
    'id' => 'servers',
    'name' => 'Servers',
    'description' => "High performance cloud servers provisioned for you.",
]));

// Servers: Standard 1X
Spark::addonPlan('servers', 'Standard 1X', 'servers:standard-1x')
    ->usageType('metered')
    ->price(0.10)
    ->features([
        '512MB RAM',
        '1 Core Processor',
        '20GB SSD Disk',
        '1TB Transfer'
    ])
    ->attributes([
        'description' => "512MB RAM. Perfect server to power hobby and small apps.",
    ]);
    
// 

Configuration

Publish config

php artisan vendor:publish --tag=spark-addons-config

Publish assets

php artisan vendor:publish --tag=spark-addons-assets

Publish views

php artisan vendor:publish --tag=spark-addons-views

Metered Billing

Metered billing or usage based billing allows you to charge your customer an amount based on what they have actually consumed by taking advantage of Stripe's metered billing.

For example, at Codemason, our users can use Codemason Servers to run their apps. These servers are billed by the hour at the corresponding rate and can be cancelled at any time. At the end of the month, the customer is billed for the amount of hours they have accumulated.

By default metered add-on plans are measuring usage by the hour. However, it's easy to swap this implementation out for your own, just as you would for any other Spark interaction with the Spark::swap technique.

The behind the scenes of how this works is fairly simple: at the end of the billing cylce, Stripe fires a invoice.created webhook approximately an hour before the invoice is finalised and a charge is attempted. When your app receives that webhook, it calculates the number of hours the add-on has been active for and updates Stripe with the usage.

To make use of this functionality, you will make some additional configurations. Don't worry, it's still very easy and very straight forward.

Override the default Stripe Webhook (required)

The main thing we will need to do is make sure that the SparkAddonsServiceProvider is being manually registered after the SparkServiceProvider. This is to ensure that we're using our new controller that listens for the invoice.created webhook to perform usage calculations at the end of the month.

Disable auto-discovery so we can override the existing spark/webhook that Laravel Spark provides

Do this by adding the following to your composer.json file:

"extra": {
    "laravel": {
        "dont-discover": [
            "laravel/dusk",
            "benmag/laravel-spark-addons"
        ]
    }
},

Manually register the SparkAddonsServiceProvider after the SparkServiceProvider in the providers array in config/app.php

'providers' => [
    Laravel\Spark\Providers\SparkServiceProvider::class,
    App\Providers\SparkServiceProvider::class,
    Benmag\SparkAddons\SparkAddonsServiceProvider::class,
    // ...
]

Interactions

These are the interactions, you are able to override them with your own custom implementations where required using Spark::swap

|Interaction |Description | |---------------------------|----------------------------------------------------------------------------------------------------------------------------| |CalculateMeteredUsage |Calculate the hour based usage for the add-on subscription. | |RecordUsageUsingStripe |Records the usage on Stripe | |SubscribeAddon |Adds a new add-on subscription to a owner | |SubscribeTeamAddon |Adds a new add-on subscription to a owner | |CancelAddonSubscription |Cancels an add-on subscription. If the add-on subscription is license based, it will reduce the subscription quantity | |CancelTeamAddonSubscription|Cancels an add-on subscription. If the add-on subscription is license based, it will reduce the subscription quantity | |ResumeAddonSubscription |Resume a cancelled add-on subscription (only available if the add-on subscription is license based and in the grace period) | |ResumeTeamAddonSubscription|Resume a cancelled add-on subscription (only available if the add-on subscription is license based and in the grace period) |

Example

We use this approach at Codemason to manage the subscriptions for our add-ons. Codemason is an end-to-end cloud platform and with Codemason Add-on’s, users are able to launch production-grade apps with a click.

SocketCluster Add-on

About Codemason

We ❤️ Laravel Spark. We used Laravel Spark for Codemason so we could focus on building functionality our users loved, instead of writing boilerplate code. Codemason is the Laravel Spark of servers/hosting

Working on a Laravel Spark project? People who use Spark know how important their time is. Save yourself hours of fighting with servers by using Codemason.

Don't forget to use the coupon SPARK-3-FREE to get 3 months free access!