Get Appointment

Blog Single

Laravel Cashfree Payment Gateway Integration Guide

  • Vfix Technology
  • 11 Apr 2025
  • Laravel
  • 519 Views

Learn how to integrate Cashfree payment gateway in Laravel with a step-by-step guide. Includes migration, controller setup, payment processing, and success handling with Bootstrap UI.
 

Step 1: Install Laravel

If you haven’t already set up a Laravel project, install Laravel using Composer:
 

composer create-project --prefer-dist laravel/laravel cashfree-laravel

Navigate to the project directory:

cd cashfree-laravel

Step 3: Configure Cashfree API Keys from: https://www.cashfree.com
Get your API keys from Dashboard. Add them to your .env file:

 

CASHFREE_API_KEY=*****************
CASHFREE_API_SECRET=*********************
CASHFREE_ENV=sandbox # or production

Step 4: Create the Payments Migration:

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('payment_id')->nullable();
        $table->string('order_id')->nullable();
        $table->boolean('status')->default(0); // 0 = Pending, 1 = Success
        $table->json('other')->nullable();
        $table->timestamps();
    });
}

Run the migration:

php artisan migrate

Step 5: Create the Payment Model

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', 'payment_id', 'status','other'];

    protected $casts = [
        'other' => 'array'
    ];
}

Step 6: Create the Cashfree Controller:

php artisan make:controller CashfreeController

Edit app/Http/Controllers/CashfreeController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Payment;

class CashfreeController extends Controller
{
    public function index()
    {
        return view('cashfree.index');
    }

    public function payment(Request $request)
    {
        $request->validate([
            'name' => 'required|string',
            'email' => 'required|email',
            'phone' => 'required|digits:10',
            'amount' => 'required|numeric|min:1',
        ]);

        // Generate unique order IDs
        $orderId = 'order_'.rand(1111111111, 9999999999);
        $customerId = 'customer_'.rand(111111111, 999999999);

        $url = env('CASHFREE_ENV') === 'sandbox'
            ? "https://sandbox.cashfree.com/pg/orders"
            : "https://api.cashfree.com/pg/orders";

        $headers = [
            "Content-Type: application/json",
            "x-api-version: 2022-01-01",
            "x-client-id: ".env('CASHFREE_API_KEY'),
            "x-client-secret: ".env('CASHFREE_API_SECRET')
        ];

        $data = json_encode([
            'order_id' => $orderId,
            'order_amount' => $request->amount,
            "order_currency" => "INR",
            "customer_details" => [
                "customer_id" => $customerId,
                "customer_name" => $request->name,
                "customer_email" => $request->email,
                "customer_phone" => $request->phone,
            ],
            "order_meta" => [
                "return_url" => route('cashfree.success').'?order_id={order_id}&order_token={order_token}'
            ],
        ]);

        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);

        $response = curl_exec($curl);
        $err = curl_error($curl);
        curl_close($curl);

        if ($err) {
            return back()->with('error', 'Failed to create payment order: '.$err);
        }

        $responseData = json_decode($response);

        // Store payment details in database
        $payment = Payment::create([
            'name' => $request->name,
            'email' => $request->email,
            'phone' => $request->phone,
            'amount' => $request->amount,
            'order_id' => $orderId,
            'status' => 0 // pending
        ]);

        // Redirect to Cashfree payment page
        return redirect()->to($responseData->payment_link);
    }

    public function success(Request $request)
    {
        $orderId = $request->input('order_id');

        if (!$orderId) {
            return redirect('/')->with('error', 'Payment verification failed: Missing order ID');
        }

        // Verify payment status with Cashfree API
        $url = (env('CASHFREE_ENV') === 'sandbox'
            ? "https://sandbox.cashfree.com/pg/orders/"
            : "https://api.cashfree.com/pg/orders/") . $orderId;

        $headers = [
            "Content-Type: application/json",
            "x-api-version: 2022-01-01",
            "x-client-id: ".env('CASHFREE_API_KEY'),
            "x-client-secret: ".env('CASHFREE_API_SECRET')
        ];

        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);

        $response = curl_exec($curl);
        $err = curl_error($curl);
        curl_close($curl);

        if ($err) {
            return redirect('/')->with('error', 'Payment verification failed: '.$err);
        }

        $responseData = json_decode($response);

        //dd($responseData);

        // Update payment status in database
        $payment = Payment::where('order_id', $orderId)->first();

        if ($payment) {
            $status = ($responseData->order_status === 'PAID') ? 1 : 0;

            $payment->update([
                'status' => $status,
                'other' => $responseData,
                'payment_id' => $responseData->cf_order_id ?? null,
                'payment_method' => $responseData->payment_method ?? null
            ]);

            if ($status === 1) {
                return redirect('/')->with([
                    'success' => 'Payment Successful!',
                    'payment' => $payment,
                ]);
            }
        }

        return redirect('/')->with('error', 'Payment verification failed for Order ID: ' . $orderId);

    }
}

 

Step 7: Define Routes

Edit routes/web.php:

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\CashfreeController;

Route::get('/', [CashfreeController::class, 'index']);
Route::post('/cashfree/payments/store', [CashfreeController::class, 'payment'])->name('cashfree.payment');
Route::any('/cashfree/payments/success', [CashfreeController::class, 'success'])->name('cashfree.success');

Step 8: Create Views

resources/views/cashfree/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>Cashfree Payment</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css">
</head>

<body>
    <section class=" pt-5">
        <div class="container">
            <div class="row justify-content-center">
                <div class="col-md-6">
                    @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('error'))
                        <div class="alert alert-danger alert-dismissible fade show" role="alert">
                            <strong>Error!</strong> {{ session('error') }}
                            <button type="button" class="btn-close" data-bs-dismiss="alert"
                                aria-label="Close"></button>
                        </div>
                    @endif

                    @if (session('payment'))
                        <div class="card my-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')->payment_id }}</p>
                                <p><strong>Order Id:</strong> {{ session('payment')->order_id }}</p>
                                <p><strong>Amount:</strong> ₹{{ session('payment')->amount }}</p>
                            </div>
                        </div>
                    @endif

                    <div class="card p-3">
                        <h2>Cashfree Payment Integration</h2>
                        <form action="{{ route('cashfree.payment') }}" method="POST">
                            @csrf
                            <div class="mb-3">
                                <label for="name" class="form-label">Full Name</label>
                                <input type="text" name="name" value="{{ old('name') }}"
                                    class="form-control @error('name') is-invalid @enderror">
                                @error('name')
                                    <span class="text-danger">{{ $message }}</span>
                                @enderror
                            </div>

                            <div class="mb-3">
                                <label for="email" class="form-label">Email Address</label>
                                <input type="email" name="email" value="{{ old('email') }}"
                                    class="form-control @error('email') is-invalid @enderror">
                                @error('email')
                                    <span class="text-danger">{{ $message }}</span>
                                @enderror
                            </div>

                            <div class="mb-3">
                                <label for="phone" class="form-label">Phone Number</label>
                                <input type="tel" name="phone" value="{{ old('phone') }}"
                                    class="form-control @error('phone') is-invalid @enderror">
                                @error('phone')
                                    <span class="text-danger">{{ $message }}</span>
                                @enderror
                            </div>

                            <div class="mb-3">
                                <label for="amount" class="form-label">Amount (INR)</label>
                                <input type="number" name="amount" value="{{ old('amount') }}"
                                    class="form-control @error('amount') is-invalid @enderror">
                                @error('amount')
                                    <span class="text-danger">{{ $message }}</span>
                                @enderror
                            </div>

                            <button type="submit" class="btn btn-primary">Proceed to Pay</button>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </section>


 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-VQqxDN0EQCkWoxt/0vsQvZswzTHUVOImccYmSyhJTp7kGtPed0Qcx8rK9h9YEgx+" crossorigin="anonymous"></script>

</body>

</html>

Now Run the server and it should work as it suppose to be: 

php artisan serve

Conclusion

You have successfully integrated Cashfree Payment Gateway with Laravel! 🎉



+91 8447 525 204 Request Estimate