Simplified Laravel 9 Razorpay Integration Tutorial for Beginners

Last Updated: 07 Jan, 2024

Hi friends, this tutorial will show you the easy and simplest way of integrating Razorpay Payment Gateway in Laravel Application. To get this done, we will be using  razorpay/razorpay composer package.

Razorpay is a very popular, secured and powerful payments platform that allows us to accept payments from customers. It also helps us to automate payouts to employees & vendors. It offers the following featues:

  • You can get instant activation
  • Offers 100+ secured payment methods
  • Has leading success rate and support in the industry
  • Provides awesome checkout experience
  • Razorapy is very easy to integrate
  • Provides instant settlement from day 1
  • It also offers in-depth insights and dashboard reporting

Integrate Razorpay Payment Gateway easily in Laravel 9 Application

Dear friends, be with me and let's follow all the mentioned steps given below to do the same:

Step 1: Create a fresh Laravel 9 Application

At first, let's create a fresh laravel 9 application. In your system, open terminal and execute the following command:

composer create-project laravel/laravel l9razorpaypg

Step 2: Update DB Credentials in .env file

Next, let's update database credentials in .env file as follows:

DB_DATABASE=l9razorpaypg
DB_USERNAME={yourdbuser}
DB_PASSWORD={yourdbpass}

Step 3: Install and Setup Razorpay Composer Package

Next, install razorpay/razorpay composer package by executing below mentioned command in your terminal:

composer require razorpay/razorpay:2.*

Now, you have to visit to Razorpay Official Website (https://dashboard.razorpay.com/) and login to your account. If you have not created your Razorpay account, create a new account. Then you can get your API Credentials (API_KEY and API_SECRET) from your razorpay dashboard. Open .env file and configure these keys in it as follows:

RPPG_API_KEY={razorpay_api_key}
RPPG_API_SECRET={razorpay_api_secret}

Next, open app/config/services.php file and add below given Razorpay code inside it:

'razorpay' => [
    'api_key' => env('RPPG_API_KEY'),
    'api_secret' => env('RPPG_API_SECRET'),
],

Step 4: Create RPPGPayment Model & Migration

Next, we have to create model and migration files that will help us to capture and store payment details. Execute below command in the therminal:

php artisan make:model RPPGPayment
php artisan make:migration create_rppgpayments_table

Above commands will generate a model and a migration file. Open app/Models/RPPGPayment.php file and copy below mentioned code into it:

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class RPPGPayment extends Model
{
    use HasFactory;
    protected $fillable = [
        'name',
        'email',
        'mobile',
        'amount'
    ];
}

Open the databse/migrations/*_create_rppgpayments_table.php file and copy below given code inside it:

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up()
    {
        Schema::create('rppgpayments', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email');
            $table->string('mobile');
            $table->string('amount');
            $table->string('purpose');
            $table->string('payment_request_id');
            $table->string('payment_link');
            $table->string('payment_status')->nullable();
            $table->string('payment_id')->nullable();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('rppgpayments');
    }
};

Next, you have to execute below command that will run the laravel migrattion and will create the necessary tables in the mysql db:

php artisan migrate

Step 5: Create RPPGPayment Controller

Next, open app/Http/Controllers/RPPGPaymentController.php file and copy below mentioned code in it:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Validator;
use App\Models\RPPGPayment;

class RPPGPaymentController extends Controller
{
    protected $rpp = 10;

    public function index(Request $request)
    {
        $request_data = $request->all();
        $view_data = [];
        
        if (!$request->ajax()){
            $view_data['title'] = 'Razorpay Payments List';
            return view('rppgpayments.index')->with($view_data);
        } else {
            $page = $request_data['page'];
            $view_data['page'] = $page;
        
            $records = RPPGPayment::orderBy('created_at', 'desc')->paginate($this->rpp);
            $record_starts = $this->rpp * ($page - 1) + 1;
            $record_ends = $this->rpp * ($page - 1) + count($records);
            $view_data['records'] = $records;
            $view_data['record_starts'] = $record_starts;
            $view_data['record_ends'] = $record_ends;
            return view('rppgpayments.list')->with($view_data);
        }
    }

    public function create(Request $request)
    {
        $view_data['title'] = 'Create New Razorpay Payment';
        return view('rppgpayments.create')->with($view_data);
    }

    public function store(Request $request)
    {
        $posted_data = $request->all();
        $validator = Validator::make($posted_data, array(
            'name' => 'required|min:3',
            'email' => 'required',
            'mobile' => 'required',
            'amount' => 'required'
        ), array(
            'name.required' => 'Enter name.',
            'name.min' => 'Minium of 3 characters.',
            'email.required' => 'Enter email address.',
            'mobile.required' => 'Enter mobile number.',
            'amount.required' => 'Enter amount.'
        ));

        if ($validator->fails()) {
            return redirect()->back()->withInput($request->only('name', 'email', 'mobile', 'amount'))->withErrors($validator->errors());
        }

        try {
            $rp = config('services.razorpay');
            $api = new Api($rp['api_key'], $rp['api_secret']);
            $name = trim($request->name);
            $email = trim($request->email);
            $mobile = trim($request->mobile);
            $amount = intval($request->amount) * 100;
            $purpose = 'Razorpay Payment Invoice';

            $payload = array(
                "type" => "link",
                "view_less" => 1,
                "amount" => $amount,
                "currency" => "INR",
                "description" => $purpose,
                "receipt" => "RPORDER" . Str::random(9),
                "sms_notify" => 1,
                "email_notify" => 1,
                "expire_by" => strtotime("+1 month"),
                "callback_url" => url('/razorpaypayments/success'),
                "callback_method" => "get",
                "customer" => array(
                    "name" => $name,
                    "email" => $email,
                    "contact" => $mobile,
                ),
            );

            $invoice  = $api->invoice->create($payload);
            $invoice = $invoice->toArray();

            if ($invoice['status'] == 'issued') {
                RPPGPayment::insert([
                    'name' => $name,
                    'email' => $email,
                    'mobile' => $mobile,
                    'amount' => $amount,
                    'purpose' => $purpose,
                    'payment_request_id' => $invoice['id'],
                    'payment_link' => $invoice['short_url'],
                    'payment_status' => $invoice['status'],
                    'created_at' => now(),
                    'updated_at' => now()
                ]);
                header('Location: ' . $invoice['short_url']);
                exit();
            } else {
                echo "<pre>";
                print_r($invoice);
                exit;
            }
        }catch (Exception $e) {
            echo "<pre>";
            print('Error: ' . $e->getMessage());
            exit;
        }
    }

    public function success(Request $request)
    {
        $request_data = $request->all();

        $invoice_id = $request_data['razorpay_invoice_id'];
        $invoice_status = $request_data['razorpay_invoice_status'];
        $payment_id = $request_data['razorpay_payment_id'];
        
        $rp_payment = RPPGPayment::where('payment_request_id', $invoice_id)->first();
        
        if (strtolower(trim($invoice_status)) == 'paid') {
            $rp_payment->payment_status = $invoice_status;
            $rp_payment->payment_id = $payment_id;
            $rp_payment->save();
            dd('Payment Successful');
        } else {
            dd('Payment Failed!');
        }
        dd($request_data);
    }
}

Step 6: Create App Routes

Next, open routes/web.php file and copy the below mentioned code into it:

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\RPPGPaymentController;

Route::group(['prefix' => 'razorpaypayments'], function () {
    Route::get('/', [RPPGPaymentController::class, 'index']);
    Route::get('/create', [RPPGPaymentController::class, 'create']);
    Route::post('/', [RPPGPaymentController::class, 'store']);
    Route::any('/success', [RPPGPaymentController::class, 'success']);
});

Step 7: Create Blade View Files

Next, create the below blade files under resources/views/rppgpayments directory:

resources/views/rppgpayments/index.blade.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Razorpay Payment Gateway Integration - Laravel 9</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
</head>
<body>
<div class="container mt-3">
    <div class="row text-center"><h1>Razorpay Payment Gateway Integration</h1></div>
    <div class="row" id="result-div"><strong style="color: #0cf;text-align: center;">Fetching records...</strong></div>
</div>
<script>
var pageNo = 1;
$(function(){
    $.ajax({
        url: "{{url('razorpaypayments')}}",
        type: "GET",
        dataType: "HTML",
        data: {
            'page': pageNo
        }
    }).done(function(data){
        $("#result-div").empty().html(data);
    }).fail(function(jqXHR, ajaxOptions, thrownError){
        console.log('No response from server');
    }).always(function(){
    });
});
</script>
</body>
</html>

resources/views/rppgpayments/list.blade.php

<div class="col-12 mb-3">
    <div class="card text-white bg-success mb-3">
        <div class="card-header">
            <h3 class="card-title" style="display: inline-block;">Razorpay Payments List</h3>
            <a href="{{url('/razorpaypayments/create')}}" class="btn btn-primary float-end">Create New Razorpay Payment</a>
        </div>
        <div class="card-body table-responsive">
            <table class="table table-striped text-white">
                <thead>
                <tr style="text-transform: uppercase;">
                    <th>#</th>
                    <th>Name</th>
                    <th>EMail</th>
                    <th>Mobile</th>
                    <th>Amount</th>
                    <th>Purpose</th>
                    <th>Status</th>
                    <th>PaymentId</th>
                    <th>CreatedAt</th>
                </tr>
                </thead>
                <tbody>
                @if($records->count() > 0)
                    @foreach($records as $rec)
                    <tr>
                        <td>{{$loop->iteration}}</td>
                        <td>{{$rec->name}}</td>
                        <td>{{$rec->email}}</td>
                        <td>{{$rec->mobile}}</td>
                        <td>{{$rec->amount}}</td>
                        <td>{{$rec->purpose}}</td>
                        <td><button class="btn btn-info">{{$rec->payment_status}}</button></td>
                        <td>{{$rec->payment_id}}</td>
                        <td>{{$rec->created_at}}</td>
                    </tr>
                    @endforeach
                @else
                    <tr class="text-center"><td colspan="8">Record not found!!</td></tr>
                @endif
                </tbody>
            </table>
            {!! $records->links() !!}
        </div>
    </div>
</div>

resources/views/rppgpayments/create.blade.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Razorpay Payment Gateway Integration - Laravel 9</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-3">
        <div class="row justify-content-center">
            <div class="col-12 col-md-6 mb-3">
                <div class="card text-dark bg-success mb-3">
                    <div class="card-header">
                        <h3 class="card-title text-white" style="display: inline-block;">Create New Payment</h3>
                        <a href="{{url('/razorpaypayments')}}" class="btn btn-primary float-end">Payments List</a>
                    </div>
                    <div class="card-body">
                        <form action="{{ url('razorpay/payments') }}" method="POST" name="laravel9-razorpay-integration">
                            {{ csrf_field() }}
                            <div class="form-floating">
                              <input type="text" class="form-control" name="name" id="name" value="{{ old('name') }}" placeholder="name">
                              <label for="name">Full Name</label>
                            </div>
                            <div class="form-floating">
                              <input type="email" class="form-control" name="email" id="email" value="{{ old('email') }}" placeholder="email">
                              <label for="email">Email Address</label>
                            </div>
                            <div class="form-floating">
                              <input type="text" class="form-control" name="mobile" id="mobile" value="{{ old('mobile') }}" placeholder="mobile">
                              <label for="mobile">Mobile Number</label>
                            </div>
                            <div class="form-floating">
                              <input type="text" class="form-control" name="amount" id="amount" value="{{ old('amount') }}" placeholder="amount">
                              <label for="amount">Amount</label>
                            </div>
                            <button class="w-100 btn btn-lg btn-primary" type="submit">Place Order</button>
                        </form>
                        @if ($errors->any())
                        <div class="alert alert-danger text-start" role="alert">
                            <strong>Opps!</strong> Something went wrong<br>
                            <ul>
                            @foreach ($errors->all() as $error)
                                <li>{{ $error }}</li>
                            @endforeach
                            </ul>
                        </div>
                        @endif
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

Step 8: Start Laravel Development Server

Lets start the development server now by executing below command into the terminal:

php artisan serve

Once development server is started, open below URL in your browser:

http://127.0.0.1:8000/razorpaypayments

You can use below mentioned Test Card Credentials to test your application just created:

===Mastercard
5267 3181 8797 5449
Random CVV
Any future date as per your wish

===Visa
4111 1111 1111 1111
Random CVV
Any future date as per your wish

For more information about razorpay test cards, please visit the below mentioned url:

https://razorpay.com/docs/payments/payments/test-card-upi-details/

Thank You, Please Share.

Recommended Posts

Simplified Laravel 9 REST API Tutorial using Sanctum  Authentication

Simplified Laravel 9 REST API Tutorial using Sanctum Authentication

In this simplified tutorial, you will learn the simplest way to create a REST API application in Laravel 9 that will be authenticated using Laravel Sanctum.

Simplified Laravel 9 Cashfree Integration Tutorial for Beginners

Simplified Laravel 9 Cashfree Integration Tutorial for Beginners

In this awesome tutorial, we are going to learn the simplest way of integrating Cashfree Payment Gateway inside Laravel 9 application.

Simplified Laravel 9 Instamojo Integration Tutorial for Beginners

Simplified Laravel 9 Instamojo Integration Tutorial for Beginners

In this simple tutorial, you will be learning the easy and comprehensive way of integrating Instamojo Payment Gateway inside Laravel 9 application.