Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package life.mosu.mosuserver.application.refund;

import life.mosu.mosuserver.application.refund.processor.TossRefundProcessor;
import life.mosu.mosuserver.domain.payment.entity.PaymentJpaEntity;
import life.mosu.mosuserver.domain.payment.entity.PaymentStatus;
import life.mosu.mosuserver.domain.payment.projection.PaymentWithLunchProjection;
import life.mosu.mosuserver.domain.payment.repository.PaymentJpaRepository;
import life.mosu.mosuserver.domain.refund.entity.RefundJpaEntity;
Expand Down Expand Up @@ -48,14 +50,23 @@ public void doProcess(Long userId, MergedRefundRequest request) {

PaymentWithLunchProjection targetPayment = findPaymentOrThrow(paymentKey,
examApplicationId);
log.info("target payment log : {}", targetPayment);

int totalQuantity = getTotalPaymentCount(paymentKey);

log.info("total quantity log : {}", totalQuantity);
Comment on lines +53 to +57

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These log statements appear to be for debugging. It's recommended to use the DEBUG level for such detailed tracing to avoid cluttering INFO logs in production environments. INFO logs are generally reserved for significant application state changes.

Suggested change
log.info("target payment log : {}", targetPayment);
int totalQuantity = getTotalPaymentCount(paymentKey);
log.info("total quantity log : {}", totalQuantity);
log.debug("target payment log : {}", targetPayment);
int totalQuantity = getTotalPaymentCount(paymentKey);
log.debug("total quantity log : {}", totalQuantity);


int refundAmount = calculateRefundAmount(totalQuantity, targetPayment.lunchChecked());

RefundJpaEntity refundEntity = processRefund(request, refundAmount,
targetPayment.examApplicationId());
try {
refundJpaRepository.save(refundEntity);
PaymentJpaEntity payment = paymentJpaRepository.findByExamApplicationId(
targetPayment.examApplicationId())
.orElseThrow(() -> new CustomRuntimeException(ErrorCode.PAYMENT_NOT_FOUND));

payment.changeStatus(PaymentStatus.ABORTED);
Comment on lines 64 to +69

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

It's a good practice to fetch required entities and perform validations before making state changes like saving a new entity. By fetching the PaymentJpaEntity before saving the RefundJpaEntity, you can fail faster if the payment is not found, avoiding an unnecessary database operation that would be rolled back anyway. This improves clarity and follows the fail-fast principle.

Suggested change
refundJpaRepository.save(refundEntity);
PaymentJpaEntity payment = paymentJpaRepository.findByExamApplicationId(
targetPayment.examApplicationId())
.orElseThrow(() -> new CustomRuntimeException(ErrorCode.PAYMENT_NOT_FOUND));
payment.changeStatus(PaymentStatus.ABORTED);
PaymentJpaEntity payment = paymentJpaRepository.findByExamApplicationId(
targetPayment.examApplicationId())
.orElseThrow(() -> new CustomRuntimeException(ErrorCode.PAYMENT_NOT_FOUND));
refundJpaRepository.save(refundEntity);
payment.changeStatus(PaymentStatus.ABORTED);

eventTxService.publishSuccessEvent(refundEntity.getTransactionKey(), refundAmount,
userId, targetPayment.examId(), examApplicationId);
} catch (Exception e) {
Expand All @@ -75,7 +86,8 @@ private PaymentWithLunchProjection findPaymentOrThrow(String paymentKey,
}

private int getTotalPaymentCount(String paymentKey) {
return paymentJpaRepository.findByPaymentKey(paymentKey).size();
return paymentJpaRepository.findByPaymentKeyAndPaymentStatus(paymentKey, PaymentStatus.DONE)
.size();
}

private int calculateRefundAmount(int totalQuantity, boolean lunchChecked) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public void afterCommitHandler(RefundTxEvent event) {
RefundContext ctx = event.getContext();
quotaSyncService.sync(ctx.examId());
log.info("[AFTER_COMMIT] 환불 성공 후 알림톡 발송 시작: orderId={}", ctx.transactionKey());
paymentJpaRepository.deleteByExamApplicationId(ctx.examApplicationId());
sendNotification(ctx.userId(), ctx.examApplicationId());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public class CreateVirtualAccountProcessor implements

@Override
public VirtualAccountResponse process(CreateVirtualAccountRequest request) {
var application = examApplicationJpaRepository.findById(request.applicationId())
var application = examApplicationJpaRepository.findByApplicationId(request.applicationId())
.stream().findFirst()
.orElseThrow(
() -> new CustomRuntimeException(ErrorCode.EXAM_APPLICATION_NOT_FOUND));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import life.mosu.mosuserver.domain.payment.entity.PaymentJpaEntity;
import life.mosu.mosuserver.domain.payment.entity.PaymentStatus;
import life.mosu.mosuserver.domain.payment.projection.PaymentWithLunchProjection;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
Expand Down Expand Up @@ -34,7 +36,8 @@ public interface PaymentJpaRepository extends JpaRepository<PaymentJpaEntity, Lo
)
List<PaymentWithLunchProjection> findByPaymentKeyWithLunch(String paymentKey);

List<PaymentJpaEntity> findByPaymentKey(String paymentKey);
List<PaymentJpaEntity> findByPaymentKeyAndPaymentStatus(String paymentKey,
PaymentStatus status);

@Query("""
SELECT p
Expand All @@ -43,4 +46,6 @@ public interface PaymentJpaRepository extends JpaRepository<PaymentJpaEntity, Lo
AND p.paymentStatus in ('PREPARE', 'EXPIRED', 'ABORTED')
""")
List<PaymentJpaEntity> findFailedPayments(@Param("time") LocalDateTime time);

Optional<PaymentJpaEntity> findByExamApplicationId(Long examApplicationId);
}