json($this->payments->publicOptions()); } public function initiate(Request $request) { $gateway = $this->payments->resolve(); if (!$gateway || !$gateway->isAvailable()) { throw new UnprocessableEntityHttpException('پرداخت آنلاین در حال حاضر فعال نیست'); } $amount = (int) $request->input('value', $request->input('amount', 0)); $minDeposit = $this->config->getInt('min_deposit', 0); if ($amount < 1000) { throw new UnprocessableEntityHttpException('حداقل مبلغ پرداخت ۱۰۰۰ ریال است'); } if ($minDeposit > 0 && $amount < $minDeposit) { throw new UnprocessableEntityHttpException( 'حداقل مقدار واریز ' . number_format($minDeposit) . ' ریال است' ); } $customer = auth('customer')->user(); $withdraw = Withdraw::create([ 'customer_id' => $customer->id, 'cash' => $amount, 'note' => 'واریز آنلاین', 'sts' => 1, ]); $referenceId = 'WD-' . $withdraw->id; try { $result = $gateway->initiate([ 'amount' => $amount, 'reference_id' => $referenceId, 'description' => 'شارژ کیف پول کاربر ' . ($customer->name ?? $customer->id), 'metadata' => [ 'withdraw_id' => $withdraw->id, 'customer_id' => $customer->id, ], ]); } catch (RuntimeException $e) { $withdraw->sts = 3; $withdraw->save(); \Log::warning('wallet.payment.initiate_failed', [ 'withdraw_id' => $withdraw->id, 'message' => $e->getMessage(), ]); return response()->json([ 'message' => $e->getMessage() ?: 'مشکل در ارتباط با درگاه', ], 422); } if (!empty($result['session_id'])) { $withdraw->tracked_number = (string) $result['session_id']; $withdraw->save(); } // حداقل اطلاعات برای redirect — بدون credential و بدون جزئیات داخلی درگاه return response()->json([ 'payment_url' => $result['payment_url'], ], 201); } /** * وریفای برگشت مرورگر از فرانت — امضا و شارژ سمت سرور؛ بدون افشای secret. * Body یا query: status, reference_id, session_id, amount, track_number, timestamp, signature */ public function verifyReturn(Request $request) { $gateway = $this->payments->resolve(); if (!$gateway) { throw new UnprocessableEntityHttpException('پرداخت آنلاین فعال نیست'); } $payload = array_filter([ 'status' => $request->input('status'), 'reference_id' => $request->input('reference_id'), 'session_id' => $request->input('session_id'), 'amount' => $request->input('amount'), 'track_number' => $request->input('track_number'), 'timestamp' => $request->input('timestamp'), 'signature' => $request->input('signature'), ], static fn ($v) => $v !== null && $v !== ''); $synthetic = Request::create('/', 'GET', $payload); $result = $gateway->handleReturn($synthetic); if (!($result['ok'] ?? false)) { return response()->json([ 'ok' => false, 'message' => $result['message'] ?? 'خطا در تأیید پرداخت', ], (int) ($result['http_status'] ?? 400)); } /** @var Withdraw|null $withdraw */ $withdraw = $result['withdraw'] ?? null; if (!$withdraw) { return response()->json(['ok' => false, 'message' => 'سفارش یافت نشد'], 404); } $customerId = (int) auth('customer')->id(); if ((int) $withdraw->customer_id !== $customerId) { return response()->json(['ok' => false, 'message' => 'دسترسی غیرمجاز'], 403); } $sts = (int) $withdraw->sts; $paid = $sts === 2; return response()->json([ 'ok' => true, 'paid' => $paid, 'status' => $paid ? 'success' : ((string) ($payload['status'] ?? '') === 'success' ? 'pending' : 'failed'), 'amount' => (int) $withdraw->cash, 'reference_id' => 'WD-' . $withdraw->id, 'withdraw_id' => $withdraw->id, 'track_number' => $withdraw->tracked_number, ]); } public function returnFromGateway(Request $request, string $provider) { try { $gateway = $this->payments->resolveOrFail($provider); } catch (InvalidArgumentException $e) { return response('درگاه نامعتبر', 404); } $result = $gateway->handleReturn($request); if (!($result['ok'] ?? false)) { return response( (string) ($result['message'] ?? 'خطا'), (int) ($result['http_status'] ?? 400) ); } $Withdraw = $result['withdraw']; $site_url = $this->config->resolvePublicSiteUrl($request) ?: '/'; return view('showTransactionReport', compact('Withdraw', 'site_url')); } public function webhook(Request $request, string $provider) { try { $gateway = $this->payments->resolveOrFail($provider); } catch (InvalidArgumentException $e) { return response()->json(['message' => 'invalid_provider'], 404); } $result = $gateway->handleWebhook($request); $status = (int) ($result['http_status'] ?? 200); if (!($result['ok'] ?? false)) { return response()->json([ 'message' => $result['message'] ?? 'error', ], $status >= 400 ? $status : 400); } return response()->json([ 'ok' => true, 'ignored' => (bool) ($result['ignored'] ?? false), ]); } /** سازگاری با URLهای قبلی external-payment/* → montify */ public function returnLegacy(Request $request) { return $this->returnFromGateway($request, WalletPaymentManager::PROVIDER_MONTIFY); } public function webhookLegacy(Request $request) { return $this->webhook($request, WalletPaymentManager::PROVIDER_MONTIFY); } }