'use client'; import '../style.scss'; import { useEffect, useRef, useState } from 'react'; import { useSearchParams } from 'next/navigation'; import { fetchApi, getDateTime } from '@/lib/utils/client'; import { TossConfirmRequest } from '@/types/request/payment/charge'; import { TossConfirmResponse } from '@/types/response/payment/charge'; type ViewStatus = 'loading'|'success'|'waiting'|'error'; export default function ChargeSuccessPage() { const searchParams = useSearchParams(); const [status, setStatus] = useState('loading'); const [message, setMessage] = useState('결제 승인 처리 중...'); const [pointAmount, setPointAmount] = useState(0); const [paidAt, setPaidAt] = useState(null); const calledRef = useRef(false); useEffect(() => { if (calledRef.current) { return; } calledRef.current = true; confirmPayment(); }, []); const confirmPayment = async () => { const paymentKey = searchParams.get('paymentKey'); const orderID = searchParams.get('orderId'); const amountStr = searchParams.get('amount'); const amount = amountStr ? parseInt(amountStr, 10) : NaN; if (!paymentKey || !orderID || isNaN(amount)) { setStatus('error'); setMessage('결제 정보가 올바르지 않습니다.'); return; } try { const res = await fetchApi('/api/payments/confirm', { method: 'POST', body: { paymentKey, orderID, amount } as TossConfirmRequest, silent: true }); const data = res.data; if (res.success && data?.success) { // 가상계좌 입금 대기 — 이 시점엔 적립 전. 입금 완료 후 지갑에 반영된다. if (data.status === 'WaitingDeposit') { setStatus('waiting'); setMessage(data.message || '가상계좌가 발급되었습니다. 입금 확인 후 충전됩니다.'); return; } setPointAmount(data.pointAmount); setPaidAt(data.paidAt); setStatus('success'); setMessage(data.message || '캐시 충전 완료'); if (window.opener) { window.opener.postMessage({ type: 'CHARGE_COMPLETE' }, '*'); } } else { setStatus('error'); setMessage(data?.message || res.message || '결제 승인에 실패했습니다.'); } } catch { setStatus('error'); setMessage('결제 승인 중 오류가 발생했습니다.'); } }; const handleClose = () => { if (window.opener) { window.close(); } else { window.location.href = '/'; } }; return (
{status === 'loading' &&
} {status === 'success' &&
} {status === 'waiting' &&
} {status === 'error' &&
}

{message}

{status === 'success' && (
충전 캐시 {pointAmount.toLocaleString()} 원
결제 일시 {getDateTime(paidAt)}
)} {status !== 'loading' && ( )}
); }