

결제 완료 시 payment_tb에 데이터 Insert 후 payment/success로 redirect
필요(출력) 데이터
페이지 데이터 | table / column | 조회할 데이터 |
포스터 이미지 | movie / posterUrls | moviePosterUrl |
예매번호 | payment / bookingNumber | bookingNumber |
상영 일시(시작/종료시간) | showtime / startedAt | showtime / endtime |
상영관 (영화관&상영관 이름) | screen / name | cinemaName / screenName |
관람 인원 (예매한 인원 수) | x | people |
좌석 번호 | seat / seatNumber | seatNumbers |
결제 금액 | x | totalPrice |
할인금액 / 관람권 or 할인권 | payment / mycoupon , point | discount (현재는 0원 고정) |
총 결제 금액 (결제 금액 - 할인 금액) | payment / price | payPrice |
관련 레이어 및 코드
1. PaymentController
- 결제 성공 후
payment/success
페이지로 이동
@GetMapping("/api/payment/success")
public String paymentSuccess(HttpSession session, Model model) {
// 세션에서 예약 ID와 총 결제 금액 가져오기
Long sessionReservationId = (Long) session.getAttribute("sessionReservationId");
Double sessionTotalPrice = (Double) session.getAttribute("sessionTotalPrice");
if (sessionReservationId == null || sessionTotalPrice == null) {
throw new ExceptionApi404("Reservation or Price data is missing.");
}
// 예약 정보와 결제 정보를 한 번에 조회
PaymentResponse.PaymentViewDTO paymentData = paymentService.getPaymentViewData(sessionReservationId);
// 할인 금액은 0으로 고정 (추후 쿠폰 및 할인 적용 시 수정 가능)
int discount = 0;
double payPrice = sessionTotalPrice - discount;
// 8자리 예매번호 생성
String bookingNumber = paymentService.generateBookingNumber();
// 모델에 paymentData 객체 전체 추가
model.addAttribute("paymentData", paymentData);
model.addAttribute("mTotalPrice", sessionTotalPrice); // 총 금액
model.addAttribute("discount", discount); // 할인 금액
model.addAttribute("payPrice", payPrice); // 최종 결제 금액
model.addAttribute("bookingNumber", bookingNumber); // 8자리 예매번호
return "payment/success";
}
- 세션에서
reservationId
와totalPrice
를 가져와paymentService
를 통해 결제 데이터 조회
- 결제 정보, 할인금액(0원), 최종 결제 금액을 계산하여
model
에 담아payment/success
페이지에 전달
2. PaymentService
PaymentViewDto
객체 생성해서 필요 데이터 조회 및 전달
public PaymentResponse.PaymentViewDTO getPaymentViewData(Long reservationId) {
Reservation reservation = reservationRepository.findById(reservationId)
.orElseThrow(() -> new ExceptionApi404("예약 정보를 찾을 수 없습니다."));
Showtime showtime = reservation.getTickets().getFirst().getShowtime();
int runtimeMinutes = showtime.getMovie().getRuntime(); // 영화 런타임 (분 단위)
Timestamp startedAt = Timestamp.valueOf(showtime.getStartedAt().toLocalDateTime()); // 상영 시작 시간
String startTime = convertTimeStampToString(startedAt, "yyyy.MM.dd HH:mm"); // 시작 시간 포맷팅
String endTime = calculateEndTime(startedAt, runtimeMinutes); // 종료 시간 계산
return new PaymentResponse.PaymentViewDTO(
reservationId,
reservation.getUser().getUsername(),
reservation.getUser().getEmail(),
reservation.getUser().getPhone(),
showtime.getMovie().getPosterUrls().get(0).getUrl(),
showtime.getMovie().getMovieNm(),
startTime, // 시작 시간
endTime, // 종료 시간
showtime.getScreen().getCinema().getName(),
showtime.getScreen().getName(),
reservation.getTickets().size(),
reservation.getTickets().stream()
.map(ticket -> ticket.getSeat().getSeatNumber())
.collect(Collectors.toList()),
reservation.getTickets().size() * showtime.getPrice(),
reservation.getTickets().size() * showtime.getPrice()
);
}
getPaymentViewData
메소드는reservationId
를 기반으로 데이터 조회. 영화 정보, 좌석 정보, 결제 금액등을 포함한 DTO 반환
3. payment/success.mustache
- 받아온 데이터 출력
<div class="info_row">
<span class="info_label">예매번호</span>
<span>{{bookingNumber}}</span>
</div>
<div class="info_row">
<span class="info_label">상영 일시</span>
<span>{{paymentData.showtime}} ~ {{paymentData.endtime}}</span> <!-- 시작 시간 ~ 종료 시간 -->
</div>
<div class="info_row">
<span class="info_label">상영관</span>
<span>{{paymentData.cinemaName}} {{paymentData.screenName}}</span>
</div>
<div class="info_row">
<span class="info_label">관람 인원</span>
<span>{{paymentData.people}}</span>
</div>
<div class="info_row">
<span class="info_label">좌석</span>
<span>{{#paymentData.seatNumbers}}{{.}} {{/paymentData.seatNumbers}}</span>
</div>
<div class="bottom_section">
<span>주문 금액</span> <strong>{{paymentData.price}}원</strong>
</div>
<div class="bottom_section middle">
<span>할인 금액</span> <strong>{{discount}}원</strong>
</div>
<div class="bottom_section">
<span>총 결제 금액</span> <strong>{{paymentData.totalPrice}}원</strong>
</div>

예약 - 좌석 선택 - 결제 로직 시연영상
Share article