codersandip/laravel-multi-payment-gateway

A unified payment gateway wrapper for Indian-focused gateways (Razorpay, PayU, Stripe, Cashfree).

Maintainers

Package info

github.com/codersandip/laravel-multi-payment-gateway

pkg:composer/codersandip/laravel-multi-payment-gateway

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-02-26 20:31 UTC

This package is auto-updated.

Last update: 2026-04-04 18:53:33 UTC


README

A unified, production-ready payment gateway package for Indian-focused gateways (Razorpay, PayU, Stripe, Cashfree). Built specifically for Laravel 10+, implementing clean architecture, SOLID principles, and an automatic driver failover mechanism.

Features

  • Driver-based Architecture: Clean abstractions over multiple gateways.
  • Database Tracking: Eloquent models log all transactions, allowing instant audit trails.
  • Failover & Retries: Automatic retries for failed requests, and fallback to secondary gateways.
  • Robust Event System: Automatically dispatches PaymentSuccess and PaymentFailed events.
  • Async Queue Jobs: Run payment actions in the background.
  • Auto-Reconciliation Artisan Command: Scheduled DB cleanup for pending webhooks.
  • Extensible: Easily register custom drivers.
  • Centralized Logging: Dedicated channel logging for all gateway interactions.
  • Unified Standard Response: Predictable array returns [success, gateway, transaction_id, status, message, raw].
  • No Third-Party SDKs: Powered completely by Laravel's built-in HTTP client (Illuminate\Support\Facades\Http).

Installation

You can install the package via Composer:

composer require codersandip/laravel-multi-payment-gateway

Publish the configuration file and migrate the database:

php artisan vendor:publish --provider="Codersandip\MultiPayment\MultiPaymentServiceProvider" --tag="config"
php artisan migrate

Configuration

In config/multi-payment.php, you can set the default driver, failover drivers, error logging channel, and the allowed retries before moving to a fallback.

'default' => 'razorpay',
'failovers' => ['stripe', 'cashfree'],
'retries' => [
    'attempts' => 2,
    'sleep' => 1000, // milliseconds
],

Usage

1. Basic Charge

use Codersandip\MultiPayment\Facades\MultiPayment;

$response = MultiPayment::charge([
    'amount' => 500,
    'currency' => 'INR',
    'email' => 'customer@test.com',
    'phone' => '9999999999',
]);

2. Async Background Process

If you wish to handle the request later in the background through the Laravel Queue, simply use:

MultiPayment::chargeAsync([
    'amount' => 500,
    'currency' => 'INR',
]);

3. Failover Execution

The manager automatically attempts the charge via the default gateway using Laravel's native retry() mechanism. If all retries exhaust, the manager catches the Exception and automatically shifts to the failover stack (e.g. from Razorpay directly to Stripe).

4. Events System

The package fires standard events whenever a gateway successfully completes an API execution or exhausts all retries resulting in an error.

To listen to these events, register listeners in EventServiceProvider:

use Codersandip\MultiPayment\Events\PaymentSuccess;
use Codersandip\MultiPayment\Events\PaymentFailed;

protected $listen = [
    PaymentSuccess::class => [
        SendPaymentReceipt::class,
    ],
    PaymentFailed::class => [
        AlertSupportTeam::class,
    ],
];

5. Custom Driver Extensibility

Thanks to Laravel's Manager pattern, extending this package with any custom gateway is trivial. Inside your AppServiceProvider boot method:

use Codersandip\MultiPayment\Facades\MultiPayment;
use App\Payment\CustomGatewayDriver;

MultiPayment::extend('custom_gateway', function ($app) {
    return new CustomGatewayDriver(config('services.custom'));
});

Then use it instantly: MultiPayment::driver('custom_gateway')->charge(...)

Webhooks

We provide a built-in macro to handle webhooks asynchronously across any enabled gateway. Register this in your routes/api.php:

Route::paymentWebhooks('webhooks/payments');

This automatically handles verified posts to /api/webhooks/payments/razorpay, .../stripe, etc.

Database & Auto Reconciliation

Every charge request securely logs an pending Eloquent PaymentTransaction before communicating with the Gateway. Once a gateway returns successfully (or fails across all failovers), the DB is synced seamlessly.

If a Sandbox Sandbox or webhooks drop instantly, you can run and schedule our artisan command to manually query the Gateways and fix all drifted pending payments:

php artisan payment:reconcile-pending --days=3

You can cleanly schedule this in Laravel's Console/Kernel.php:

$schedule->command('payment:reconcile-pending')->hourly();

Frontend / Blade Components

The package natively ships with beautiful, pre-configured Blade Components targeting the official JavaScript SDK/Widgets of every supported gateway!

You can easily publish these views to customize them locally:

php artisan vendor:publish --tag="multi-payment-views"

Once a charge executes, pass the payload $response to any component in your blade file. They automatically mount the UI and redirect to your specified $verifyUrl upon success!

{{-- Stripe Elements --}}
@include('multi-payment::components.stripe', [
    'response' => $chargeResponse,
    'verifyUrl' => route('payment.verify') 
])

{{-- Razorpay Checkout js Modal --}}
@include('multi-payment::components.razorpay', [
    'response' => $chargeResponse,
    'verifyUrl' => route('payment.verify'),
    'themeColor' => '#ff0000', // Optional
])

{{-- Cashfree SDK Modal --}}
@include('multi-payment::components.cashfree', [
    'response' => $chargeResponse
])

{{-- PayU Auto-Submit Form --}}
@include('multi-payment::components.payu', [
    'response' => $chargeResponse,
    'autoOpen' => true 
])

Testing

The package relies on orchestra/testbench for Laravel container bindings. Run tests natively via PHPUnit:

composer require --dev orchestra/testbench phpunit/phpunit
vendor/bin/phpunit