Search by

the6fallenangel / variza-laravel

the6fallenangel

Laravel package for Variza payment gateway — create payment links and handle webhooks with Laravel-native events.

Package info

github.com/the6fallenangel/variza-laravel

pkg:composer/the6fallenangel/variza-laravel

Fund package maintenance!

the6fallenangel.github.io/support

Statistics

Installs: 5

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.3.0 2026-09-18 22:47 UTC

This package is auto-updated.

Last update: 2026-09-18 22:48:49 UTC


README

Variza

پکیج لاراول واریزا

پکیج رسمی واریزا برای اتصال سریع و ساده برنامه‌های لاراول به سرویس پرداخت واریزا.

PHP Version Tests Packagist Version Packagist Downloads License

این پکیج ابزارهای لازم برای ایجاد لینک پرداخت، دریافت و اعتبارسنجی وب‌هوک‌ها و مدیریت رویدادهای پرداخت را در اختیار شما قرار می‌دهد و به‌صورت یکپارچه با اکوسیستم لاراول کار می‌کند.

📦 نصب

برای نصب پکیج، دستور زیر را اجرا کنید:

composer require the6fallenangel/variza-laravel

پس از نصب، فایل تنظیمات پکیج را با دستور زیر منتشر کنید:

php artisan vendor:publish --tag=variza-config

⚙️ پیکربندی

ابتدا کلید API و کلید امضای وب‌هوک واریزا را در فایل .env قرار دهید:

VARIZA_API_TOKEN=your-api-token-here
VARIZA_WEBHOOK_SECRET=your-webhook-secret-here

برای دریافت این کلیدها:

  1. وارد پنل واریزا شوید.
  2. در بخش پروفایل، گزینه کلید API را پیدا کنید و یک کلید جدید بسازید.
  3. در همان بخش، کلید امضای وب‌هوک را نیز دریافت کنید.

سپس آدرس وب‌هوک برنامه خود را از مسیر پروفایل ← وب‌هوک در پنل واریزا ثبت کنید:

https://yourdomain.com/variza/webhook

🚀 ایجاد لینک پرداخت

با استفاده از Facade واریزا می‌توانید تنها با چند خط کد یک لینک پرداخت ایجاد کنید:

use The6FallenAngel\VarizaLaravel\Facades\Variza;
use The6FallenAngel\VarizaLaravel\DTOs\PaymentLinkRequest;
use The6FallenAngel\VarizaLaravel\DTOs\Expiry;

$paymentLink = Variza::createPaymentLink(new PaymentLinkRequest(
    amount: 500000,                                    // مبلغ به تومان (حداقل 1000)
    returnUrl: route('order.callback'),                // آدرس بازگشت
    title: 'Order #123',                               // اختیاری
    cardLast4: '1234',                                 // اختیاری — انتخاب کارت مشخص
    expiresIn: Expiry::OneHour,                        // اختیاری — مدت اعتبار لینک
    memberPhone: '09123456789',                        // اختیاری — شماره موبایل عضو مارکت‌پلیس
));

// کارت تصادفی — توزیع خودکار بار
$paymentLink = Variza::createPaymentLink(new PaymentLinkRequest(
    amount: 500000,
    returnUrl: route('order.callback'),
    cardLast4: PaymentLinkRequest::RANDOM_CARD, // or 'random' — pick least-load active card
));

// کارت‌های واریزا — تسویه کیف‌پول با تتر
$paymentLink = Variza::createPaymentLink(new PaymentLinkRequest(
    amount: 500000,
    returnUrl: route('order.callback'),
    cardLast4: PaymentLinkRequest::VARIZA_CARDS, // or 'variza' — buyer pays Variza cards, wallet credited in Toman
));

// انتقال کاربر به صفحه پرداخت
return redirect($paymentLink->payUrl);

🔀 توزیع هوشمند بار (کارت تصادفی) — با ارسال cardLast4: PaymentLinkRequest::RANDOM_CARD یا 'random'، سیستم در لحظه‌ی پرداخت از بین کارت‌های فعال شما، کارتی با کمترین تعداد تراکنش موفق امروز را انتخاب می‌کند (در صورت تساوی، تصادفی). نیازمند اشتراک دارای قابلیت «کارت تصادفی» و حداقل ۲ کارت فعال؛ در غیر این صورت API خطای ۴۲۲ برمی‌گرداند.

💼 کارت‌های واریزا (تسویه کیف‌پول) — با ارسال cardLast4: PaymentLinkRequest::VARIZA_CARDS یا 'variza'، خریدار به کارت واریزا واریز می‌کند و نیازی به ثبت کارت بانکی ندارید؛ کیف‌پول شما به تومان (پس از کسر کارمزد) شارژ و قابل برداشت به‌صورت تتر (USDT) است. نیازمند اشتراک دارای قابلیت «کارت‌های واریزا» و سقف مبلغ هر لینک ۲٬۰۰۰٬۰۰۰ تومان؛ در غیر این صورت API خطای ۴۲۲ برمی‌گرداند.

🏪 مارکت‌پلیس — اگر از پلن مارکت‌پلیس استفاده می‌کنید، مالک می‌تواند با ارسال memberPhone (شماره 09xxxxxxxxx عضو ) لینک را به نام آن عضو ایجاد کند. کارت مقصد و محدودیت‌ها مربوط به عضو سنجیده می‌شود ولی اعتبار از مالک کسر و وب‌هوک به آدرس مالک ارسال می‌گردد.

استفاده از Dependency Injection

در صورت تمایل می‌توانید به‌جای Facade، کلاینت واریزا را با Dependency Injection دریافت کنید:

use The6FallenAngel\VarizaLaravel\VarizaClient;
use The6FallenAngel\VarizaLaravel\DTOs\PaymentLinkRequest;

class CheckoutController extends Controller
{
    public function __construct(private VarizaClient $variza)
    {
    }

    public function pay()
    {
        $paymentLink = $this->variza->createPaymentLink(
            new PaymentLinkRequest(
                amount: 500000,
                returnUrl: route('order.callback'),
            )
        );

        return redirect($paymentLink->payUrl);
    }
}

مدت اعتبار لینک پرداخت

برای مشخص‌کردن مدت اعتبار لینک، می‌توانید از مقادیر آماده Expiry استفاده کنید:

ثابت مقدار توضیح
Expiry::ThirtyMinutes 30m ۳۰ دقیقه
Expiry::OneHour 1h ۱ ساعت
Expiry::TwoHours 2h ۲ ساعت
Expiry::SixHours 6h ۶ ساعت
Expiry::OneDay 1d ۱ روز
Expiry::ThreeDays 3d ۳ روز
Expiry::OneWeek 1w ۱ هفته
Expiry::Never never بدون انقضا

🔔 وب‌هوک و رویدادهای پرداخت

پس از تأیید موفق پرداخت، واریزا یک وب‌هوک به برنامه شما ارسال می‌کند. این پکیج به‌صورت خودکار مراحل زیر را انجام می‌دهد:

  1. امضای وب‌هوک را با Middleware بررسی می‌کند.
  2. رویداد PaymentPaid را اجرا می‌کند.
  3. به شما اجازه می‌دهد این رویداد را با Listener یا Queue پردازش کنید.

ایجاد Listener

برای ساخت Listener دستور زیر را اجرا کنید:

php artisan make:listener CompleteOrderPayment

سپس می‌توانید Listener را به شکل زیر پیاده‌سازی کنید:

namespace App\Listeners;

use The6FallenAngel\VarizaLaravel\Events\PaymentPaid;
use App\Models\Order;

class CompleteOrderPayment
{
    public function handle(PaymentPaid $event): void
    {
        $payload = $event->payload;

        // پیدا کردن سفارش بر اساس slug
        $order = Order::where('payment_slug', $payload->slug)->first();

        if ($order && $order->status !== 'paid') {
            $order->update([
                'status' => 'paid',
                'payment_code' => $payload->attemptCode,
                'paid_amount' => $payload->amount,
                'paid_at' => now(),
            ]);

            // اگر پرداخت مربوط به عضو مارکت‌پلیس بوده:
            // $memberPhone = $payload->memberPhone; // '09123456789' | null

            // ارسال ایمیل، پیامک و سایر اقدامات موردنیاز
        }
    }
}

ثبت Listener

Listener را در EventServiceProvider برنامه خود ثبت کنید:

use The6FallenAngel\VarizaLaravel\Events\PaymentPaid;
use App\Listeners\CompleteOrderPayment;

protected $listen = [
    PaymentPaid::class => [
        CompleteOrderPayment::class,
    ],
];

پردازش ناهمزمان با Queue

اگر پردازش رویداد زمان‌بر است، می‌توانید Listener را به‌صورت queued اجرا کنید:

namespace App\Listeners;

use Illuminate\Contracts\Queue\ShouldQueue;
use The6FallenAngel\VarizaLaravel\Events\PaymentPaid;

class CompleteOrderPayment implements ShouldQueue
{
    public function handle(PaymentPaid $event): void
    {
        // پردازش‌های زمان‌بر
    }
}

⚠️ نکته مهم درباره وب‌هوک

پردازش وب‌هوک باید Idempotent باشد؛ یعنی اگر یک رویداد بیش از یک‌بار دریافت شد، نباید باعث ثبت دوباره پرداخت یا تغییر اشتباه وضعیت سفارش شود.

واریزا در صورت دریافت پاسخ نامعتبر یا در صورت عدم دریافت پاسخ موفق از سرور شما، رویداد را دوباره ارسال می‌کند. ارسال‌های مجدد با فاصله‌های ۳۰، ۶۰، ۱۸۰ و ۶۰۰ ثانیه انجام می‌شوند و هر رویداد حداکثر ۵ بار ارسال خواهد شد.

به همین دلیل، در Listener خود حتماً بررسی کنید که سفارش قبلاً پرداخت نشده باشد.

🚨 مدیریت خطاها

وضعیت HTTP استثنا توضیح
422 ValidationException خطای اعتبارسنجی درخواست
429 RateLimitException عبور از محدودیت نرخ درخواست
سایر ApiException سایر خطاهای API
InvalidSignatureException امضای وب‌هوک نامعتبر است
use The6FallenAngel\VarizaLaravel\Facades\Variza;
use The6FallenAngel\VarizaLaravel\Exceptions\ValidationException;
use The6FallenAngel\VarizaLaravel\Exceptions\RateLimitException;

try {
    $paymentLink = Variza::createPaymentLink($request);
} catch (ValidationException $e) {
    // ورودی‌های نامعتبر
    logger()->error('Variza validation error', [
        'errors' => $e->errors,
        'status' => $e->status,
    ]);
} catch (RateLimitException $e) {
    // محدودیت نرخ درخواست
    return back()->with('error', 'لطفاً چند لحظه صبر کنید و دوباره تلاش کنید.');
} catch (\Exception $e) {
    // سایر خطاها
    logger()->error('Variza API error', ['message' => $e->getMessage()]);
}

🧪 تست

این پکیج همراه با مجموعه تست ارائه می‌شود. برای نصب وابستگی‌ها و اجرای تست‌ها:

composer install
composer test

⚙️ تنظیمات پیشرفته

برای مشاهده یا شخصی‌سازی تنظیمات پکیج، فایل config/variza.php را بررسی کنید:

return [
    // کلید API واریزا
    'api_token' => env('VARIZA_API_TOKEN'),

    // کلید امضای وب‌هوک
    'webhook_secret' => env('VARIZA_WEBHOOK_SECRET'),

    // آدرس پایه API (معمولاً نیازی به تغییر ندارد)
    'base_url' => env('VARIZA_BASE_URL', 'https://variza.ir/api/v1'),

    // مسیر دریافت وب‌هوک
    'webhook_path' => env('VARIZA_WEBHOOK_PATH', 'variza/webhook'),

    // تایم‌اوت درخواست (بر حسب ثانیه)
    'timeout' => env('VARIZA_TIMEOUT', 30),
];

📚 مستندات و منابع

🤝 مشارکت

برای گزارش باگ، درخواست قابلیت جدید یا پیشنهاد بهبود، از بخش Issues استفاده کنید.

📄 مجوز

این پکیج تحت مجوز MIT منتشر شده است.

برای آشنایی بیشتر با واریزا و سایر قابلیت‌های آن به variza.ir مراجعه کنید.

🇬🇧 English

Variza Laravel Package is the official Laravel package for connecting Laravel applications to the Variza payment service — create payment links, receive and verify webhooks, and handle payment events seamlessly integrated with the Laravel ecosystem.

📦 Installation

composer require the6fallenangel/variza-laravel
php artisan vendor:publish --tag=variza-config

Configuration

Add your Variza credentials to .env:

VARIZA_API_TOKEN=your-api-token-here
VARIZA_WEBHOOK_SECRET=your-webhook-secret-here

Register your webhook URL in the Variza panel:

https://yourdomain.com/variza/webhook

Create a payment link

use The6FallenAngel\VarizaLaravel\Facades\Variza;
use The6FallenAngel\VarizaLaravel\DTOs\PaymentLinkRequest;
use The6FallenAngel\VarizaLaravel\DTOs\Expiry;

$paymentLink = Variza::createPaymentLink(new PaymentLinkRequest(
    amount: 500000,                     // amount in Toman (min 1000)
    returnUrl: route('order.callback'),
    title: 'Order #123',                // optional
    expiresIn: Expiry::OneHour,         // optional
    memberPhone: '09123456789',         // optional — marketplace team member phone
));

// random least-load card — automatic distribution
$paymentLink = Variza::createPaymentLink(new PaymentLinkRequest(
    amount: 500000,
    returnUrl: route('order.callback'),
    cardLast4: PaymentLinkRequest::RANDOM_CARD, // or 'random' — pick active card with least successful transactions today
));

// Variza cards — wallet settlement in Toman, withdrawable as USDT
$paymentLink = Variza::createPaymentLink(new PaymentLinkRequest(
    amount: 500000,
    returnUrl: route('order.callback'),
    cardLast4: PaymentLinkRequest::VARIZA_CARDS, // or 'variza' — buyer pays Variza cards, no seller bank account needed
));

return redirect($paymentLink->payUrl);

🔀 Smart load distribution (random card) — Pass cardLast4: PaymentLinkRequest::RANDOM_CARD or 'random' to let Variza auto-pick the active card with the fewest successful transactions today (random tie-break). Requires a plan with the Random Card feature and at least 2 active cards; otherwise the API returns 422.

💼 Variza cards (wallet settlement) — Pass cardLast4: PaymentLinkRequest::VARIZA_CARDS or 'variza' and the buyer pays Variza cards with no seller bank account needed; your wallet is credited in Toman (after fee) and withdrawable as USDT. Requires a plan with the Variza Cards feature, max 2,000,000 Toman per link; otherwise the API returns 422.

🏪 Marketplace — If you use a marketplace team plan, the owner can pass memberPhone (09xxxxxxxxx of a member) to create the link on behalf of that member. Destination card and limits are checked against the member, but credit is deducted from the owner and webhook is delivered to owner's callback_url.

Handle webhook events

Create a listener:

php artisan make:listener CompleteOrderPayment
namespace App\Listeners;

use The6FallenAngel\VarizaLaravel\Events\PaymentPaid;
use App\Models\Order;

class CompleteOrderPayment
{
    public function handle(PaymentPaid $event): void
    {
        $order = Order::where('payment_slug', $event->payload->slug)->first();

        if ($order && $order->status !== 'paid') {
            $order->update([
                'status' => 'paid',
                'payment_code' => $event->payload->attemptCode,
                'paid_at' => now(),
            ]);

            // if payment was for a marketplace member:
            // $memberPhone = $event->payload->memberPhone; // '09123456789' | null
        }
    }
}

Register the listener in EventServiceProvider:

use The6FallenAngel\VarizaLaravel\Events\PaymentPaid;
use App\Listeners\CompleteOrderPayment;

protected $listen = [
    PaymentPaid::class => [
        CompleteOrderPayment::class,
    ],
];

Error handling

use The6FallenAngel\VarizaLaravel\Exceptions\ValidationException;
use The6FallenAngel\VarizaLaravel\Exceptions\RateLimitException;

try {
    $paymentLink = Variza::createPaymentLink($request);
} catch (ValidationException $e) {
    // invalid input
} catch (RateLimitException $e) {
    // rate limited
}

Testing

composer test

Documentation

License

Released under the MIT license. Visit variza.ir to learn more.