If you’ve ever built out team management and a billing system then you already know how time consuming and painful this process is. There is so much tedious work hooking up all the different systems, designing it, creating invoices, and on and on. And thats where the SPARK comes in picture and make the job easy. Spark’s goal is to be an opinionated way of building out business oriented SaaS applications. It features team management, user roles, recurring billing through Stripe, Braintree and much more.
One of the feature that spark provides is define your billing plans in app/Providers/SparkServiceProvider.
Of course, this service provider is automatically generated when you create a new Spark project. Within the service provider’s booted
method, you will find a sample plan already defined. The default Spark application defines a “no card up front” trial plan, which will allow new users to sign up for your application without providing their billing details during their initial registration.
You may modify this plan and define additional plans as needed. The first argument given to the plan
method is the displayable name of the plan while the second argument is the plan’s ID on either Stripe or Braintree:
Spark::plan('Pro', 'monthly-pro')
->price(20)
->features([
'Feature 1',
'Feature 2',
'Feature 3',
]);
The features
method accepts an array of features provided by a given plan. These features will be displayed when a user clicks the “Plan Features” modal on the registration or settings views.
If you would like to define a plan that has a yearly billing frequency, you may use the yearly
method:
Spark::plan('Pro', 'yearly-pro')
->price(100)
->yearly()
->features([
'Feature 1',
'Feature 2',
'Feature 3',
]);
The problem with this approach is that you have to change code every time you add new billing plans or promotional plans. Definitely we would need a feature where you should be able to add price plan dynamically. There is no provision in spark for same. So following is the way I have figured out to deal with it.
Create Migration and Table for Dynamic Plans
Schema::create('dynamic_plans', function (Blueprint $table) {
$table->increments('id');
$table->string('plan_id');
$table->string('plan_name');
$table->string('plan_description');
$table->double('amount')->default(0.00);
$table->integer('trial_days')->nullable()->default(null);
$table->string('period');
$table->string('features')->nullable()->default(null);
$table->timestamps();
}); This table will hold all dynamic plans and required features to define a dynamic plan in SPARK.
Create CRUD for dynamic_plans table
Create CRUD to add/edit/archieve entries into dynamic_plans table.
Define dynamic plans in SparkServiceProvider
<?php
namespace App\Providers;
use Laravel\Spark\Spark;
use Laravel\Spark\Providers\AppServiceProvider as ServiceProvider;
use App\DynamicPlan;
class SparkServiceProvider extends ServiceProvider
{
/**
* Your application and company details.
*
* @var array
*/
protected $details = [
‘vendor’ => ‘Company Name’,
‘product’ => ‘Product 1’,
‘street’ => ’Address’,
‘location’ => ‘location’,
‘phone’ => ‘+91 999999999’,
];
/**
* The address where customer support e-mails should be sent.
*
* @var string
*/
protected $sendSupportEmailsTo = null;
/**
* All of the application developer e-mail addresses.
*
* @var array
*/
protected $developers = [
//
];
/**
* Indicates if the application will expose an API.
*
* @var bool
*/
protected $usesApi = true;
/**
* Finish configuring Spark for the application.
*
* @return void
*/
public function booted()
{
// Spark::useStripe()->noCardUpFront()->trialDays(10);
Spark::useStripe();
$plans = DynamicPlan::all();
foreach ($plans as $plan)
{
$sparkPlan = Spark::plan($plan->plan_name, $plan->plan_id)
->price($plan->amount);
if(!empty($plan->trial_days))
{
$sparkPlan->trialDays($plan->trial_days);
}
$sparkPlan->features(explode(‘,’, $plan->features));
$sparkPlan->interval = $plan->period;
}
}
}
So as soon as you make entries in dynamic_plans table, the said plan will be available.
Enjoy Coding!!