در این آموزش، اتصال کامل درگاه پرداخت تربپی به Laravel را پیادهسازی میکنیم؛ شامل:
- دریافت Access Token
- ساخت لینک پرداخت
- Callback
- Verify
- Settle
- ذخیره تراکنش
- رفع خطاهای رایج مثل 419 و verify نشدن
ساختار پروژه
در این آموزش از این بخشها استفاده میکنیم:
app/Services/TorobPayService.php
app/Http/Controllers/PaymentsController.php
routes/web.php
config/services.php
تنظیمات config/services.php
ابتدا تنظیمات ترب را اضافه کنید.
'torob' => [
'base_url' => env('TOROB_BASE_URL'),
'client_id' => env('TOROB_CLIENT_ID'),
'client_secret' => env('TOROB_CLIENT_SECRET'),
'username' => env('TOROB_USERNAME'),
'password' => env('TOROB_PASSWORD'),
],
تنظیمات .env
TOROB_BASE_URL=https://integration.torob.com
TOROB_CLIENT_ID=xxxxxxxx
TOROB_CLIENT_SECRET=xxxxxxxx
TOROB_USERNAME=xxxxxxxx
TOROB_PASSWORD=xxxxxxxx
ساخت سرویس ترب
فایل:
app/Services/TorobPayService.php
دریافت Access Token
public function getAccessToken()
{
return Cache::remember(
'torob_token_' . md5(config('services.torob.client_id')),
3500,
function () {
$basic = base64_encode(
config('services.torob.client_id')
. ':'
. config('services.torob.client_secret')
);
$res = Http::withHeaders([
'Authorization' => 'Basic ' . $basic,
'Accept' => 'application/json',
])->post(
$this->baseUrl() . '/api/online/v1/oauth/token',
[
'username' => config('services.torob.username'),
'password' => config('services.torob.password'),
]
);
if (!$res->successful()) {
throw new Exception($res->body());
}
return $res->json()['access_token'];
}
);
}
ساخت پرداخت
public function createPayment($order, $amount)
{
$token = $this->getAccessToken();
$res = Http::withToken($token)
->acceptJson()
->post(
$this->baseUrl() . '/api/online/payment/v1/token',
[
"amount" => (int)$amount,
"paymentMethodTypeDto" => "ONLINE_CREDIT",
"returnURL" => route(
'torob.callback',
['order_id' => $order->id]
),
"transactionId" => (string)$order->id,
"cartList" => [
[
"cartId" => (string)$order->id,
"totalAmount" => (int)$amount,
"shippingAmount" => 0,
"cartItems" => [
[
"id" => (string)$order->id,
"name" => "Order #" . $order->id,
"count" => 1,
"amount" => (int)$amount,
"category" => "general"
]
]
]
]
]
);
if (!$res->successful()) {
throw new Exception($res->body());
}
return $res->json()['response'];
}
Verify پرداخت
public function verifyPayment($paymentToken)
{
$token = $this->getAccessToken();
$res = Http::withToken($token)
->acceptJson()
->post(
$this->baseUrl() . '/api/online/payment/v1/verify',
[
"paymentToken" => $paymentToken
]
);
if (!$res->successful()) {
throw new Exception($res->body());
}
return $res->json()['response'];
}
Settle پرداخت
public function settlePayment($paymentToken)
{
$token = $this->getAccessToken();
$res = Http::withToken($token)
->acceptJson()
->post(
$this->baseUrl() . '/api/online/payment/v1/settle',
[
"paymentToken" => $paymentToken
]
);
if (!$res->successful()) {
throw new Exception($res->body());
}
return $res->json()['response'];
}
ساخت Route Callback
فایل:
routes/web.php
Route::match(
['get', 'post'],
'/payment/torob/callback',
[PaymentsController::class, 'torobResult']
)->name('torob.callback');
غیرفعال کردن CSRF برای Callback
فایل:
app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'payment/torob/callback',
];
متد Purchase
if ($request->gateway === 'torob') {
$torob = new TorobPayService();
// تبدیل تومان به ریال
$torobAmount = (int)$amount * 10;
$result = $torob->createPayment($order, $torobAmount);
$paymentToken = $result['paymentToken'];
$paymentUrl = $result['paymentPageUrl'];
$transaction->transaction_id = $paymentToken;
$transaction->payment_token = $paymentToken;
$transaction->save();
return redirect()->away($paymentUrl);
}
Callback و Verify
public function torobResult(Request $request)
{
try {
$orderId = $request->order_id;
$transaction = Transaction::where('order_id', $orderId)
->latest()
->first();
if (!$transaction) {
throw new \Exception('Transaction not found');
}
$paymentToken = $transaction->payment_token;
$torob = new TorobPayService();
/*
|--------------------------------------------------------------------------
| VERIFY
|--------------------------------------------------------------------------
*/
$verify = $torob->verifyPayment($paymentToken);
/*
|--------------------------------------------------------------------------
| SETTLE
|--------------------------------------------------------------------------
*/
$settle = $torob->settlePayment($paymentToken);
/*
|--------------------------------------------------------------------------
| SUCCESS
|--------------------------------------------------------------------------
*/
$transaction->status = 2;
$transaction->transaction_result = json_encode([
'verify' => $verify,
'settle' => $settle
]);
$transaction->save();
return redirect('/result?status=2');
} catch (\Exception $e) {
Log::error('Torob Error', [
'message' => $e->getMessage()
]);
return redirect('/result?status=failed');
}
}
ساخت جدول تراکنشها
نمونه فیلدهای لازم:
Schema::create('transactions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('order_id');
$table->string('transaction_id')->nullable();
$table->string('payment_token')->nullable();
$table->longText('transaction_result')->nullable();
$table->tinyInteger('status')->default(0);
$table->timestamps();
});
وضعیتهای تراکنش
| وضعیت | معنی |
|---|---|
| 0 | در انتظار پرداخت |
| 1 | ناموفق |
| 2 | موفق |
خطاهای رایج
ارور 419
دلیل:
CSRF middleware
راهحل:
protected $except = [
'payment/torob/callback',
];
Verify نشدن
دلیل:
استفاده از transaction_id اشتباه به جای payment_token
اشتباه:
$transaction->transaction_id
درست:
$transaction->payment_token
Callback خالی
در تربپی معمولاً callback پارامتر خاصی برنمیگرداند.
به همین دلیل بهتر است order_id را داخل returnURL ارسال کنید.
پاک کردن Cache لاراول
بعد از تغییرات:
php artisan optimize:clear
نتیجه نهایی
بعد از این پیادهسازی:
- پرداخت تربپی کامل کار میکند
- verify و settle انجام میشود
- callback بدون خطا اجرا میشود
- از تداخل تراکنش کاربران جلوگیری میشود
- ساختار سرویس تمیز و قابل توسعه خواهد بود





