Files
radicall/app/Services/Payment/ZibalPaymentService.php

85 lines
2.6 KiB
PHP

<?php
namespace App\Services\Payment;
use App\Enums\PaymentStatusEnum;
use App\Models\Payment;
use App\Models\User;
use Illuminate\Support\Facades\Http;
use RuntimeException;
class ZibalPaymentService
{
protected const API_URL = 'https://gateway.zibal.ir/v1';
protected const START_URL = 'https://gateway.zibal.ir/start';
public function request(User $payer, int $amount, string $orderId, array $attributes = []): Payment
{
$response = Http::post(self::API_URL . '/request', [
'merchant' => $this->merchant(),
'amount' => $amount * 10,
'callbackUrl' => $this->callbackUrl(),
'orderId' => $orderId,
])->json();
if (($response['result'] ?? null) !== 100) {
throw new RuntimeException('خطا در ایجاد درخواست پرداخت: ' . ($response['message'] ?? 'پاسخ نامعتبر از درگاه'));
}
return Payment::create(array_merge([
'track_id' => (string) $response['trackId'],
'amount' => $amount,
'status' => PaymentStatusEnum::Pending->value,
'payer_id' => $payer->id,
], $attributes));
}
public function paymentUrl(Payment $payment): string
{
return self::START_URL . '/' . $payment->track_id;
}
public function verify(Payment $payment): Payment
{
if ($payment->status !== PaymentStatusEnum::Pending) {
return $payment;
}
$response = Http::post(self::API_URL . '/verify', [
'merchant' => $this->merchant(),
'trackId' => $payment->track_id,
])->json();
if (in_array($response['result'] ?? null, [100, 201], true)) {
$payment->update([
'status' => PaymentStatusEnum::Paid->value,
'ref_number' => $response['refNumber'] ?? null,
'verified_at' => now(),
]);
} else {
$payment->update(['status' => PaymentStatusEnum::Failed->value]);
}
return $payment;
}
public function markFailed(Payment $payment): Payment
{
if ($payment->status === PaymentStatusEnum::Pending) {
$payment->update(['status' => PaymentStatusEnum::Failed->value]);
}
return $payment;
}
protected function merchant(): string
{
return config('services.zibal.sandbox') ? 'zibal' : config('services.zibal.merchant');
}
protected function callbackUrl(): string
{
return config('services.zibal.callback_url') ?: route('dashboard.payments.callback');
}
}