Spring boot kim's Shop/리팩토링

Springboot 결제시스템 (7) 카카오페이 연동

디비드킴 2021. 9. 8. 16:07

가상계좌를 다룰 방법을 찾았다
세틀 뱅크 테스트는 매번 취소는 불가능하지만
입금 전 수정/카드결제가 가능했다
그래서 카카오페이를 직접 연동하기로 하고
세틀 뱅크를 pg사로 붙였다
네이버 페이는 사업자 등록증이 필요하다

테스트 계정 범위
1. 세틀 뱅크로 입금 전 수정 가능
2. 세틀 뱅크 일반 결제 가능
3. 카카오페이 불가능
-따로 직접 붙임
4. 입금 후 부분 취소 불가능
-db만 수정해주고 기분만 내야겠다
5. 일반 결제는 동일하게 부분 취소/환불 가능

카카오페이를 붙이면서
현재 예약시스템도 뜯어고쳤다

이전에는 예약/일반상품을 따로 구별하려고 했다
하지만 이제는 물건을 구매했을 때 예약상품이든
일반상품이든 요청을 하면 결제 검증을 하고 예약/상품에 따라
crud가 일어난다

우선 카카오페이를 붙여보자
순서는 제품 검증-> ready(결제창 띄움)->결제-> 품목 구별-> insert
공식문서를 보고 붙였다

kakopayService

kakopayService.java

하나하나 봐보자
아이템 정보를 가져온다
String[][] itemArray=tryKakaoPayDto.getItemArray();

vscode

종류별로 다루기 편하게 가공한다(예약/일반상품)
Map<String,Object>result=paymentService.getTotalPriceAndOther(itemArray, kind);

vscode

가공하는 이유는 프런트에서
json으로 받질 않아서이다..
json이긴 한데 json안에 json이 아닌 배열이 들어있다
(json으로 받는다면 가공할 필요는 없을 거 같다)
상품 총액/재고/등을 검사한다
paymentService.confrimProduct(tryKakaoPayDto.getTotalPrice(),totalPrice,count,itemName);
카카오에서 제시하는 조건에 맞게 body를 세팅 후 통신
JSONObject response=getPayLink(readyUrl);
통신 결과를 바탕으로 세션 생성 이유는
HttpSession httpSession=request.getSession();
이제 ready->결제 완료 갈 때 토큰이 만료된 경우를 방지하기 위해
db에 필요한 정보도 같이 넣어준다

payemntService
getTotalPriceAndOther

payemntService.java

가지고 있는 품목수에 맞춰 총액 계산
totalPrice+=priceService.getTotalPrice(itemArray[i][0],Integer.parseInt(itemArray[i][1]));
상품 이름 분류
itemName+=itemArray[i][0];
상품 개수 문류
count+=Integer.parseInt(itemArray[i][1]);
각 아이템별 개별 개수를 다 더해준다
예약은 1로 고정이지만 예를 들어 상품일 때(프런트에서)
초코파이 3개 우유 2개 이런 경우를 생각해서 만들었다
상품 종류에 따른 추가 작업
if(kind.equals(aboutPayEnums.reservation.getString()))
아마 json안에 json배열로 받으면
이런 작업이 필요 없을 것이다

confrimProduct

payemntService.java

재고/총액 위조를 검사한다
getPayLink

kakopayService.java

통신하는 곳

통신 후 성공적이라면 뭐를 막 준다

vscode

여기서 프런트에게 "next_redirect_pc_url"를 리턴해주면 된다

그리고 windowopen으로 열면 결제창이 뜬다
문제는 자식 창인데 이놈이 결제가 끝나고 부모 창에게 전달하는 법을 모르겠다

이제 결제 시도/후로 가보자
kakopayService

kakopayService.java

세션에서 정보를 꺼낸다
String[][]itemArray=(String[][])httpSession.getAttribute("itemArray");
결제 시도에 필요한 세팅을 한다(카카오 개발자 센터에 잘 나와있다)
body.add("cid", cid);
결제 시도
JSONObject response=getPayLink(approveUrl);
성공했다면 paidproduct테이블에 인서트 할 준비
nomalPayment nomalPayment=new nomalPayment();
인서트 시도
paymentService.insertPayment(nomalPayment,totalPrice);
예약상품이었다면 예약 테이블에 저장 시도
if(kind.equals("reservation")

테스트

http://localhost:3030/reservationPagevar3.html
http://localhost:3030/showReservationPage.html

잘 들어갔다 문제는

쓰흡.. 이창이 꺼지고
부모 창이 저 데이터를 받아야 하는데 모르겠다
url이 8080인 거 보면 백엔드 서버인데...
리다이렉트를 해줘야 하나..? 잘 모르겠다 이 부분은..

 

방법을 알았다 

팝업창으로 띄우고 페이지를 더많들어서 

콜백에서 처리후 리다이렉트 페이지로 보내주면된다

리펙토링에서 다뤄보자

결제 완료 후 crud중 예외가 터진다면

errorController.java

에러컨트롤러로와서 자동 환불이된다