Learn how to integrate Razorpay payment gateway in Laravel with a step-by-step guide. Includes migration, controller setup, payment processing, and success handling with Bootstrap UI.
If you haven’t already set up a Laravel project, install Laravel using Composer:
composer create-project --prefer-dist laravel/laravel razorpay-integration
Navigate to the project directory:
cd razorpay-integration
Install the Razorpay PHP SDK:
composer require razorpay/razorpay
.env
file:
RAZORPAY_KEY=your_key_here
RAZORPAY_SECRET=your_secret_here
Generate the migration file:
php artisan make:migration create_payments_table
Edit the generated file in:
database/migrations/xxxx_xx_xx_xxxxxx_create_payments_table.php
:
public function up()
{
Schema::create('payments', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email');
$table->string('phone');
$table->decimal('amount', 10, 2);
$table->string('razorpay_payment_id')->nullable();
$table->string('order_id')->nullable();
$table->boolean('status')->default(0); // 0 = Pending, 1 = Success
$table->timestamps();
});
}
Run the migration:
php artisan migrate
Run the following command:
php artisan make:model Payment
Edit app/Models/Payment.php
:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Payment extends Model
{
use HasFactory;
protected $fillable = ['name', 'email', 'phone', 'amount', 'order_id', 'razorpay_payment_id', 'status'];
}
php artisan make:controller RazorpayController
Edit app/Http/Controllers/RazorpayController.php
:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Razorpay\Api\Api;
use App\Models\Payment;
class RazorpayController extends Controller
{
public function index()
{
return view('razorpay.index');
}
public function payment(Request $request)
{
$request->validate([
'name' => 'required|string',
'email' => 'required|email',
'phone' => 'required',
'amount' => 'required|numeric|min:1',
]);
$api = new Api(env('RAZORPAY_KEY'), env('RAZORPAY_SECRET'));
$order = $api->order->create([
'receipt' => 'order_' . uniqid(),
'amount' => $request->amount * 100, // Convert to paise
'currency' => 'INR',
'payment_capture' => 1
]);
$payment = Payment::create([
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone,
'amount' => $request->amount,
'order_id' => $order['id'],
'status' => 0
]);
return view('razorpay.payment', [
'orderId' => $order['id'],
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone,
'amount' => $request->amount,
'razorpayKey' => env('RAZORPAY_KEY'),
]);
}
public function success(Request $request)
{
if (!$request->razorpay_payment_id || !$request->razorpay_order_id) {
return back()->with('error', 'Payment failed. Please try again.');
}
$payment = Payment::where('order_id', $request->razorpay_order_id)->first();
if (!$payment) {
return back()->with('error', 'Invalid payment record.');
}
$payment->update([
'razorpay_payment_id' => $request->razorpay_payment_id,
'status' => 1 // Mark as successful
]);
return redirect('/razorpay')->with([
'success' => 'Payment Successful!',
'payment' => $payment
]);
}
}
Edit routes/web.php
:
use App\Http\Controllers\RazorpayController;
Route::get('/razorpay', [RazorpayController::class, 'index']);
Route::post('/razorpay/payment', [RazorpayController::class, 'payment'])->name('razorpay.payment');
Route::post('/razorpay/success', [RazorpayController::class, 'success'])->name('razorpay.success');
resources/views/razorpay/index.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Razorpay Payment</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>
<body class="container mt-5">
@if (session('success'))
<div class="alert alert-success alert-dismissible fade show" role="alert">
<strong>Success!</strong> {{ session('success') }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endif
@if (session('payment'))
<div class="card mt-3">
<div class="card-header bg-success text-white">
<h5 class="mb-0">Payment Details</h5>
</div>
<div class="card-body">
<p><strong>Payment ID:</strong> {{ session('payment')->razorpay_payment_id }}</p>
<p><strong>Amount:</strong> ₹{{ session('payment')->amount }}</p>
</div>
</div>
@endif
<h2>Razorpay Payment Integration</h2>
<form action="{{ route('razorpay.payment') }}" method="POST">
@csrf
<div class="mb-3">
<label for="name" class="form-label">Full Name</label>
<input type="text" name="name" class="form-control" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email Address</label>
<input type="email" name="email" class="form-control" required>
</div>
<div class="mb-3">
<label for="phone" class="form-label">Phone Number</label>
<input type="text" name="phone" class="form-control" required>
</div>
<div class="mb-3">
<label for="amount" class="form-label">Amount (INR)</label>
<input type="number" name="amount" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Proceed to Pay</button>
</form>
</body>
</html>
resources/views/razorpay/payment.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Complete Payment</title>
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
</head>
<body onload="startPayment()">
<h3 style="text-align: center">Processing Payment...</h3>
<form name="razorpayForm" action="{{ route('razorpay.success') }}" method="POST">
@csrf
<input type="hidden" name="razorpay_payment_id" id="razorpay_payment_id">
<input type="hidden" name="razorpay_order_id" id="razorpay_order_id">
<input type="hidden" name="razorpay_signature" id="razorpay_signature">
</form>
<script>
function startPayment() {
var options = {
"key": "{{ $razorpayKey }}",
"amount": "{{ $amount * 100 }}",
"currency": "INR",
"name": "{{ $name }}",
"description": "Test Transaction",
"order_id": "{{ $orderId }}",
"handler": function (response){
document.getElementById('razorpay_payment_id').value = response.razorpay_payment_id;
document.getElementById('razorpay_order_id').value = response.razorpay_order_id;
document.forms['razorpayForm'].submit();
},
"prefill": {
"name": "{{ $name }}",
"email": "{{ $email }}",
"contact": "{{ $phone }}"
},
"theme": {
"color": "#3399cc"
}
};
var rzp = new Razorpay(options);
rzp.open();
}
</script>
</body>
</html>
You have successfully integrated Razorpay with Laravel! 🎉