import { isLoginRequiredError } from '@_api/apiClient'; import { confirmPayment } from '@_api/payment/paymentAPI'; import { type PaymentConfirmRequest, PaymentType } from '@_api/payment/PaymentTypes'; import { confirmReservation } from '@_api/reservation/reservationAPI'; import '@_css/reservation-v2-1.css'; import React, { useEffect, useRef } from 'react'; import { useLocation, useNavigate } from 'react-router-dom'; import { formatDate } from 'src/util/DateTimeFormatter'; declare global { interface Window { PaymentWidget: any; } } const ReservationStep2Page: React.FC = () => { const navigate = useNavigate(); const location = useLocation(); const paymentWidgetRef = useRef(null); const paymentMethodsRef = useRef(null); const { reservationId, storeName, themeName, themePrice, totalPrice, date, time, participantCount } = location.state || {}; const handleError = (err: any) => { if (isLoginRequiredError(err)) { alert('로그인이 필요해요.'); navigate('/login', { state: { from: location } }); } else { const message = err.response?.data?.message || '알 수 없는 오류가 발생했습니다.'; alert(message); console.error(err); } }; useEffect(() => { if (!reservationId) { alert('잘못된 접근입니다.'); navigate('/reservation'); return; } const script = document.createElement('script'); script.src = 'https://js.tosspayments.com/v1/payment-widget'; script.async = true; document.head.appendChild(script); script.onload = () => { const widgetClientKey = "test_gck_docs_Ovk5rk1EwkEbP0W43n07xlzm"; const paymentWidget = window.PaymentWidget(widgetClientKey, window.PaymentWidget.ANONYMOUS); paymentWidgetRef.current = paymentWidget; const paymentMethods = paymentWidget.renderPaymentMethods( "#payment-method", { value: totalPrice, currency: "KRW" }, { variantKey: "DEFAULT" } ); paymentMethodsRef.current = paymentMethods; }; }, [reservationId, totalPrice, navigate]); const handlePayment = () => { if (!paymentWidgetRef.current || !reservationId) { alert('결제 위젯이 로드되지 않았거나 예약 정보가 없습니다.'); return; } const generateRandomString = () => crypto.randomUUID().replace(/-/g, ''); paymentWidgetRef.current.requestPayment({ orderId: generateRandomString(), orderName: `${themeName} 예약 결제`, amount: totalPrice, }).then((data: any) => { const paymentData: PaymentConfirmRequest = { paymentKey: data.paymentKey, orderId: data.orderId, amount: totalPrice, paymentType: data.paymentType || PaymentType.NORMAL, }; confirmPayment(reservationId, paymentData) .then(() => { return confirmReservation(reservationId); }) .then(() => { alert('결제가 완료되었어요!'); navigate('/reservation/success', { state: { storeName: storeName, themeName: themeName, date: date, time: time, participantCount: participantCount, totalPrice: totalPrice, } }); }) .catch(handleError); }).catch((error: any) => { console.error("Payment request error:", error); alert("결제 요청 중 오류가 발생했습니다."); }); }; if (!reservationId) { return null; } return (

결제하기

결제 정보 확인

날짜: {formatDate(date)}

시간: {time}

테마: {themeName}

매장: {storeName}

인원: {participantCount}명

1인당 금액: {themePrice.toLocaleString()}원

총 금액: {totalPrice.toLocaleString()}원

결제 수단

); }; export default ReservationStep2Page;