어제 카카오페이 API를 이용해서 강의 하나의 단건결제를 구현했다. 하지만 오늘 장바구니기능을 구현하다 보니 새로운 문제가 생겼다.
일괄구매
장바구니 기능을 넣다보니 일괄적으로 아이템들을 구매할 일이 생겼다. 아이템 가격내역을 결제 준비요청을 보내는데는 아무 문제가 없었지만, 결제 엔티티를 생성하는 시점에서 문제가 발생했다.
사용자의 강의 결제여부 파악을 위해서 강의 아이템마다 결제 엔티티가 생성되어야 하는데, 카카오페이 API에서는 각각의 금액을 보낼 방법이 없이 금액합계만을 요청 인자로 보낼 수 있었다. 어떻게 해야 결제 엔티티를 분리해서 생성할 수 있을지 잠깐 고민을 해보았다.
VO를 이용하기
아샬님에게 배운 방식은 아니지만 카카오페이 API를 사용할 때 VO를 만들어서 결제 준비단계와 승인단계를 이어준 데서 힌트를 얻었다. KakaoPayItemVO라는 객체를 만들어서 준비단계에서 먼저 강의 목록들을 담아준뒤
List<Course> courses = courseRepository.findAllById(courseIds);
kakaoPayItemVO = new KakaoPayItemVO(courses);
결제 승인에서 예외가 발생하지 않으면 kakaoPayItemVO를 리턴해 강의 정보를 전달해주었다.
try {
kakaoPayApprovalVO = restTemplate.postForObject(new URI(HOST + "/v1/payment/approve"), body, KakaoPayApprovalVO.class);
return kakaoPayItemVO;
} catch (RestClientException | URISyntaxException e) {
e.printStackTrace();
throw new KakaoApprovalFail(e);
}
받아온 kakaoPayItemVO와 Account의 정보를 이용해 결제 목록을 만들어 준다.
public PaymentsDto purchase(PaymentRequestDto paymentRequestDto, AccountId accountId) {
KakaoPayItemVO kakaoPayItemVO = kakaoService.approve(paymentRequestDto, accountId);
Account account = accountRepository.findById(accountId.value())
.orElseThrow(() -> new AccountNotFound(accountId));
List<Payment> payments = Payment.listOf(kakaoPayItemVO.getCourses(), account);
List<Payment> saved = paymentRepository.saveAll(payments);
List<PaymentDto> paymentDtos = saved.stream()
.map(Payment::toDto)
.toList();
return new PaymentsDto(paymentDtos);
}
그 결과 아래와 같이 따로따로 결제엔티티를 생성할 수 있었다.
사실 임의로 KakaoPayItemVO를 만들어서 처리를 해준게 뭔가 찜찜하긴 했지만, 지금은 최대한 결과물을 내는데 초점을 맞추자. 나중에 문제가 생기면 거기에서 또 배우면 된다. 화이팅!!