1010import org .springframework .stereotype .Service ;
1111import org .springframework .transaction .annotation .Transactional ;
1212
13- import com .threestar .trainus .domain .coupon .user .entity .CouponStatus ;
1413import 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 ;
1615import com .threestar .trainus .domain .lesson .student .service .StudentLessonService ;
1716import com .threestar .trainus .domain .lesson .teacher .entity .Lesson ;
1817import 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