CoderFunda
  • Home
  • About us
    • Contact Us
    • Disclaimer
    • Privacy Policy
    • About us
  • Home
  • Php
  • HTML
  • CSS
  • JavaScript
    • JavaScript
    • Jquery
    • JqueryUI
    • Stock
  • SQL
  • Vue.Js
  • Python
  • Wordpress
  • C++
    • C++
    • C
  • Laravel
    • Laravel
      • Overview
      • Namespaces
      • Middleware
      • Routing
      • Configuration
      • Application Structure
      • Installation
    • Overview
  • DBMS
    • DBMS
      • PL/SQL
      • SQLite
      • MongoDB
      • Cassandra
      • MySQL
      • Oracle
      • CouchDB
      • Neo4j
      • DB2
      • Quiz
    • Overview
  • Entertainment
    • TV Series Update
    • Movie Review
    • Movie Review
  • More
    • Vue. Js
    • Php Question
    • Php Interview Question
    • Laravel Interview Question
    • SQL Interview Question
    • IAS Interview Question
    • PCS Interview Question
    • Technology
    • Other
⌕
Popular learning topics
PHP Laravel JavaScript CSS SQL Python Vue.js WordPress

20 August, 2026

Laravel Razorpay Payment Gateway with Transaction Tracking, OTP Verification & Custom SMS

 Programing Coderfunda     August 20, 2026     Laravel     No comments   

Build a secure, production-ready Razorpay payment integration in Laravel with complete transaction management, server-side payment verification, OTP authentication, custom SMS notifications, and webhook support.

Description

This implementation provides a complete payment workflow:

  • 💳 Razorpay payment gateway integration
  • 🔐 Secure Razorpay signature verification
  • 🆔 Unique transaction ID for every payment
  • 📦 Razorpay Order ID and Payment ID tracking
  • 💰 Amount and currency verification
  • 🗄️ Complete payment and customer data stored in MySQL
  • 📋 Transaction event/audit history
  • 📱 OTP generation after successful payment
  • 🔒 Hashed OTP storage with expiration
  • 🚫 OTP attempt limits and duplicate OTP protection
  • 💬 Custom SMS message after successful payment
  • ⚡ Queue-based SMS sending
  • 🔄 Razorpay webhook integration
  • 🛡️ Idempotent payment processing
  • ❌ Payment failure handling
  • 💸 Refund/status tracking support
  • 📝 Detailed payment response storage
  • 🔍 Transaction reconciliation and debugging support
  • 🔐 Production-focused security practices

Complete Payment Flow

Customer
↓
Create Transaction
↓
Generate Transaction ID
↓
Create Razorpay Order
↓
Razorpay Checkout
↓
Payment Successful
↓
Server-Side Signature Verification
↓
Verify Order + Amount + Currency
↓
Save Payment Details
↓
Mark Transaction as PAID
↓
Generate OTP
↓
Store Hashed OTP
↓
Send Custom SMS
↓
Customer Enters OTP
↓
Verify OTP
↓
Mark Transaction COMPLETED

Goal: Create a reliable Laravel payment system where every payment is securely tracked from transaction creation → Razorpay payment → verification → OTP → final completion, with a complete database audit trail.


I’ll use Laravel 12-style structure, Eloquent, queued SMS, signed Razorpay checkout, server-side verification, webhook handling, idempotency, OTP hashing, expiry, and attempt limits.

Important: Replace the SmsService implementation with your actual SMS provider credentials/API. The payment logic itself does not depend on the SMS provider.


1. Install Razorpay

composer require razorpay/razorpay

.env

APP_NAME="My Laravel App"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://example.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=my_database
DB_USERNAME=my_user
DB_PASSWORD=my_password

RAZORPAY_KEY_ID=rzp_live_xxxxxxxxx
RAZORPAY_KEY_SECRET=xxxxxxxxxxxxxxxx
RAZORPAY_WEBHOOK_SECRET=xxxxxxxxxxxxxxxx

QUEUE_CONNECTION=database

OTP_EXPIRY_MINUTES=10
OTP_MAX_ATTEMPTS=5

config/services.php

'razorpay' => [
'key' => env('RAZORPAY_KEY_ID'),
'secret' => env('RAZORPAY_KEY_SECRET'),
'webhook_secret' => env('RAZORPAY_WEBHOOK_SECRET'),
],

'otp' => [
'expiry_minutes' => env('OTP_EXPIRY_MINUTES', 10),
'max_attempts' => env('OTP_MAX_ATTEMPTS', 5),
],

2. Database structure

We'll create:

transactions
transaction_events
otps

The important identifier is our own:

transaction_id

For example:

TXN-20260820-A8F92KLM7P

This is separate from Razorpay's:

razorpay_order_id
razorpay_payment_id

3. Transactions migration

Create:

php artisan make:migration create_transactions_table
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::create('transactions', function (Blueprint $table) {
$table->id();

$table->uuid('uuid')->unique();

$table->string('transaction_id', 50)->unique();

$table->foreignId('user_id')
->nullable()
->constrained()
->nullOnDelete();

$table->string('customer_name');
$table->string('customer_email');
$table->string('customer_phone', 20);

$table->decimal('amount', 12, 2);
$table->string('currency', 3)->default('INR');

$table->string('status')->default('created');

$table->string('razorpay_order_id')
->nullable()
->unique();

$table->string('razorpay_payment_id')
->nullable()
->unique();

$table->string('razorpay_signature')
->nullable();

$table->string('payment_method')
->nullable();

$table->string('payment_status')
->nullable();

$table->timestamp('paid_at')->nullable();

$table->timestamp('failed_at')->nullable();

$table->text('failure_reason')->nullable();

$table->json('razorpay_order_response')->nullable();

$table->json('razorpay_payment_response')->nullable();

$table->json('metadata')->nullable();

$table->timestamps();

$table->index(['user_id', 'status']);
$table->index(['customer_phone']);
$table->index(['created_at']);
});
}

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

4. Transaction events

This gives you an audit trail.

php artisan make:migration create_transaction_events_table
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::create('transaction_events', function (Blueprint $table) {
$table->id();

$table->foreignId('transaction_id')
->constrained('transactions')
->cascadeOnDelete();

$table->string('event');

$table->string('source')->nullable();

$table->json('payload')->nullable();

$table->timestamps();

$table->index([
'transaction_id',
'event'
]);
});
}

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

5. OTP migration

php artisan make:migration create_otps_table
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::create('otps', function (Blueprint $table) {
$table->id();

$table->foreignId('transaction_id')
->constrained('transactions')
->cascadeOnDelete();

$table->string('phone', 20);

$table->string('otp_hash');

$table->timestamp('expires_at');

$table->unsignedTinyInteger('attempts')
->default(0);

$table->unsignedTinyInteger('max_attempts')
->default(5);

$table->timestamp('verified_at')
->nullable();

$table->timestamp('last_sent_at')
->nullable();

$table->timestamps();

$table->index([
'transaction_id',
'verified_at'
]);
});
}

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

Run:

php artisan migrate

6. Transaction model

app/Models/Transaction.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Transaction extends Model
{
protected $fillable = [
'uuid',
'transaction_id',
'user_id',
'customer_name',
'customer_email',
'customer_phone',
'amount',
'currency',
'status',
'razorpay_order_id',
'razorpay_payment_id',
'razorpay_signature',
'payment_method',
'payment_status',
'paid_at',
'failed_at',
'failure_reason',
'razorpay_order_response',
'razorpay_payment_response',
'metadata',
];

protected $casts = [
'amount' => 'decimal:2',
'paid_at' => 'datetime',
'failed_at' => 'datetime',
'razorpay_order_response' => 'array',
'razorpay_payment_response' => 'array',
'metadata' => 'array',
];

public function events(): HasMany
{
return $this->hasMany(TransactionEvent::class);
}

public function otps(): HasMany
{
return $this->hasMany(Otp::class);
}

public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

7. TransactionEvent model

app/Models/TransactionEvent.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class TransactionEvent extends Model
{
protected $fillable = [
'transaction_id',
'event',
'source',
'payload',
];

protected $casts = [
'payload' => 'array',
];

public function transaction(): BelongsTo
{
return $this->belongsTo(Transaction::class);
}
}

8. OTP model

app/Models/Otp.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Otp extends Model
{
protected $fillable = [
'transaction_id',
'phone',
'otp_hash',
'expires_at',
'attempts',
'max_attempts',
'verified_at',
'last_sent_at',
];

protected $casts = [
'expires_at' => 'datetime',
'verified_at' => 'datetime',
'last_sent_at' => 'datetime',
];

protected $hidden = [
'otp_hash',
];

public function transaction(): BelongsTo
{
return $this->belongsTo(Transaction::class);
}
}

9. Razorpay service

Create:

app/Services/RazorpayService.php
<?php

namespace App\Services;

use Razorpay\Api\Api;

class RazorpayService
{
protected Api $api;

public function __construct()
{
$this->api = new Api(
config('services.razorpay.key'),
config('services.razorpay.secret')
);
}

public function createOrder(
string $receipt,
int $amountInPaise,
string $currency = 'INR'
): array {
$order = $this->api->order->create([
'receipt' => $receipt,
'amount' => $amountInPaise,
'currency' => $currency,
]);

return $order->toArray();
}

public function verifyPayment(
string $orderId,
string $paymentId,
string $signature
): bool {
$this->api->utility->verifyPaymentSignature([
'razorpay_order_id' => $orderId,
'razorpay_payment_id' => $paymentId,
'razorpay_signature' => $signature,
]);

return true;
}

public function fetchPayment(string $paymentId): array
{
return $this->api
->payment
->fetch($paymentId)
->toArray();
}
}

10. Transaction service

This is where the important business logic lives.

app/Services/PaymentService.php

<?php
'-' .
strtoupper(Str::random(10));

$transaction = Transaction::create([
'uuid' => (string) Str::uuid(),

'transaction_id' => $transactionId,

'user_id' => $data['user_id'] ?? null,

'customer_name' => $data['name'],
'customer_email' => $data['email'],
'customer_phone' => $data['phone'],

'amount' => $data['amount'],

'currency' => 'INR',

'status' => 'creating',

'metadata' => $data['metadata'] ?? null,
]);

$amountPaise = (int) round(
$transaction->amount * 100
);

$order = $this->razorpay->createOrder(
$transaction->transaction_id,
$amountPaise,
$transaction->currency
);

$transaction->update([
'razorpay_order_id' => $order['id'],
'status' => 'created',
'razorpay_order_response' => $order,
]);

$transaction->events()->create([
'event' => 'order_created',
'source' => 'application',
'payload' => $order,
]);

return $transaction->fresh();
});
}

public function verifyAndCapturePayment(
Transaction $transaction,
array $paymentData
): Transaction {

return DB::transaction(function () use (
$transaction,
$paymentData
) {

$transaction = Transaction::query()
->whereKey($transaction->id)
->lockForUpdate()
->firstOrFail();

/*
* Idempotency:
*
* If the payment was already processed,
* don't process it again.
*/
if ($transaction->status === 'paid') {
return $transaction;
}

$this->razorpay->verifyPayment(
$paymentData['razorpay_order_id'],
$paymentData['razorpay_payment_id'],
$paymentData['razorpay_signature']
);

/*
* Make sure the payment belongs to
* our transaction.

11. OTP service

app/Services/OtpService.php

<?php
'expires_at' => now(),
]);

$otp = (string) random_int(100000, 999999);

$record = Otp::create([
'transaction_id' => $transaction->id,

'phone' => $transaction->customer_phone,

'otp_hash' => Hash::make($otp),

'expires_at' => now()->addMinutes(
config('services.otp.expiry_minutes', 10)
),

'attempts' => 0,

'max_attempts' => config(
'services.otp.max_attempts',
5
),

'last_sent_at' => now(),
]);

/*
* Never return/store plaintext OTP in DB.
*
* Return it temporarily so the SMS job can use it.
*/
$record->plain_otp = $otp;

return $record;
});
}

public function verify(
Transaction $transaction,
string $inputOtp
): bool {

return DB::transaction(function () use (
$transaction,
$inputOtp
) {

$otp = Otp::query()
->where('transaction_id', $transaction->id)
->whereNull('verified_at')
->latest()
->lockForUpdate()
->first();

if (!$otp) {
throw new RuntimeException(
'OTP not found.'
);
}

if ($otp->expires_at->isPast()) {
throw new RuntimeException(
'OTP has expired.'
);
}

if ($otp->attempts >= $otp->max_attempts) {
throw new RuntimeException(
'Maximum OTP attempts exceeded.'
);
}

$otp->increment('attempts');

if (!Hash::check($inputOtp, $otp->otp_hash)) {
throw new RuntimeException(
'Invalid OTP.'
);
}

$otp->update([
'verified_at' => now(),
]);

12. SMS service

Create:

app/Services/SmsService.php
<?php

namespace App\Services;

class SmsService
{
public function sendOtp(
string $phone,
string $name,
string $otp
): bool {

$message =
"Hello {$name}, your payment was successful. " .
"Your OTP is {$otp}. " .
"This OTP is valid for 10 minutes. " .
"Do not share this OTP with anyone.";

/*
* Integrate your SMS provider here.
*
* Example:
*
* Http::post(...)
*/

logger()->info('OTP SMS prepared', [
'phone' => $phone,
'message' => $message,
]);

return true;
}
}

Do not log the OTP in production. The logger above is only illustrative; remove the message from production logs.


13. Queue job for SMS

Sending SMS inside the payment request can slow down the payment response.

Create:

php artisan make:job SendOtpSmsJob

app/Jobs/SendOtpSmsJob.php

<?php

namespace App\Jobs;

use App\Models\Transaction;
use App\Services\SmsService;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Queue\Queueable;

class SendOtpSmsJob implements ShouldQueue
{
use Queueable;

public int $tries = 3;

public function __construct(
public int $transactionId,
public string $otp
) {
}

public function handle(SmsService $sms): void
{
$transaction = Transaction::findOrFail(
$this->transactionId
);

$sms->sendOtp(
$transaction->customer_phone,
$transaction->customer_name,
$this->otp
);
}
}

14. Payment controller

Create:

php artisan make:controller PaymentController

app/Http/Controllers/PaymentController.php

<?php
}

return response()->json([
'success' => true,

'transaction_id' =>
$transaction->transaction_id,

'message' =>
'Payment successful. OTP has been sent.',
]);

} catch (Throwable $e) {

Log::error(
'Payment verification failed',
[
'message' => $e->getMessage(),
'transaction_id' =>
$request->transaction_id,
]
);

return response()->json([
'success' => false,

'message' =>
'Payment verification failed.',
], 400);
}
}

public function otpPage(
string $transactionId
) {

$transaction = Transaction::where(
'transaction_id',
$transactionId
)->firstOrFail();

abort_unless(
$transaction->status === 'paid',
403
);

return view(
'payment.otp',
compact('transaction')
);
}

public function verifyOtp(Request $request)
{
$validated = $request->validate([
'transaction_id' =>
'required|string',

'otp' =>
'required|digits:6',
]);

try {

$transaction = Transaction::where(
'transaction_id',
$validated['transaction_id']
)->firstOrFail();

$this->otpService->verify(
$transaction,
$validated['otp']
);

return response()->json([
'success' => true,

'message' =>
'OTP verified successfully.',
]);

} catch (Throwable $e) {


15. Routes

routes/web.php

<?php

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

Route::get(
'/payment',
[PaymentController::class, 'checkout']
)->name('payment.checkout');

Route::post(
'/payment/create-order',
[PaymentController::class, 'createOrder']
)->name('payment.create');

Route::post(
'/payment/success',
[PaymentController::class, 'success']
)->name('payment.success');

Route::get(
'/payment/otp/{transactionId}',
[PaymentController::class, 'otpPage']
)->name('payment.otp');

Route::post(
'/payment/verify-otp',
[PaymentController::class, 'verifyOtp']
)->name('payment.verify-otp');

If your payment requires authentication, use:

Route::middleware('auth')->group(function () {

Route::get(
'/payment',
[PaymentController::class, 'checkout']
);

Route::post(
'/payment/create-order',
[PaymentController::class, 'createOrder']
);

// ...
});

16. Checkout Blade

resources/views/payment/checkout.blade.php

<!DOCTYPE html>
<html>
<head>
<title>Payment</title>

<meta name="csrf-token"
content="{{ csrf_token() }}">

<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
</head>

<body>

<h2>Make Payment</h2>

<form id="paymentForm">

<input
type="text"
id="name"
placeholder="Name"
required
>

<br><br>

<input
type="email"
id="email"
placeholder="Email"
required
>

<br><br>

<input
type="text"
id="phone"
placeholder="Phone"
required
>

<br><br>

<input
type="number"
id="amount"
value="499"
min="1"
required
>

<br><br>

<button type="submit">
Pay Now
</button>

</form>

<script>

const form = document.getElementById('paymentForm');

form.addEventListener('submit', async function (e) {

e.preventDefault();

const data = {
name: document.getElementById('name').value,
email: document.getElementById('email').value,
phone: document.getElementById('phone').value,
amount: document.getElementById('amount').value
};

const response = await fetch(

17. OTP page

resources/views/payment/otp.blade.php

<!DOCTYPE html>
<html>
<head>
<title>Verify OTP</title>

<meta name="csrf-token"
content="{{ csrf_token() }}">
</head>

<body>

<h2>Verify OTP</h2>

<p>
Payment successful.
</p>

<p>
OTP has been sent to:
{{ substr($transaction->customer_phone, 0, 3) }}******
</p>

<form id="otpForm">

<input
type="hidden"
id="transaction_id"
value="{{ $transaction->transaction_id }}"
>

<input
type="text"
id="otp"
maxlength="6"
pattern="[0-9]{6}"
placeholder="Enter OTP"
required
>

<br><br>

<button type="submit">
Verify OTP
</button>

</form>

<div id="message"></div>

<script>


18. Razorpay webhook

This is extremely important for production.

The browser can disappear after payment. Your server should also receive Razorpay's webhook.

Create:

app/Http/Controllers/RazorpayWebhookController.php
<?php
$payload,
config('services.razorpay.webhook_secret')
);

if (!hash_equals(
$expectedSignature,
$signature
)) {

Log::warning(
'Invalid Razorpay webhook signature'
);

return response()->json([
'message' => 'Invalid signature'
], 400);
}

$data = $request->json()->all();

$event = $data['event'] ?? null;

$paymentEntity =
$data['payload']['payment']['entity']
?? null;

if (!$paymentEntity) {

return response()->json([
'success' => true
]);
}

$razorpayOrderId =
$paymentEntity['order_id']
?? null;

if (!$razorpayOrderId) {

return response()->json([
'success' => true
]);
}

DB::transaction(function () use (
$razorpayOrderId,
$paymentEntity,
$event
) {

$transaction =
Transaction::where(
'razorpay_order_id',
$razorpayOrderId
)
->lockForUpdate()
->first();

if (!$transaction) {

Log::warning(
'Transaction not found for webhook',
[
'order_id' =>
$razorpayOrderId
]
);

return;
}

/*
* Store webhook event.
*/
$transaction->events()->create([
'event' =>
$event ?? 'unknown',

'source' =>
'razorpay_webhook',

'payload' =>
$paymentEntity,

19. Webhook route

Put this in routes/api.php:

use App\Http\Controllers\RazorpayWebhookController;

Route::post(
'/razorpay/webhook',
[RazorpayWebhookController::class, 'handle']
);

The webhook endpoint should not require CSRF because Razorpay is calling it server-to-server.

Configure the webhook in your Razorpay dashboard to:

https://example.com/api/razorpay/webhook

Subscribe to at least:

payment.captured
payment.failed
order.paid

20. Queue setup

Because SMS is queued, create the jobs table if necessary:

php artisan make:queue-table
php artisan migrate

Then run:

php artisan queue:work --tries=3

For production, use Supervisor rather than manually running queue:work.

Example Supervisor configuration:

[program:laravel-worker]

process_name=%(program_name)s_%(process_num)02d

command=php /var/www/html/artisan queue:work --sleep=3 --tries=3 --timeout=90

autostart=true
autorestart=true

stopasgroup=true
killasgroup=true

numprocs=2

redirect_stderr=true

stdout_logfile=/var/www/html/storage/logs/worker.log

stopwaitsecs=3600

21. Payment statuses

I recommend using:

creating
created
paid
completed
failed
refunded
cancelled

The lifecycle is:

creating
↓
created
↓
paid
↓
completed

If payment fails:

created
↓
failed

If later refunded:

paid/completed
↓
refunded

22. Example database record

After payment, transactions could contain:

id: 25
uuid: 2a9c...uuid
transaction_id: TXN-20260820-A8F92KLM7P
user_id: 15

customer_name: Rahul
customer_email: rahul@example.com
customer_phone: 9876543210

amount: 499.00
currency: INR

status: paid
payment_status: captured

razorpay_order_id: order_Random123
razorpay_payment_id: pay_Random456

payment_method: upi

paid_at: 2026-08-20 15:20:30

And the Razorpay response is preserved in:

razorpay_order_response
razorpay_payment_response

This is useful for reconciliation and debugging.


23. Transaction event history

You can then see:

transaction_events

order_created
payment_verified
payment.captured
otp_verified

For example:

TXN-20260820-A8F92KLM7P

15:20:01 order_created
15:20:29 payment_verified
15:20:31 payment.captured
15:20:35 otp_verified

This is much better than trying to infer the payment history from a single transactions row.


24. Very important: prevent duplicate OTPs

There is one more production concern.

The browser callback and webhook can both arrive.

You must not do this:

generateOtp();
sendSms();

every time a payment callback arrives.

Instead, use a locked transaction and check whether a valid OTP already exists.

For even stronger protection, add an otp_sent_at column to transactions:

$table->timestamp('otp_sent_at')->nullable();

Then inside the locked transaction:

if (!$transaction->otp_sent_at) {

// Generate OTP

$transaction->update([
'otp_sent_at' => now(),
]);

// Dispatch SMS
}

That makes the OTP process explicitly idempotent.


25. Security checklist

For a real production deployment, I recommend all of these:

✓ HTTPS
✓ Razorpay signature verification
✓ Razorpay webhook signature verification
✓ Server-side amount verification
✓ Server-side currency verification
✓ Transaction/order ID matching
✓ DB row locking
✓ Idempotency protection
✓ OTP hashed in database
✓ OTP expiration
✓ OTP attempt limit
✓ SMS queued
✓ Payment audit events
✓ Razorpay response stored
✓ No card information stored
✓ No plaintext OTP stored
✓ No OTP in production logs
✓ Rate limiting on OTP endpoints
✓ Rate limiting on payment creation
✓ Production APP_DEBUG=false
✓ Queue worker with Supervisor
✓ Database backups
✓ Payment reconciliation

One change I strongly recommend

For the most robust version, don't make the frontend callback responsible for generating the OTP. Let the server-side payment confirmation service own the entire process:

Razorpay payment
↓
Signature verification
↓
Amount/order verification
↓
Transaction locked
↓
Transaction = PAID
↓
Create OTP exactly once
↓
Commit DB transaction
↓
Queue SMS

Then the Razorpay webhook can independently reconcile the transaction without accidentally sending another OTP.

If you tell me your Laravel version (10/11/12), whether you're using login/authentication, and which SMS provider (MSG91, Twilio, Fast2SMS, etc.), I can adapt this into the exact production structure for your project, including the SMS API implementation and rate-limited resend-OTP endpoint.

 

Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Newer Posts Older Posts Home

Meta

Popular Posts

  • Google Cloud Tasks to be used as the Queue Driver in Laravel
      Laravel Google Cloud Tasks Queue   package allows Google Cloud Tasks to be used as the queue driver. This package requires Laravel 6 or hi...
  • 82-year-old Florida man’s 70-year collection includes a letter from Elizabeth Taylor
    https://timesofindia.indiatimes.com/world/us/an-82-year-old-florida-man-has-spent-seven-decades-collecting-magazines-photographs-and-celebr...
  • Savannah Chrisley’s husband seeks return of $2.17 million seized in fraud case
    image/jpeg https://timesofindia.indiatimes.com/tv/news/english/savannah-chrisleys-husband-jason-galanis-seeks-return-of-2-17-million-seized-...
  • Imran apologises as HC slams him for protests despite being an OCI card holder
    image/jpeg https://timesofindia.indiatimes.com/entertainment/hindi/bollywood/news/imran-khan-apologises-as-bombay-high-court-slams-the-actor...
  • Manipulate values in element in xml file using xslt
    I want to have possibility to remove or replace unnecessary text inside values in elements in xml file and I want use an XSLT transformation...

Categories

  • Ajax (26)
  • Bootstrap (30)
  • DBMS (42)
  • HTML (12)
  • HTML5 (46)
  • JavaScript (10)
  • Jquery (34)
  • Jquery UI (2)
  • JqueryUI (32)
  • Laravel (1069)
  • Laravel Tutorials (23)
  • Laravel-Question (36)
  • Magento (9)
  • Magento 2 (95)
  • MariaDB (1)
  • MySql Tutorial (3)
  • PHP-Interview-Questions (3)
  • Php Question (13)
  • Python (36)
  • RDBMS (13)
  • SQL Tutorial (79)
  • Vue.js Tutorial (69)
  • Wordpress (158)
  • Wordpress Theme (3)
  • codeigniter (108)
  • oops (4)
  • php (854)

Social Media Links

  • Follow on Twitter
  • Like on Facebook
  • Subscribe on Youtube
  • Follow on Instagram

Pages

  • Home
  • Contact Us
  • Privacy Policy
  • About us

Blog Archive

  • ▼  2026 (419)
    • ►  11/01 - 11/08 (86)
    • ►  09/27 - 10/04 (66)
    • ►  09/20 - 09/27 (52)
    • ►  09/13 - 09/20 (10)
    • ►  08/30 - 09/06 (87)
    • ▼  08/16 - 08/23 (1)
      • Laravel Razorpay Payment Gateway with Transaction ...
    • ►  08/02 - 08/09 (8)
    • ►  07/26 - 08/02 (108)
    • ►  06/28 - 07/05 (1)
  • ►  2025 (4)
    • ►  07/06 - 07/13 (2)
    • ►  06/29 - 07/06 (2)
  • ►  2024 (486)
    • ►  09/15 - 09/22 (30)
    • ►  09/08 - 09/15 (35)
    • ►  09/01 - 09/08 (35)
    • ►  08/11 - 08/18 (2)
    • ►  08/04 - 08/11 (33)
    • ►  07/28 - 08/04 (30)
    • ►  07/07 - 07/14 (11)
    • ►  06/30 - 07/07 (35)
    • ►  06/23 - 06/30 (5)
    • ►  06/02 - 06/09 (31)
    • ►  05/26 - 06/02 (20)
    • ►  05/05 - 05/12 (29)
    • ►  04/28 - 05/05 (26)
    • ►  04/07 - 04/14 (10)
    • ►  03/31 - 04/07 (34)
    • ►  03/24 - 03/31 (10)
    • ►  03/03 - 03/10 (35)
    • ►  02/25 - 03/03 (15)
    • ►  02/04 - 02/11 (22)
    • ►  01/28 - 02/04 (30)
    • ►  01/07 - 01/14 (8)
  • ►  2023 (484)
    • ►  12/31 - 01/07 (35)
    • ►  12/24 - 12/31 (10)
    • ►  12/03 - 12/10 (33)
    • ►  11/26 - 12/03 (20)
    • ►  11/05 - 11/12 (35)
    • ►  10/29 - 11/05 (20)
    • ►  10/22 - 10/29 (9)
    • ►  10/15 - 10/22 (7)
    • ►  10/08 - 10/15 (9)
    • ►  10/01 - 10/08 (10)
    • ►  09/24 - 10/01 (9)
    • ►  09/17 - 09/24 (9)
    • ►  09/10 - 09/17 (7)
    • ►  09/03 - 09/10 (9)
    • ►  08/27 - 09/03 (9)
    • ►  08/20 - 08/27 (8)
    • ►  08/13 - 08/20 (8)
    • ►  08/06 - 08/13 (8)
    • ►  07/30 - 08/06 (8)
    • ►  07/23 - 07/30 (7)
    • ►  07/16 - 07/23 (8)
    • ►  07/09 - 07/16 (7)
    • ►  07/02 - 07/09 (8)
    • ►  06/25 - 07/02 (7)
    • ►  06/18 - 06/25 (7)
    • ►  06/11 - 06/18 (7)
    • ►  06/04 - 06/11 (11)
    • ►  05/28 - 06/04 (7)
    • ►  05/21 - 05/28 (8)
    • ►  05/14 - 05/21 (11)
    • ►  05/07 - 05/14 (7)
    • ►  04/30 - 05/07 (7)
    • ►  04/23 - 04/30 (8)
    • ►  04/16 - 04/23 (9)
    • ►  04/09 - 04/16 (7)
    • ►  04/02 - 04/09 (4)
    • ►  03/26 - 04/02 (21)
    • ►  03/19 - 03/26 (2)
    • ►  03/12 - 03/19 (9)
    • ►  03/05 - 03/12 (26)
    • ►  02/26 - 03/05 (25)
    • ►  01/15 - 01/22 (7)
    • ►  01/08 - 01/15 (1)
  • ►  2022 (1037)
    • ►  12/11 - 12/18 (13)
    • ►  12/04 - 12/11 (1)
    • ►  11/27 - 12/04 (40)
    • ►  11/06 - 11/13 (1)
    • ►  10/16 - 10/23 (13)
    • ►  09/04 - 09/11 (5)
    • ►  08/21 - 08/28 (24)
    • ►  08/14 - 08/21 (24)
    • ►  07/03 - 07/10 (9)
    • ►  06/19 - 06/26 (3)
    • ►  05/29 - 06/05 (3)
    • ►  05/22 - 05/29 (3)
    • ►  05/15 - 05/22 (109)
    • ►  05/01 - 05/08 (7)
    • ►  04/24 - 05/01 (7)
    • ►  04/17 - 04/24 (64)
    • ►  04/10 - 04/17 (115)
    • ►  04/03 - 04/10 (73)
    • ►  03/27 - 04/03 (77)
    • ►  03/13 - 03/20 (2)
    • ►  03/06 - 03/13 (25)
    • ►  02/27 - 03/06 (18)
    • ►  02/20 - 02/27 (153)
    • ►  02/13 - 02/20 (187)
    • ►  01/30 - 02/06 (45)
    • ►  01/23 - 01/30 (15)
    • ►  01/16 - 01/23 (1)
  • ►  2021 (412)
    • ►  10/24 - 10/31 (2)
    • ►  07/25 - 08/01 (1)
    • ►  07/11 - 07/18 (10)
    • ►  06/13 - 06/20 (29)
    • ►  05/23 - 05/30 (1)
    • ►  05/02 - 05/09 (24)
    • ►  04/25 - 05/02 (24)
    • ►  04/18 - 04/25 (112)
    • ►  04/11 - 04/18 (1)
    • ►  04/04 - 04/11 (6)
    • ►  03/28 - 04/04 (86)
    • ►  03/21 - 03/28 (19)
    • ►  03/14 - 03/21 (2)
    • ►  03/07 - 03/14 (10)
    • ►  02/28 - 03/07 (1)
    • ►  02/21 - 02/28 (29)
    • ►  02/14 - 02/21 (13)
    • ►  02/07 - 02/14 (12)
    • ►  01/31 - 02/07 (6)
    • ►  01/17 - 01/24 (2)
    • ►  01/10 - 01/17 (8)
    • ►  01/03 - 01/10 (14)
  • ►  2020 (376)
    • ►  12/27 - 01/03 (37)
    • ►  12/20 - 12/27 (92)
    • ►  12/13 - 12/20 (29)
    • ►  12/06 - 12/13 (37)
    • ►  11/29 - 12/06 (4)
    • ►  11/15 - 11/22 (14)
    • ►  11/08 - 11/15 (8)
    • ►  11/01 - 11/08 (2)
    • ►  10/18 - 10/25 (14)
    • ►  10/11 - 10/18 (16)
    • ►  10/04 - 10/11 (10)
    • ►  09/20 - 09/27 (10)
    • ►  09/06 - 09/13 (19)
    • ►  08/30 - 09/06 (26)
    • ►  08/23 - 08/30 (4)
    • ►  08/16 - 08/23 (2)
    • ►  07/12 - 07/19 (48)
    • ►  05/17 - 05/24 (2)
    • ►  01/05 - 01/12 (2)
  • ►  2019 (74)
    • ►  07/07 - 07/14 (6)
    • ►  06/16 - 06/23 (6)
    • ►  02/10 - 02/17 (17)
    • ►  01/13 - 01/20 (37)
    • ►  01/06 - 01/13 (8)
  • ►  2018 (376)
    • ►  12/30 - 01/06 (24)
    • ►  12/16 - 12/23 (8)
    • ►  12/09 - 12/16 (98)
    • ►  12/02 - 12/09 (16)
    • ►  11/18 - 11/25 (36)
    • ►  11/04 - 11/11 (18)
    • ►  10/28 - 11/04 (10)
    • ►  10/21 - 10/28 (26)
    • ►  10/14 - 10/21 (52)
    • ►  10/07 - 10/14 (4)
    • ►  09/30 - 10/07 (2)
    • ►  09/23 - 09/30 (68)
    • ►  09/16 - 09/23 (4)
    • ►  09/09 - 09/16 (4)
    • ►  08/26 - 09/02 (6)

Data Publish News

Loading...

Al Jazeera – Breaking News, World News and Video from Al Jazeera

Loading...

Laravel News

Loading...

Copyright © CoderFunda | Powered by Blogger
Design by Coderfunda | Blogger Theme by Coderfunda | Distributed By Coderfunda