182 lines
6.0 KiB
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;
|
|
}
|
|
}
|