Spring boot kim's Shop/리팩토링

Spring boot 결제시스템 리팩토링!(2) with 세틀뱅크/카카오페이

디비드킴 2021. 9. 19. 23:37

일반 결제 취소 = 카드/카카오페이/가상계좌 입금 후 = 돈이 들어온 후 환불만 해주면 됨
시나리오
요청-> 취소가능 여부 검증-> 예약/상품 테이블 선택 아이템 삭제-> 각 아이템별 결제수단 추출-> 같은 아이디 값으로 모으기-> 아이디별 환불 pg사 전송
가상계좌 미입금 부분 취소 = 채번 새로 받은 후 기존 채번취소 요청
요청-> 취소가능 여부 검증-> 예약/상품 테이블 선택 아이템 삭제-> 각 아이템별 결제수단 추출-> 같은 아이디 값으로 모으기-> 새 채번 요청-> 새 계좌/가격 상품/예약/결제 테이블 수정-> 채번 취소 요청

고비는 크게 두 가지였다
1. 각 아이템별 결제수단 추출-> 같은 아이디 값으로 모으기
2. 새 계좌/가격 상품/예약/결제 테이블 수정-> 채번 취소 요청

일단 최선을 다해서 구현하긴 했다
그래도 일반 결제 취소는 할만한 게
카드결제 취소를 만들면
다른 카카오페이/가상계좌 입금 후도
비슷하게 만들면 된다
(아니 거의 똑같은 수준이다)


가상계좌는 입금 전 취소는 와... 힘들었다..
흐름을 봐보자

restcontroller

restcontroller.java

tryCancleDto

tryCancleDto.java

@size로 배열도 유효성 검사를 할 수 있다는 거 같은데
찾아보고 붙여줘야겠다

paymentService

paymentService.java

상품 종류 구별
String kind=aboutPayEnums.valueOf(tryCancleDto.getKind()).getString();
해당 테이블 삭제 및 해당 상품에 대한 정보
left 조인해서 결제정보까지 끌어오는 함수
clientInters=reservationService.deleteReservationDb(cancleIds);
본격적인 환불 함수
deletePaymentDb(clientInters);

deletePaymentDb

paymentService.java

결제 수단별로 분류
for(getClientInter g:clientInters){
각 서비스 호출
if(!cards.isEmpty()){
if(!vbankPaids.isEmpty()){
if(!vbankReadys.isEmpty()){
if(!kakaopays.isEmpty()){
여기는 계좌이체 등 붙일수록 늘어날 곳이다

requestCancleCard

cardService.java

같은 아이디로 묶어서 전달하기
for(int i=0;i<cardsSize;i++){
여기서 좀 설명이 필요한데
결제 취소는 결제 아이디 값으로 구분함
즉 결제 취소 시 상품이 천 개는 백개는
아이디와 환불할 금액만 주면 됨

예를 들어
어제 a라는 상품 100개를 카드로 결제함
오늘 다시 a라는 상품 50개를 카드로 결제함
근데 어제 a상품 30개 + 오늘 a상품 10개를 취소하고 싶음
이랬을 때 최대 40번의 요청이 일어날 수 있음
그러나 결제 아이디로 생각한다면
두 개의 묶음으로 나눌 수 있음
즉 이렇게 묶어서 요청을 한 번에 하면
요청수를 40->2번으로 줄일 수 있다!

결제 테이블 수정 및 전달할 포맷 담기
makeReseponseSettleDto( minusPrice, cards.get(i),requests);
요청 보내기
for(reseponseSettleDto r: requests){

makeReseponseSettleDto

cardService.java

요청할 형식 dto
reseponseSettleDto reseponseSettleDto=new reseponseSettleDto();
결제 테이블 수정
updateCardPay(minusPrice, cards.getCid(),cards,reseponseSettleDto);
취소 시 요구하는 데이터 dto에 담기
getClientInterToDto(cards,reseponseSettleDto,minusPrice);
요청
requests.add(reseponseSettleDto);

updateCardPay

cardService.java

취소 요청금액이 원래 금액보다 적으면 update
cardDao.updateCardPriceAndCountNative(Integer.toString(originPrice-newPrice), cnclOrd, id);
같다면 delete
cardDao.deleteById(id);
취소 회차를 요구하므로 넣어주자
reseponseSettleDto.setCnclOrd(cnclOrd);

updateCardPriceAndCountNative

cardDao.java

makecancelBody

cardService.java

세틀 뱅크 요구 사항대로 가공한다
requestCancleCard

paymentService.java

body를 받아서 전송해준다

테스트

https://localhost:8443/showReservationPage.html

이 예약의 개수는 8개이다 하지만
상품과 join 해서 보면 2개가 되는 것이다
상품은 8개지만 결제 요청은 2번인 것!

reservation9981989538/reservation5310211772 이렇게 두 개이다

각각 1개씩 환불

https://localhost:8443/showReservationPage.html
reservation5310211772&amp;amp;nbsp;
vscode
https://localhost:8443/showReservationPage.html
reservation9981989538
vscode

동시 다중 환불

https://localhost:8443/showReservationPage.html
reservation9981989538/reservation5310211772
vscode

환불은 4개 했지만 요청은 두 번만 일어났다 예스!
마지막 남은 한 개씩 동시 환불

https://localhost:8443/showReservationPage.html
mysql

남은 금액=환불금액이었으므로 delete가 잘 수행되었다

vscode

역시 잘되었다

마찬가지로 카카오페이/가상계좌도 잘된다
거기다 + 세 개를 한꺼번에 섞는다면?

https://localhost:8443/showReservationPage.html

아이고 before캡처를 까먹었다

https://localhost:8443/showReservationPage.html
mysql

vbank는 전액 환불이었으니 db에 없는 게 당연한 거고
kakaopay/card모두 잘 수정되어있다

vscode
vscode
vscode

결제 종류별로 순서대로 잘 취소되는 모습이다!

아 진짜 여기까지도 힘들었는데
가상계좌 입금 전 부분 취소는 진짜 힘들었다 ㅋㅋㅋㅋ
가보자!