Skip to content

Commit 17f7c26

Browse files
committed
Feat: 결제 관련 조건 추가 및 구조 리팩토링
1 parent 6b88ae0 commit 17f7c26

File tree

3 files changed

+50
-45
lines changed

3 files changed

+50
-45
lines changed

src/main/java/com/threestar/trainus/domain/payment/repository/PaymentRepository.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
public interface PaymentRepository extends JpaRepository<Payment, Long> {
1717
Optional<Payment> findByOrderId(String orderId);
1818

19-
Optional<Payment> findByUserCouponAndStatus(UserCoupon coupon, PaymentStatus status);
19+
Optional<Payment> findByUserAndLessonAndUserCouponAndStatus(User user, Lesson lesson, UserCoupon coupon, PaymentStatus status);
20+
21+
Optional<Payment> findByUserAndLessonAndUserCouponIsNullAndStatus(User user, Lesson lesson, PaymentStatus status);
2022

2123
@Query(value = """
2224
select * from payments

src/main/java/com/threestar/trainus/domain/payment/repository/TossPaymentRepository.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.threestar.trainus.domain.payment.entity.TossPayment;
88

99
public interface TossPaymentRepository extends JpaRepository<TossPayment, Long> {
10-
Optional<TossPayment> findByPaymentKey(String paymentKey);
1110

1211
Optional<TossPayment> findByOrderId(String orderId);
1312
}

src/main/java/com/threestar/trainus/domain/payment/service/PaymentService.java

Lines changed: 47 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010
import org.springframework.stereotype.Service;
1111
import org.springframework.transaction.annotation.Transactional;
1212

13-
import com.threestar.trainus.domain.coupon.user.entity.CouponStatus;
1413
import com.threestar.trainus.domain.coupon.user.entity.UserCoupon;
15-
import com.threestar.trainus.domain.coupon.user.repository.UserCouponRepository;
14+
import com.threestar.trainus.domain.coupon.user.service.CouponService;
1615
import com.threestar.trainus.domain.lesson.student.service.StudentLessonService;
1716
import com.threestar.trainus.domain.lesson.teacher.entity.Lesson;
1817
import com.threestar.trainus.domain.lesson.teacher.service.AdminLessonService;
@@ -51,10 +50,24 @@ public class PaymentService {
5150
private final UserService userService;
5251
private final PaymentClient paymentClient;
5352
private final AdminLessonService lessonService;
53+
private final CouponService couponService;
5454
private final StudentLessonService studentLessonService;
5555
private final PaymentRepository paymentRepository;
5656
private final TossPaymentRepository tossPaymentRepository;
57-
private final UserCouponRepository userCouponRepository;
57+
58+
private static int getRefundPrice(LocalDateTime cancelTime, Payment payment) {
59+
int refundPrice = 0;
60+
if (cancelTime.isBefore(payment.getLesson().getStartAt().minusMonths(1))) {
61+
refundPrice = payment.getPayPrice();
62+
} else if (cancelTime.isBefore(payment.getLesson().getStartAt().minusWeeks(1))) {
63+
refundPrice = (payment.getPayPrice() * 50 / 100);
64+
} else if (cancelTime.isBefore(payment.getLesson().getStartAt().minusDays(3))) {
65+
refundPrice = (payment.getPayPrice() * 30 / 100);
66+
} else {
67+
refundPrice = (payment.getPayPrice() * 30 / 100);
68+
}
69+
return refundPrice;
70+
}
5871

5972
@Transactional
6073
public PaymentResponseDto preparePayment(PaymentRequestDto request, Long userId) {
@@ -64,39 +77,44 @@ public PaymentResponseDto preparePayment(PaymentRequestDto request, Long userId)
6477
//올바른 결제자인지 체크
6578
studentLessonService.checkValidLessonParticipant(lesson, user);
6679

67-
// 여기서 중복 결제 방지
80+
// 중복 결제 방지
6881
validateDuplicatedPayment(lesson, user);
6982

70-
int originPrice = lesson.getPrice();
7183
int discount = 0;
7284

7385
UserCoupon coupon = null;
74-
if (request.userCouponId() != null) {
75-
coupon = userCouponRepository.findById(request.userCouponId())
76-
.filter(c -> c.getStatus() == CouponStatus.ACTIVE)
77-
.orElseThrow(() -> new BusinessException(ErrorCode.COUPON_NOT_FOUND));
86+
if (request.userCouponId() != null) { //쿠폰이 있는 주문 내역(실제 결제 진행 전) 불러오기
87+
coupon = couponService.getValidUserCoupon(request.userCouponId(), userId);
7888

79-
Optional<Payment> existing = paymentRepository.findByUserCouponAndStatus(coupon, PaymentStatus.READY);
80-
if (existing.isPresent()) {
89+
Optional<Payment> existingCoupon = paymentRepository.findByUserAndLessonAndUserCouponAndStatus(user, lesson,
90+
coupon, PaymentStatus.READY);
91+
if (existingCoupon.isPresent()) {
8192
return PaymentResponseDto.builder()
82-
.originPrice(existing.get().getOriginPrice())
93+
.originPrice(existingCoupon.get().getOriginPrice())
8394
.lessonTitle(lesson.getLessonName())
84-
.paymentMethod(existing.get().getPaymentMethod())
85-
.payPrice(existing.get().getPayPrice())
86-
.orderId(existing.get().getOrderId())
95+
.paymentMethod(existingCoupon.get().getPaymentMethod())
96+
.payPrice(existingCoupon.get().getPayPrice())
97+
.orderId(existingCoupon.get().getOrderId())
8798
.build();
8899
}
89100

90-
String discountPrice = coupon.getCoupon().getDiscountPrice();
91-
if (discountPrice.contains("%")) {
92-
int discountPercentage = Integer.parseInt(discountPrice.substring(0, discountPrice.indexOf("%")));
93-
discount = (originPrice * discountPercentage) / 100;
94-
} else {
95-
discount = Integer.parseInt(discountPrice.substring(0, discountPrice.indexOf("원")));
101+
discount = couponService.calculateDiscountedPrice(lesson.getPrice(), coupon);
102+
} else {
103+
Optional<Payment> existingNoneCoupon = paymentRepository.findByUserAndLessonAndUserCouponIsNullAndStatus(
104+
user, lesson,
105+
PaymentStatus.READY);
106+
if (existingNoneCoupon.isPresent()) {
107+
return PaymentResponseDto.builder()
108+
.originPrice(existingNoneCoupon.get().getOriginPrice())
109+
.lessonTitle(lesson.getLessonName())
110+
.paymentMethod(existingNoneCoupon.get().getPaymentMethod())
111+
.payPrice(existingNoneCoupon.get().getPayPrice())
112+
.orderId(existingNoneCoupon.get().getOrderId())
113+
.build();
96114
}
97115
}
98116

99-
int finalPrice = Math.max(0, originPrice - discount);
117+
int finalPrice = Math.max(0, lesson.getPrice() - discount);
100118

101119
String orderId = UUID.randomUUID().toString();
102120

@@ -105,7 +123,7 @@ public PaymentResponseDto preparePayment(PaymentRequestDto request, Long userId)
105123
.lesson(lesson)
106124
.orderId(orderId)
107125
.payPrice(finalPrice)
108-
.originPrice(originPrice)
126+
.originPrice(lesson.getPrice())
109127
.payDate(LocalDateTime.now())
110128
.userCoupon(coupon)
111129
.status(PaymentStatus.READY)
@@ -115,7 +133,7 @@ public PaymentResponseDto preparePayment(PaymentRequestDto request, Long userId)
115133
paymentRepository.save(payment);
116134

117135
return PaymentResponseDto.builder()
118-
.originPrice(originPrice)
136+
.originPrice(lesson.getPrice())
119137
.lessonTitle(lesson.getLessonName())
120138
.paymentMethod(PaymentMethod.CREDIT_CARD)
121139
.payPrice(finalPrice)
@@ -156,10 +174,8 @@ public SuccessfulPaymentResponseDto processConfirm(ConfirmPaymentRequestDto requ
156174
.approvedAt(paidAt)
157175
.build();
158176

159-
if (payment.getUserCoupon() != null && payment.getUserCoupon().getStatus() == CouponStatus.ACTIVE) {
160-
UserCoupon coupon = payment.getUserCoupon();
161-
coupon.use();
162-
userCouponRepository.save(coupon);
177+
if (payment.getUserCoupon() != null) {
178+
couponService.useCoupon(payment.getUserCoupon());
163179
}
164180
tossPaymentRepository.save(tossPayment);
165181

@@ -181,16 +197,7 @@ public CancelPaymentResponseDto processCancel(CancelPaymentRequestDto request) {
181197
throw new BusinessException(ErrorCode.INVALID_CANCEL_DATE);
182198
}
183199

184-
int refundPrice = 0;
185-
if (cancelTime.isBefore(payment.getLesson().getStartAt().minusMonths(1))) {
186-
refundPrice = payment.getPayPrice();
187-
} else if (cancelTime.isBefore(payment.getLesson().getStartAt().minusWeeks(1))) {
188-
refundPrice = (payment.getPayPrice() * 50 / 100);
189-
} else if (cancelTime.isBefore(payment.getLesson().getStartAt().minusDays(3))) {
190-
refundPrice = (payment.getPayPrice() * 30 / 100);
191-
} else {
192-
refundPrice = (payment.getPayPrice() * 30 / 100);
193-
}
200+
int refundPrice = getRefundPrice(cancelTime, payment);
194201

195202
//여기서 client 호출
196203
TossPaymentResponseDto tossResponse = paymentClient.cancelPayment(
@@ -213,10 +220,7 @@ public CancelPaymentResponseDto processCancel(CancelPaymentRequestDto request) {
213220
if (payment.getUserCoupon() != null) {
214221
UserCoupon coupon = payment.getUserCoupon();
215222
payment.setUserCoupon(null); //payment에서도 쿠폰 제거
216-
if (coupon.getStatus() == CouponStatus.INACTIVE) {
217-
coupon.restore();
218-
userCouponRepository.save(coupon);
219-
}
223+
couponService.restoreCoupon(coupon);
220224
}
221225
paymentRepository.save(payment);
222226

@@ -262,7 +266,7 @@ public PaymentCancelHistoryPageDto viewAllFailureTransaction(Long userId, int pa
262266

263267
public void validateDuplicatedPayment(Lesson lesson, User user) {
264268
boolean alreadyPaid = paymentRepository.existsByLessonAndUserAndStatusIn(
265-
lesson, user, List.of(PaymentStatus.DONE, PaymentStatus.READY)
269+
lesson, user, List.of(PaymentStatus.DONE)
266270
);
267271

268272
if (alreadyPaid) {

0 commit comments

Comments
 (0)