카드 매입 승인 경로 Spring Boot 3 전환 (ACX-E2E-1785394564819)
Some checks failed
Verify / source-contract (push) Has been cancelled
Some checks failed
Verify / source-contract (push) Has been cancelled
This commit is contained in:
parent
e56f14722c
commit
0d4a244b56
1 changed files with 106 additions and 0 deletions
|
|
@ -0,0 +1,106 @@
|
|||
package com.acquirex.cardacquisition.service;
|
||||
|
||||
import com.acquirex.cardacquisition.entity.CardAcquisition;
|
||||
import com.acquirex.cardacquisition.repository.CardAcquisitionRepository;
|
||||
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;
|
||||
|
||||
@Service
|
||||
public class CardAcquisitionService {
|
||||
|
||||
private static final BigDecimal MAX_SINGLE_TRANSACTION = new BigDecimal("10000000");
|
||||
private static final BigDecimal DAILY_LIMIT = new BigDecimal("50000000");
|
||||
|
||||
private final CardAcquisitionRepository repository;
|
||||
|
||||
public CardAcquisitionService(CardAcquisitionRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public AcquisitionResponse requestAcquisition(AcquisitionRequest request) {
|
||||
validateRequest(request);
|
||||
|
||||
CardAcquisition acquisition = new CardAcquisition(
|
||||
request.getMerchantId(), request.getCardNumber(), request.getAmount(), request.getCurrency());
|
||||
|
||||
CardAcquisition saved = repository.save(acquisition);
|
||||
String approvalCode = generateApprovalCode();
|
||||
saved.approve(approvalCode);
|
||||
|
||||
AcquisitionResponse response = AcquisitionResponse.fromEntity(repository.save(saved));
|
||||
response.setMessage("매입 승인이 완료되었습니다");
|
||||
return response;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public AcquisitionResponse getAcquisition(Long id) {
|
||||
CardAcquisition acquisition = repository.findById(id)
|
||||
.orElseThrow(() -> new AcquisitionNotFoundException("매입 정보를 찾을 수 없습니다: " + id));
|
||||
AcquisitionResponse response = AcquisitionResponse.fromEntity(acquisition);
|
||||
response.setMessage("매입 정보를 조회했습니다");
|
||||
return response;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<AcquisitionResponse> getAcquisitionsByMerchant(String merchantId) {
|
||||
return repository.findByMerchantId(merchantId).stream()
|
||||
.map(AcquisitionResponse::fromEntity).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<AcquisitionResponse> getPendingAcquisitions() {
|
||||
return repository.findByStatus(CardAcquisition.AcquisitionStatus.PENDING).stream()
|
||||
.map(AcquisitionResponse::fromEntity).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public AcquisitionResponse cancelAcquisition(Long id) {
|
||||
CardAcquisition acquisition = repository.findById(id)
|
||||
.orElseThrow(() -> new AcquisitionNotFoundException("매입 정보를 찾을 수 없습니다: " + id));
|
||||
|
||||
if (acquisition.getStatus() == CardAcquisition.AcquisitionStatus.CANCELLED) {
|
||||
throw new IllegalStateException("이미 취소된 매입입니다");
|
||||
}
|
||||
|
||||
acquisition.setStatus(CardAcquisition.AcquisitionStatus.CANCELLED);
|
||||
acquisition.setApprovalTime(LocalDateTime.now());
|
||||
|
||||
AcquisitionResponse response = AcquisitionResponse.fromEntity(repository.save(acquisition));
|
||||
response.setMessage("매입이 취소되었습니다");
|
||||
return response;
|
||||
}
|
||||
|
||||
private void validateRequest(AcquisitionRequest request) {
|
||||
if (request.getAmount().compareTo(MAX_SINGLE_TRANSACTION) > 0) {
|
||||
throw new InvalidAcquisitionException("단일 거래 한도를 초과했습니다");
|
||||
}
|
||||
|
||||
LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
|
||||
BigDecimal todayTotal = repository.findByRequestTimeBetween(startOfDay, startOfDay.plusDays(1)).stream()
|
||||
.filter(a -> a.getMerchantId().equals(request.getMerchantId()))
|
||||
.map(CardAcquisition::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
if (todayTotal.add(request.getAmount()).compareTo(DAILY_LIMIT) > 0) {
|
||||
throw new InvalidAcquisitionException("일일 한도를 초과했습니다");
|
||||
}
|
||||
}
|
||||
|
||||
private String generateApprovalCode() {
|
||||
return "APR" + UUID.randomUUID().toString().substring(0, 12).toUpperCase();
|
||||
}
|
||||
|
||||
public static class AcquisitionNotFoundException extends RuntimeException {
|
||||
public AcquisitionNotFoundException(String message) { super(message); }
|
||||
}
|
||||
|
||||
public static class InvalidAcquisitionException extends RuntimeException {
|
||||
public InvalidAcquisitionException(String message) { super(message); }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue