Laravel Cashier Stripe Subscription Example
Aug 29, 2022 . Admin
Hello Friends,
Hello all! In this article, we will talk about laravel cashier stripe subscription example. In this article, we will implement a laravel cashier subscription example. step by step explain stripe subscription example laravel. This post will give you simple example of laravel cashier stripe tutorial. So, let's follow few step to create example of laravel cashier stripe example.
You can use this example with laravel 6, laravel 7, laravel 8 and laravel 9 versions.
Whenever we want to develop our own product in IT fields, then we are looking for a subscription-based product. so, we don't have to worry about getting money. It will automatically charge every month or based on the plan. So, if you are working on a laravel project and you need to add a subscription plan to it. Then laravel provides a Cashier package to add these functions. You can create a stripe plan and the user can select a plan, based on the plan stripe will charge automatically. I will give you step by step example here.
In this example, I will show you step-by-step how to implement a stripe subscription using laravel cashier. In this example, we will create Basic and Premium two plans with it's price. The user can choose one of that two plans. based on the plan user will get features. You can see the below preview as well. So let's see the below steps and get it done with your app.
Preview:This is optional; however, if you have not created the laravel app, then you may go ahead and execute the below command:
composer create-project laravel/laravel example-appStep 2: Setup Database Configuration
After successfully installing the laravel app then after configuring the database setup. We will open the ".env" file and change the database name, username and password in the env file.
.envDB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=Enter_Your_Database_Name DB_USERNAME=Enter_Your_Database_Username DB_PASSWORD=Enter_Your_Database_PasswordStep 3: Install Auth Scaffold
Laravel's laravel/ui package provides a quick way to scaffold all of the routes and views you need for authentication using a few simple commands:
composer require laravel/ui
Next, we need to generate auth scaffold with bootstrap, so let's run the below command:
php artisan ui bootstrap --auth
Then, install npm packages using the below command:
npm install
At last, built bootstrap CSS using the below command:
npm run buildStep 4: Install Cashier Package
In this step, we will install laravel/cashier that way we can use stripe API and methods to create subscriptions. so let's run the below command:
composer require laravel/cashier
Next, we need to publish cashier migration for creating tables, so let's run the below command:
php artisan vendor:publish --tag="cashier-migrations"
Then, run the migration command to create a table using the below command:
php artisan migrateStep 5: Create Stripe Account & Get Stripe API Key and SECRET
This step is a very important step, if you don't have a stripe account then you need to create and if you have then proceeded to get Stripe Key and Secret. So, Let's open below stripe official website using the below link:
1) Open Stripe official websiteAfter login, You need to go on Developers tab and get API keys as like below:
Just, saved that Key and Secret we will use in .env file.
Next, you need to go on Products tab and create following two plans:
1) Basic
2) Premium
You must have to copy Plan ID, that we will store in plans table with seeder.
You can see below screenshot:
Now, just add Stripe Key and Secret add on .env file as below:
.envSTRIPE_KEY=pk_test_MRzwmMVtDyyp1r1q79LGjJ STRIPE_SECRET=sk_test_eKrHzLozoU4PTjCwhIPdrStep 6: Configure Cashier
In this step, we will use cashier Laravel\Cashier\Billable class in User model, so let's add it below:
app/Models/User.php<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Laravel\Sanctum\HasApiTokens; use Laravel\Cashier\Billable; class User extends Authenticatable { use HasApiTokens, HasFactory, Notifiable, Billable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for serialization. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ]; }Step 7: Create Migration and Model for Plan
Here, we have to create migration for "plans" table using Laravel php artisan command, so first fire bellow command:
php artisan make:migration create_plans_table
After this command you will find one file in the following path "database/migrations" and you have to put the below code in your migration file to create a plans table.
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('plans', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('slug'); $table->string('stripe_plan'); $table->integer('price'); $table->string('description'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('plans'); } };
Now you have to run this migration by the following command:
php artisan migrate
In this step, we will create Plan.php model. let's copy the below code and paste it.
app/Models/Plan.php<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Plan extends Model { use HasFactory; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'slug', 'stripe_plan', 'price', 'description', ]; /** * Write code on Method * * @return response() */ public function getRouteKeyName() { return 'slug'; } }Step 8: Create Routes
In this step, we will create three routes for plans, plans show and subscription buy. So, let's add a new route to that file.
routes/web.php<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\PlanController; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home'); Route::middleware("auth")->group(function () { Route::get('plans', [PlanController::class, 'index']); Route::get('plans/{plan}', [PlanController::class, 'show'])->name("plans.show"); Route::post('subscription', [PlanController::class, 'subscription'])->name("subscription.create"); });Step 9: Create Controller File
in the next step, now we have created a new controller as PlanController and write three methods on it like as below, So let's create a controller:
app/Http/Controllers/PlanController.php<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Plan; class PlanController extends Controller { /** * Write code on Method * * @return response() */ public function index() { $plans = Plan::get(); return view("plans", compact("plans")); } /** * Write code on Method * * @return response() */ public function show(Plan $plan, Request $request) { $intent = auth()->user()->createSetupIntent(); return view("subscription", compact("plan", "intent")); } /** * Write code on Method * * @return response() */ public function subscription(Request $request) { $plan = Plan::find($request->plan); $subscription = $request->user()->newSubscription($request->plan, $plan->stripe_plan) ->create($request->token); return view("subscription_success"); } }Step 10: Create Blade File
In this step, we need to create three blade file with plans.blade.php, subscription.blade.php and subscription_success.blade.php, so let's update following code on it:
resources/views/plans.blade.php@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header">Select Plane:</div> <div class="card-body"> <div class="row"> @foreach($plans as $plan) <div class="col-md-6"> <div class="card mb-3"> <div class="card-header"> ${{ $plan->price }}/Mo </div> <div class="card-body"> <h5 class="card-title">{{ $plan->name }}</h5> <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p> <a href="{{ route('plans.show', $plan->slug) }}" class="btn btn-primary pull-right">Choose</a> </div> </div> </div> @endforeach </div> </div> </div> </div> </div> </div> @endsectionresources/views/subscription.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-header"> You will be charged ${{ number_format($plan->price, 2) }} for {{ $plan->name }} Plan </div> <div class="card-body"> <form id="payment-form" action="{{ route('subscription.create') }}" method="POST"> @csrf <input type="hidden" name="plan" id="plan" value="{{ $plan->id }}"> <div class="row"> <div class="col-xl-4 col-lg-4"> <div class="form-group"> <label for="">Name</label> <input type="text" name="name" id="card-holder-name" class="form-control" value="" placeholder="Name on the card"> </div> </div> </div> <div class="row"> <div class="col-xl-4 col-lg-4"> <div class="form-group"> <label for="">Card details</label> <div id="card-element"></div> </div> </div> <div class="col-xl-12 col-lg-12"> <hr> <button type="submit" class="btn btn-primary" id="card-button" data-secret="{{ $intent->client_secret }}">Purchase</button> </div> </div> </form> </div> </div> </div> </div> </div> <script src="https://js.stripe.com/v3/"></script> <script> const stripe = Stripe('{{ env('STRIPE_KEY') }}') const elements = stripe.elements() const cardElement = elements.create('card') cardElement.mount('#card-element') const form = document.getElementById('payment-form') const cardBtn = document.getElementById('card-button') const cardHolderName = document.getElementById('card-holder-name') form.addEventListener('submit', async (e) => { e.preventDefault() cardBtn.disabled = true const { setupIntent, error } = await stripe.confirmCardSetup( cardBtn.dataset.secret, { payment_method: { card: cardElement, billing_details: { name: cardHolderName.value } } } ) if(error) { cardBtn.disable = false } else { let token = document.createElement('input') token.setAttribute('type', 'hidden') token.setAttribute('name', 'token') token.setAttribute('value', setupIntent.payment_method) form.appendChild(token) form.submit(); } }) </script> @endsectionresources/views/subscription_success.blade.php
@extends('layouts.app') @section('content') <div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card"> <div class="card-body"> <div class="alert alert-success"> Subscription purchase successfully! </div> </div> </div> </div> </div> </div> @endsectionStep 11: Create Seeder For Plans
In this step, we will create seeder for creating Basic and Premium plans.
Make sure you have to copy your plan ID from stripe websiteSo, create seeder using bellow command:
php artisan make:seeder PlanSeeder
And put bellow code in PlanSeeder seeder this way:
database/seeders/PlanSeeder.php<?php namespace Database\Seeders; use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Database\Seeder; use App\Models\Plan; class PlanSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { $plans = [ [ 'name' => 'Basic', 'slug' => 'basic', 'stripe_plan' => 'price_1LXOzsGzlk2XAanfTskz9n', 'price' => 10, 'description' => 'Basic' ], [ 'name' => 'Premium', 'slug' => 'premium', 'stripe_plan' => 'price_1LXP23Gzlk2XAanf4zQZdi', 'price' => 100, 'description' => 'Premium' ] ]; foreach ($plans as $plan) { Plan::create($plan); } } }
After this we have to run bellow command for run PermissionTableSeeder seeder:
php artisan db:seed --class=PlanSeederRun Laravel App:
All the required steps have been done, now you have to type the given below command and hit enter to run the Laravel app:
php artisan serve
Now, Go to your web browser, type the given URL and view the app output:
http://localhost:8000/login
After, login you need to go on following path:
http://localhost:8000/plansOutput: Plan List Output: Purchase Plan Output: Purchase Plan Successfully
Now you can check with following card details:
Name: Test Number: 4242 4242 4242 4242 CSV: 123 Expiration Month: 12 Expiration Year: 2028
I hope it can help you...