카드 매입 승인 경로 Spring Boot 3 전환 #12
1 changed files with 115 additions and 0 deletions
|
|
@ -0,0 +1,115 @@
|
|||
package com.acquirex.approval.service;
|
||||
|
||||
import com.acquirex.approval.domain.AcquisitionApproval;
|
||||
import com.acquirex.approval.domain.AcquisitionApproval.ApprovalStatus;
|
||||
import com.acquirex.approval.repository.AcquisitionApprovalRepository;
|
||||
import jakarta.validation.constraints.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/** 카드 매입 승인 서비스 - Spring Boot 3 전환 적용 */
|
||||
@Service
|
||||
@Transactional(readOnly = true)
|
||||
public class AcquisitionApprovalService {
|
||||
|
||||
private final AcquisitionApprovalRepository repository;
|
||||
|
||||
public AcquisitionApprovalService(AcquisitionApprovalRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
/** 매입 승인 요청 처리 */
|
||||
@Transactional
|
||||
public ApprovalResponse processApproval(ApprovalRequest request) {
|
||||
String approvalNumber = generateApprovalNumber();
|
||||
AcquisitionApproval approval = new AcquisitionApproval(
|
||||
request.merchantId, maskCardNumber(request.cardNumber),
|
||||
request.approvalAmount, approvalNumber, ApprovalStatus.APPROVED, LocalDateTime.now());
|
||||
return toResponse(repository.save(approval));
|
||||
}
|
||||
|
||||
/** 승인 번호로 조회 */
|
||||
public ApprovalResponse findByApprovalNumber(String approvalNumber) {
|
||||
return repository.findByApprovalNumber(approvalNumber)
|
||||
.map(this::toResponse)
|
||||
.orElseThrow(() -> new IllegalArgumentException("승인 번호를 찾을 수 없습니다: " + approvalNumber));
|
||||
}
|
||||
|
||||
/** 가맹점별 승인 목록 조회 */
|
||||
public List<ApprovalResponse> findByMerchantId(String merchantId, ApprovalStatus status) {
|
||||
return repository.findByMerchantIdAndStatus(merchantId, status)
|
||||
.stream().map(this::toResponse).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/** 승인 취소 처리 */
|
||||
@Transactional
|
||||
public ApprovalResponse cancelApproval(Long id) {
|
||||
AcquisitionApproval approval = repository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("승인 정보를 찾을 수 없습니다: " + id));
|
||||
if (approval.getStatus() == ApprovalStatus.CANCELLED) {
|
||||
throw new IllegalStateException("이미 취소된 승인입니다");
|
||||
}
|
||||
approval.setStatus(ApprovalStatus.CANCELLED);
|
||||
return toResponse(repository.save(approval));
|
||||
}
|
||||
|
||||
private String generateApprovalNumber() {
|
||||
return "AP" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 4).toUpperCase();
|
||||
}
|
||||
|
||||
private String maskCardNumber(String cardNumber) {
|
||||
if (cardNumber == null || cardNumber.length() < 10) return cardNumber;
|
||||
return cardNumber.substring(0, 6) + "****" + cardNumber.substring(cardNumber.length() - 4);
|
||||
}
|
||||
|
||||
private ApprovalResponse toResponse(AcquisitionApproval a) {
|
||||
return new ApprovalResponse(a.getId(), a.getMerchantId(), a.getCardNumber(),
|
||||
a.getApprovalAmount(), a.getApprovalNumber(), a.getStatus(), a.getApprovalDatetime());
|
||||
}
|
||||
|
||||
/** 카드 매입 승인 요청 DTO - Spring Boot 3: jakarta.validation 적용 */
|
||||
public static class ApprovalRequest {
|
||||
@NotBlank(message = "가맹점 ID는 필수입니다")
|
||||
@Size(max = 20)
|
||||
public String merchantId;
|
||||
|
||||
@NotBlank(message = "카드번호는 필수입니다")
|
||||
@Pattern(regexp = "\\d{13,19}", message = "카드번호는 13~19자리 숫자입니다")
|
||||
public String cardNumber;
|
||||
|
||||
@NotNull(message = "승인 금액은 필수입니다")
|
||||
@DecimalMin(value = "0.01", message = "승인 금액은 0보다 커야 합니다")
|
||||
@DecimalMax(value = "999999999.99")
|
||||
public BigDecimal approvalAmount;
|
||||
|
||||
public ApprovalRequest() {}
|
||||
public ApprovalRequest(String merchantId, String cardNumber, BigDecimal approvalAmount) {
|
||||
this.merchantId = merchantId; this.cardNumber = cardNumber; this.approvalAmount = approvalAmount;
|
||||
}
|
||||
}
|
||||
|
||||
/** 카드 매입 승인 응답 DTO */
|
||||
public static class ApprovalResponse {
|
||||
public Long id;
|
||||
public String merchantId;
|
||||
public String cardNumber;
|
||||
public BigDecimal approvalAmount;
|
||||
public String approvalNumber;
|
||||
public ApprovalStatus status;
|
||||
public LocalDateTime approvalDatetime;
|
||||
|
||||
public ApprovalResponse() {}
|
||||
public ApprovalResponse(Long id, String merchantId, String cardNumber, BigDecimal approvalAmount,
|
||||
String approvalNumber, ApprovalStatus status, LocalDateTime approvalDatetime) {
|
||||
this.id = id; this.merchantId = merchantId; this.cardNumber = cardNumber;
|
||||
this.approvalAmount = approvalAmount; this.approvalNumber = approvalNumber;
|
||||
this.status = status; this.approvalDatetime = approvalDatetime;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue