dashti-amin / laravel-snapp-pay
Laravel Snapp Pay installment payment gateway based on the official Snapp Pay WooCommerce gateway flow.
Requires
- php: ^8.1
- illuminate/cache: ^10.0|^11.0|^12.0
- illuminate/config: ^10.0|^11.0|^12.0
- illuminate/console: ^10.0|^11.0|^12.0
- illuminate/database: ^10.0|^11.0|^12.0
- illuminate/http: ^10.0|^11.0|^12.0
- illuminate/routing: ^10.0|^11.0|^12.0
- illuminate/support: ^10.0|^11.0|^12.0
This package is auto-updated.
Last update: 2026-08-09 15:24:44 UTC
README
کتابخانه Laravel برای درگاه اقساطی Snapp Pay، بر اساس flow موجود در افزونه WooCommerce snapppay-woocommerce-gateway-v1.4.2.
قابلیتها
- OAuth Password Grant و cache کردن Bearer Token
- بررسی eligibility
- دریافت payment token
- redirect به
paymentPageUrl - callback با
state=OK - Verify
- Settle
- Cancel
- Status
- Update
- تبدیل تومان/ریال
- نرمالسازی شماره موبایل ایران
- ثبت تراکنش مستقل در دیتابیس
- retry خودکار بعد از HTTP 401
- TLS verification فعال بهصورت پیشفرض
- سازگار با Laravel 10/11/12 و PHP 8.1+
نصب
برای توسعه محلی:
composer require amin/laravel-snapp-pay
اگر پکیج را بهصورت local repository نگه میداری:
"repositories": [ { "type": "path", "url": "../laravel-snapp-pay" } ]
سپس:
composer require amin/laravel-snapp-pay:@dev php artisan vendor:publish --tag=snapp-pay-config php artisan vendor:publish --tag=snapp-pay-migrations php artisan migrate
.env
SNAPP_PAY_BASE_URL=https://api.snapppay.ir SNAPP_PAY_CLIENT_ID= SNAPP_PAY_CLIENT_SECRET= SNAPP_PAY_CLIENT_USERNAME= SNAPP_PAY_CLIENT_PASSWORD= SNAPP_PAY_AMOUNT_CURRENCY=toman SNAPP_PAY_TIMEOUT=30 SNAPP_PAY_CONNECT_TIMEOUT=10 SNAPP_PAY_VERIFY_SSL=true SNAPP_PAY_CALLBACK_URL=https://example.com/payment/snapp-pay/callback SNAPP_PAY_SUCCESS_URL=https://example.com/payment/result SNAPP_PAY_FAILURE_URL=https://example.com/payment/failed
پرداخت
use Amin\SnappPay\Facades\SnappPay; use Amin\SnappPay\DTO\PaymentRequest; $transactionId = now()->format('YmdHis') . '-' . $order->id; $payment = new PaymentRequest( amount: SnappPay::toRial($order->payable_amount, 'toman'), transactionId: $transactionId, returnUrl: route('snapp-pay.callback', [ 'transaction_id' => $transactionId, ]), mobile: SnappPay::normalizeMobile($order->mobile), cartItems: [ [ 'name' => 'محصول نمونه', 'count' => 1, 'amount' => SnappPay::toRial(500000, 'toman'), 'id' => 123, 'category' => 'دستهبندی', ], ], ); $result = SnappPay::createPayment($payment); return redirect()->away($result['payment_page_url']);
Callback
مسیر پیشفرض:
POST|GET /payment/snapp-pay/callback
در callback:
- transaction_id پیدا میشود.
- اگر state غیر OK باشد تراکنش cancelled میشود.
- paymentToken از تراکنش خوانده میشود.
- Verify انجام میشود.
- در صورت موفقیت Settle انجام میشود.
- تراکنش به
settledتغییر میکند.
نکته مهم: اتصال وضعیت سفارش فروشگاه به snapp_pay_transactions عمداً داخل مدل Order شما hard-code نشده است. بعد از settle باید سفارش خودتان را با transaction_id یا meta رابطه بدهید و paid/processing کنید.
API مستقیم
SnappPay::eligible(1000000, 'toman'); SnappPay::verify($paymentToken); SnappPay::settle($paymentToken); SnappPay::cancel($paymentToken); SnappPay::status($paymentToken);
نکته امنیتی
نسخه WooCommerce که از آن استخراج شده بود SSL verification را خاموش میکرد. این کتابخانه آن رفتار ناامن را کپی نمیکند و TLS را بهصورت پیشفرض verify میکند.
همچنین telemetry / ارسال اطلاعات فعالسازی افزونه WordPress به Google Sheets عمداً به Laravel منتقل نشده است؛ برای درگاه پرداخت هیچ ضرورتی ندارد.
معماری پیشنهادی برای پروژه فروشگاهی
بهتر است SnappPayTransaction فقط لاگ/رکورد پرداخت باشد و Order اصلی پروژه شما همچنان منبع اصلی وضعیت سفارش بماند.
برای هر سفارش:
orders
|
+-- payment transaction
|
+-- transaction_id
+-- payment_token
+-- amount
+-- status
در callback بعد از settle:
$order->markAsPaid(...);
و callback را idempotent نگه دارید تا refresh یا ارسال مجدد callback باعث دوبارهپرداخت نشود.