| Install | |
|---|---|
composer require amidesfahani/filament-payment-manager |
|
| Latest Version: | v4.0.1 |
| PHP: | ^8.1 |
A comprehensive Filament 4 plugin to manage Shetabit Payment gateways with a beautiful admin interface.

composer require amidesfahani/filament-payment-manager
php artisan vendor:publish --tag="filament-payment-manager-config"
php artisan vendor:publish --tag="filament-payment-manager-migrations"
php artisan vendor:publish --tag="filament-payment-manager-views"
php artisan migrate
Add the plugin to your Filament panel in app/Providers/Filament/AdminPanelProvider.php:
use YourVendor\FilamentPaymentManager\FilamentPaymentManagerPlugin;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugins([
FilamentPaymentManagerPlugin::make(),
]);
}
Add these to your .env file:
PAYMENT_CALLBACK_URL=https://yourdomain.com/payment/callback
PAYMENT_DEFAULT_CURRENCY=T
PAYMENT_AUTO_LOAD_GATEWAYS=true
PAYMENT_ENABLE_LOGGING=false
The config file config/filament-payment-manager.php allows you to customize:
use YourVendor\FilamentPaymentManager\Services\PaymentManagerService;
use Shetabit\Multipay\Invoice;
// Get the service
$paymentManager = app(PaymentManagerService::class);
// Create an invoice
$invoice = new Invoice();
$invoice->amount(10000); // Amount in Toman or Rial
// Create payment (uses default gateway)
$payment = $paymentManager->createPayment($invoice->getAmount());
// Or specify a gateway
$payment = $paymentManager->createPayment($invoice->getAmount(), 'zarinpal');
// Purchase and get transaction ID
try {
$transactionId = $payment->purchase($invoice, function($driver, $transactionId) {
// Store transaction ID in your database
})->pay()->render();
} catch (\Exception $e) {
// Handle error
}
use YourVendor\FilamentPaymentManager\Services\PaymentManagerService;
use Shetabit\Payment\Facade\Payment;
public function callback(Request $request)
{
$paymentManager = app(PaymentManagerService::class);
try {
$receipt = $paymentManager->verifyPayment();
// Payment successful
$referenceId = $receipt->getReferenceId();
// Update your order status
return redirect()->route('payment.success');
} catch (\Exception $e) {
// Payment failed
return redirect()->route('payment.failed');
}
}
$paymentManager = app(PaymentManagerService::class);
// Get all active gateways
$gateways = $paymentManager->getActiveGateways();
// Get default gateway
$defaultGateway = $paymentManager->getDefaultGateway();
// Get specific gateway by driver
$gateway = $paymentManager->getGatewayByDriver('zarinpal');
You have three options for redirect forms:
Beautiful, modern redirect form with countdown timer and animations.
Create your own Blade view:
{{-- resources/views/payments/custom-redirect.blade.php --}}
<!DOCTYPE html>
<html>
<head>
<title>Payment Redirect</title>
</head>
<body>
<h1>Redirecting to payment...</h1>
<form method="{{ $method }}" action="{{ $action }}" id="payment-form">
@foreach($inputs as $name => $value)
<input type="hidden" name="{{ $name }}" value="{{ $value }}">
@endforeach
<button type="submit">Continue</button>
</form>
<script>
document.getElementById('payment-form').submit();
</script>
</body>
</html>
Then set in gateway: payments.custom-redirect
Use placeholders in your HTML:
<form method="{method}" action="{action}">
{inputs}
<button>Pay Now</button>
</form>
<script>document.forms[0].submit();</script>
[
'merchantId' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
'callbackUrl' => 'https://yourdomain.com/payment/callback',
'description' => 'Payment for Order #123',
'currency' => 'T', // T=Toman, R=Rial
'mode' => 'normal', // normal, sandbox, zaringate
]
[
'merchantId' => 'your-merchant-id',
'password' => 'your-password',
'callbackUrl' => 'https://yourdomain.com/payment/callback',
'currency' => 'T',
]
[
'clientId' => 'your-client-id',
'clientSecret' => 'your-client-secret',
'callbackUrl' => 'https://yourdomain.com/payment/callback',
'currency' => 'USD',
'mode' => 'normal', // normal or sandbox
]
[
'secret' => 'sk_test_xxxxxxxxxxxxx',
'currency' => 'usd',
'success_url' => 'https://yourdomain.com/payment/success',
'cancel_url' => 'https://yourdomain.com/payment/cancel',
]
If you disable auto-loading in config:
use YourVendor\FilamentPaymentManager\Services\PaymentManagerService;
use YourVendor\FilamentPaymentManager\Models\PaymentGateway;
$paymentManager = app(PaymentManagerService::class);
// Load specific gateway
$gateway = PaymentGateway::where('driver', 'zarinpal')->first();
$paymentManager->registerGateway($gateway);
use YourVendor\FilamentPaymentManager\Models\PaymentGateway;
use YourVendor\FilamentPaymentManager\Services\PaymentManagerService;
$gateway = PaymentGateway::find(1);
$paymentManager = app(PaymentManagerService::class);
$html = $paymentManager->getRedirectForm(
$gateway,
'https://payment.gateway.com/pay',
'POST',
['token' => 'abc123', 'amount' => 10000]
);
return response($html);
| Method | Description |
|---|---|
createPayment($amount, $driver = null) |
Create a new payment |
verifyPayment($driver = null) |
Verify a payment callback |
getActiveGateways() |
Get all active gateways |
getDefaultGateway() |
Get the default gateway |
getGatewayByDriver($driver) |
Get gateway by driver name |
registerGateway(PaymentGateway $gateway) |
Manually register a gateway |
getRedirectForm($gateway, $action, $method, $inputs) |
Get custom redirect form HTML |
| Property | Type | Description |
|---|---|---|
name |
string | Gateway display name |
driver |
string | Payment driver name |
is_active |
boolean | Active status |
is_default |
boolean | Default gateway flag |
config |
array | Gateway configuration |
callback_url |
string | Custom callback URL |
redirect_form_view |
string | Custom Blade view path |
redirect_form_html |
string | Custom HTML template |
sort_order |
integer | Display order |
description |
string | Internal notes |
The package includes a local test gateway:
// In Filament, create a gateway with driver 'local'
// This allows you to test payment flow without real credentials
Many gateways support sandbox mode:
// Zarinpal
'mode' => 'sandbox'
// PayPal
'mode' => 'sandbox'
Make sure your callback URL:
Iranian gateways typically require amounts in Rial, but you can use Toman by setting currency => 'T' in config. The package handles conversion automatically.
Contributions are welcome! Please submit pull requests or issues on GitHub.
This package is open-source software licensed under the MIT license.
For issues and questions: