TL;DR — 전액 마일리지 결제는 포트원 결제액이 0원이라 PG 요청·웹훅이 발생하지 않는데, 완료 처리를 웹훅 검증에만 의존해 결제가
PENDING으로 영원 정지됐다. 게다가 마일리지는 준비(prepare) 시점에 선차감돼 이미 빠진 상태. 0원 결제 즉시 완료 분기 + 마일리지 차감을 완료 시점으로 이동(@Transactional 롤백으로 자동 복원)해 해결했다.
prepare(Redis 저장·PENDING) → 포트원 결제창 → verify(실결제 조회·금액 대조) + webhook(포트원→서버) → COMPLETEDCOMPLETED로 넘어가지 못하고 PENDING에 영원 정지prepare 시점 선차감 → 결제가 끝나지 않아도 차감은 이미 발생. 복원은 별도 보상 로직(restore)에 의존했는데, 이 경로(웹훅 미수신)에선 그조차 안 타1) 0원 결제 즉시 완료 분기 (PaymentService)
if (prepareInfo.getTotalAmount() == 0L) {
log.info("가족 마일리지로 전액 결제 처리 - paymentId: {}", prepareInfo.getPaymentId());
// 포트원 조회·웹훅 대기 없이 바로 완료 처리
} else {
Long paidAmount = paidPayment.getAmount().getTotal();
if (!prepareInfo.getTotalAmount().equals(paidAmount)) {
// 거제 금액과 실결제액 불일치 → 위변조 차단
}
}
PaymentFacade)2) 마일리지 차감 시점 이동: prepare → complete
preparePayment의 선차감 제거, processPaymentComplete(verify, @Transactional)에서 차감handlePaymentFailureAndRestoreMileage 보상 로직 제거(setPaymentFailed로 단순화, 약 -255줄)