Laravel Stripe Payment using Cashier from Scratch
Hello,
In this post, we will learn laravel cashier stripe example. I explained simply about laravel cashier stripe subscription tutorial. I explained simply step by step stripe subscription example laravel. We will look at an example of laravel cashier subscription example. follow the below step for laravel cashier stripe tutorial.
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:
Step 1: Install Laravel
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-app
Step 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.
.env
DB_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_Password
Step 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 build
Step 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 migrate
Step 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 website
After 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:
.env
STRIPE_KEY=pk_test_MRzwmMVtDyyp1r1q79LGjJ
STRIPE_SECRET=sk_test_eKrHzLozoU4PTjCwhIPdr
Step 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>
@endsection
resources/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>
@endsection
resources/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>
@endsection
Step 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 website
So, 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=PlanSeeder
Run 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/plans
Output: 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...
Hardik Savani
I'm a full-stack developer, entrepreneur and owner of ItSolutionstuff.com. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Laravel, Angular, Vue, Node, Javascript, JQuery, Codeigniter and Bootstrap from the early stage. I believe in Hardworking and Consistency.
We are Recommending you
- Laravel 10 Stripe Payment Gateway Integration Tutorial
- Laravel 9 Livewire Form Submit Example
- Laravel Google Bar Chart Example Tutorial
- Laravel Eloquent doesntHave() Condition Example
- How to Add Country List in Laravel?
- Laravel Custom Email Verification System Example
- Laravel Razorpay Payment Gateway Example
- How to Send SMS using Twilio in Laravel?
- Laravel Eloquent Delete Record By ID Example
- Laravel Livewire CRUD Application Tutorial
- How to Integrate Stripe Payment Gateway in Laravel?
- Paytm payment gateway integration example in Laravel 5