feat: add withdraw request functionality and UI components

This commit is contained in:
2026-08-27 02:39:57 +03:30
parent aeef95339d
commit 4ce663c669
115 changed files with 4064 additions and 315 deletions
@@ -0,0 +1,97 @@
<?php
namespace App\Http\Controllers\Client;
use App\Enums\InvoicePaymentMethodEnum;
use App\Enums\InvoiceStatusEnum;
use App\Enums\PaymentPurposeEnum;
use App\Enums\PaymentStatusEnum;
use App\Enums\WalletTransactionReasonEnum;
use App\Http\Controllers\Controller;
use App\Http\Requests\Client\PaymentRequest;
use App\Http\Resources\Client\PaymentResource;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\Invoice\InvoiceService;
use App\Services\Payment\ZibalPaymentService;
use App\Services\Wallet\WalletService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class PaymentController extends Controller
{
protected ZibalPaymentService $zibalPaymentService;
protected WalletService $walletService;
protected InvoiceService $invoiceService;
public function __construct(ZibalPaymentService $zibalPaymentService, WalletService $walletService, InvoiceService $invoiceService)
{
$this->zibalPaymentService = $zibalPaymentService;
$this->walletService = $walletService;
$this->invoiceService = $invoiceService;
}
public function store(PaymentRequest $request)
{
$invoice = Invoice::where('id', $request->invoice_id)
->where('user_id', Auth::id())
->where('status', InvoiceStatusEnum::Pending->value)
->firstOrFail();
$payment = $this->zibalPaymentService->request(Auth::user(), $invoice->amount, $invoice->number, [
'purpose' => PaymentPurposeEnum::Invoice->value,
'invoice_id' => $invoice->id,
]);
return response()->json([
'payment' => new PaymentResource($payment),
'url' => $this->zibalPaymentService->paymentUrl($payment),
]);
}
public function callback(Request $request)
{
$payment = Payment::where('track_id', $request->trackId)->first();
if (!$payment) {
return redirect()->route('dashboard.index');
}
$wasPending = $payment->status === PaymentStatusEnum::Pending;
if ($request->success == 1) {
$payment = $this->zibalPaymentService->verify($payment);
} else {
$payment = $this->zibalPaymentService->markFailed($payment);
}
if ($wasPending && $payment->status === PaymentStatusEnum::Paid) {
$this->settle($payment);
}
session()->flash('payment_result', [
'status' => $payment->status === PaymentStatusEnum::Paid ? 'paid' : 'failed',
'track_id' => $payment->track_id,
'purpose' => $payment->purpose->name,
]);
return redirect()->route('dashboard.index');
}
protected function settle(Payment $payment): void
{
if ($payment->purpose === PaymentPurposeEnum::WalletTopUp) {
$this->walletService->deposit($payment->payer, $payment->amount, WalletTransactionReasonEnum::TopUp, $payment);
return;
}
$invoice = $payment->invoice;
if ($invoice && $invoice->status === InvoiceStatusEnum::Pending) {
$this->invoiceService->markPaid($invoice, InvoicePaymentMethodEnum::Gateway);
$this->walletService->recordGatewayInvoicePayment($invoice, $payment);
}
}
}