giftcon_dev/app/Http/Controllers/Web/Payment/DanalController.php

182 lines
6.0 KiB
PHP

<?php
namespace App\Http\Controllers\Web\Payment;
use App\Http\Controllers\Controller;
use App\Services\Payments\PaymentService;
use Illuminate\Http\Request;
final class DanalController extends Controller
{
public function __construct(
private readonly PaymentService $service,
) {}
// 결제 시작(POST 권장)
public function start(Request $request)
{
$data = $request->validate([
'oid' => ['required','string','max:64'],
'method' => ['required','in:card,vact,phone'],
'card_kind' => ['nullable','in:general,exchange'],
'phone_mode' => ['nullable','in:prod,dev'],
'is_mobile' => ['nullable','boolean'],
]);
$memNo = $this->currentMemNo($request);
if ($memNo <= 0) abort(403);
$out = $this->service->start(
$data['oid'],
$memNo,
$data['method'],
[
'card_kind' => $data['card_kind'] ?? null,
'phone_mode' => $data['phone_mode'] ?? null,
'is_mobile' => (bool)($data['is_mobile'] ?? false),
]
);
if (($out['type'] ?? '') === 'redirect') {
return view('web.payments.danal.redirect', [
'actionUrl' => $out['start']['actionUrl'],
'params' => $out['start']['params'],
'acceptCharset' => $out['start']['acceptCharset'] ?? 'EUC-KR',
]);
}
return view('web.payments.danal.result', $out);
}
// 카드 RETURNURL
public function cardReturn(Request $request)
{
$token = (string)$request->query('a', '');
if ($token === '') abort(404);
if (($out['ok'] ?? false) && ($out['status'] ?? '') === 'paid') {
$attemptId = (int)($out['meta']['attempt_id'] ?? 0);
$redirect = url("/mypage/usage?attempt_id={$attemptId}");
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'title' => '결제완료',
'message' => '결제가 완료되었습니다. 구매페이지로 이동합니다.',
'redirect' => url($redirect),
]);
}
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'title' => '결제실패',
'message' => '결제에 실패했습니다.',
]);
}
// 가상계좌 RETURNURL
public function vactReturn(Request $request)
{
$token = (string)$request->query('a', '');
if ($token === '') abort(404);
$out = $this->service->handleVactReturn($token, $request->all());
if (($out['ok'] ?? false) && ($out['status'] ?? '') === 'issued') {
$attemptId = (int)($out['meta']['attempt_id'] ?? 0);
$redirect = url("/mypage/usage?attempt_id={$attemptId}");
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'title' => '가상계좌 발급',
'message' => '가상계좌가 발급되었습니다. 입금 후 결제가 완료됩니다. 구매페이지로 이동합니다.',
'redirect' => url($redirect),
]);
}
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'title' => '처리실패',
'message' => '가상계좌 처리에 실패했습니다.',
]);
}
// 가상계좌 NOTIURL (반드시 OK)
public function vactNoti(Request $request)
{
$this->service->handleVactNoti($request->all());
return response('OK', 200)->header('Content-Type', 'text/plain');
}
// 휴대폰 TargetURL
public function phoneReturn(Request $request)
{
$out = $this->service->handlePhoneReturn($request->all());
if (($out['ok'] ?? false) && ($out['status'] ?? '') === 'paid') {
$attemptId = (int)($out['meta']['attempt_id'] ?? 0);
$redirect = url("/mypage/usage?attempt_id={$attemptId}");
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'title' => '결제완료',
'message' => '결제가 완료되었습니다. 구매페이지로 이동합니다.',
'redirect' => url($redirect),
]);
}
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'title' => '결제실패',
'message' => '결제에 실패했습니다.',
]);
}
// 휴대폰 BackURL(취소)
public function phoneCancel(Request $request)
{
$out = $this->service->handlePhoneCancel($request->all());
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'message' => '결제가 취소되었습니다.',
'title' => '결제취소',
]);
}
// 카드/가상계좌 CancelURL
public function cancel(Request $request)
{
$token = (string)$request->query('a', '');
if ($token === '') abort(404);
$out = $this->service->handleCancel($token);
// ✅ 취소면: iframe 닫고 showMsg 실행
if (($out['meta']['code'] ?? '') === 'CANCEL') {
return view('web.payments.danal.finish_top_action', [
'action' => 'close_modal',
'message' => '결제가 취소되었습니다.',
'title' => '결제취소',
]);
}
return view('web.payments.danal.result', $out);
}
private function currentMemNo(Request $request): int
{
// 프로젝트에 맞게 연결해라:
// 1) Auth::user()->mem_no 가 있으면 그걸 쓰고,
// 2) local 테스트용은 request('mem_no') 허용
$u = $request->user();
if ($u && isset($u->mem_no)) return (int)$u->mem_no;
if (app()->environment('local')) {
return (int)$request->input('mem_no', 0);
}
return 0;
}
}