- [셸위:게임 친구 매칭 사이트] 토스 페이먼츠 API - 결제 기능2024년 09월 25일
- Song hyun
- 작성자
- 2024.09.25.:14
728x90반응형[셸위:게임 친구 매칭 사이트] 토스 페이먼츠 API - 결제 기능
이번 프로젝트에서는 토스 페이먼츠, 카카오 페이 총 두 개의 결제 API를 사용해서 현금 결제 기능을 구현해봤다. 이번에는 토스 페이먼츠 결제 API에 대해 설명해보려고 한다.
https://docs.tosspayments.com/reference#%EA%B2%B0%EC%A0%9C
결제 API의 과정은 크게 아래와 같이 나뉜다.
1. 클라이언트: 결제정보 전송
2. 서버: 가주문 정보를 DB에 저장 + 토스 API에 결제 요청
3. 토스 서버: 결제 요청에 대한 response 전달
4. 서버: DB 상의 가주문 정보-response 대조 후 토스 서버에 결제 승인 요청
5. 토스 서버: 결제 요청에 대한 response 전달
6. 서버: 클라이언트 측에 결제에 대한 결과 출력1. 결제창 (JSP)
-결제창 측에서는 라디오박스, 체크박스를 통해 유저가 조항에 동의했는지, 어떤 가격을 체크했는지를 점검한다. 해당 유효성 검사는 JS 측에서 onclick 함수를 통해 이뤄진다.
-유효성 검사를 통과한 뒤에는 사용자가 어떤 결제 방식을 선택했는지/얼마를 결제할건지를 fetch를 통해 서버로 post 방식으로 보내게 된다.
(1) html 코드
<h4>현재 보유 캐쉬 : ${user.currentCash}</h4> <div class="choose-cash"> <h4> 충전할 캐쉬 </h4> <h4> 결제 하실 금액 </h4> <div class="choose-container"> <div> 1,000 원<input type="radio" name="cash-btn" value="1000"> </div> <div> 3,000 원<input type="radio" name="cash-btn" value="3000"> </div> <div> 5,000 원<input type="radio" name="cash-btn" value="5000"> </div> <div> 10,000 원<input type="radio" name="cash-btn" value="10000"> </div> <div> 30,000 원<input type="radio" name="cash-btn" value="30000"> </div> </div> </div> <div class="cash-container"> <input type="checkbox" class="check1">[필수] 전체 동의</div> <input type="checkbox" class="check2">상품, 가격, 결제 전 주의사항을 확인하였습니다.</div> </div> <h5>결제 수단 선택</h5> <div class="cash-container"> <div class="button-container"> <button class = "resultButton-1" onclick="startPayment(this)" value="kakao">카카오페이</button> <button class = "resultButton-2" onclick="startPayment(this)" value="toss">토스페이</button> </div> </div>
(2) 자바스크립트
// 약관 동의 체크박스 var chk1 = document.querySelector(".check1"); var chk2 = document.querySelector(".check2"); // 결제 진행 함수 function startPayment(button) { let btnValue = button.value; let cashAmount = document.querySelector('input[name="cash-btn"]:checked'); // 유효성 검사 - 약관 동의 if (!chk1.checked || !chk2.checked) { alert('결제 전 주의사항과 동의 내역을 확인해주세요.'); return; } // 유효성 검사 - 결제 금액 선택 if (!cashAmount) { alert('결제할 금액을 선택해주세요.'); return; } // 결제 진행 if (btnValue == "kakao") { console.log("카카오 결제 요청" + cashAmount.value); requestPaymentToKakao(cashAmount.value); } else if (btnValue == "toss") { console.log("토스 결제 요청" + cashAmount.value); requestPaymentToToss(cashAmount.value); } }
2. TossController
-컨트롤러 측에서는 크게 두 가지 메서드로 결제 API를 운용한다. 첫번째는 결제 요청, 두 번째는 결제 승인이다.
(1) 결제 요청에서는 DB에 보안을 위한 가주문 정보를 저장한다. 그리고 토스 서버에 결제 요청 메세지를 보내게 된다.
(2) 결제 승인 단계에서는 가주문과 주문 내역의 orderId, userId, amount(결제 금액)을 대조하고, 결제 정보가 동일하다면 결제 승인 요청을 토스 서버에 전송하게 된다.
해당 동작들을 TossService에 보내고, TossRepository-Order.xml에 차례대로 요청하게 된다.
/** * 토스 페이 - 결제 전 정보 저장 (정보 무결성) * @param orderId * @param paymentKey * @param amount * @return * @throws UnsupportedEncodingException * @throws IOException * @throws InterruptedException * @throws URISyntaxException */ @ResponseBody @PostMapping("/send-request") public void resultTossPay(@RequestBody Map<String, Object> payload) throws UnsupportedEncodingException, URISyntaxException { // 받은 정보들 파싱 String orderId = (String) payload.get("orderId"); Long amount = Long.valueOf(payload.get("totalAmount").toString()); System.out.println(orderId); User user = (User)httpSession.getAttribute("principal"); int userId = user.getUserId(); // tosspayservice를 통해 toss에 결제 요청 - response 값 반환 String paymentKey = tossPayService.sendTossPayRequest(orderId, orderId, userId, amount); SessionUtils.addAtribute("paymentKey", paymentKey); // paymentKey 생성 return; } /** * 토스 페이먼츠 - 결제 요청 * @return * @throws URISyntaxException * @throws InterruptedException * @throws IOException */ @GetMapping("/success") public String resultTossPay(@RequestParam("orderId")String orderId, @RequestParam("paymentKey")String paymentKey, @RequestParam("amount") Long amount, Model model) throws URISyntaxException, IOException, InterruptedException { User user = (User)httpSession.getAttribute("principal"); Integer userId = user.getUserId(); // 가주문 생성 tossPayService.sendTossPayRequest(paymentKey, orderId, userId, amount); SessionUtils.addAtribute("paymentKey", paymentKey); // paymentKey 생성 // tosspayservice를 통해 toss에 결제 요청 - response 값 반환 String responseEntity = tossPayService.sendTossPayRequestFinish(orderId, paymentKey,amount); String getResult = responseEntity.toString(); // 주문 상태 변경 orderService.changeOrderStatus(paymentKey); // 유저 캐쉬 상태 변경 orderService.updateUsersCurrentCash(user.getUserId(),amount); User updateUser = userService.searchByUserId(user.getUserId()); httpSession.setAttribute("principal",user); model.addAttribute("user", updateUser); if(responseEntity.contains("code")) { return "/cash/chargeResult" ; } return "/cash/chargeResult" ; } /** * 결제 성공 페이지 * @param pgToken * @return */ // http://localhost:8080/toss-pay/result @GetMapping("/result11") public String resultKakaoPay(@RequestParam("pg_token") String pgToken) { return "../test/main"; }
-한 번 해보면 쉬워지는 게 API라고 느끼게 해준 계기였다. 처음에는 정말 어려웠는데, 한번 요청을 주고받는 걸 경험해보고 나니 어떤 식으로 API가 작동하고, 요청을 받아오는 지 알 수 있게 되어 뿌듯했다.
-결제 요청 API 구현에만 어언 일주일이 걸렸는데(그 구조와 원리를 이해하는 데 시간이 많이 걸렸다.) 처음에는 막무가내로 다른 사람들이 어떤 식으로 코드를 작성했는지, 깃허브와 블로그를 찾아봤다. 하지만 각자 사용하는 라이브러리와 그 버전이 다르다보니, 따라 쓴다고 해도 생각처럼 잘 되지 않았다. 결국 내가 스스로 할 수 밖에 없었다. (...)
매일 남아 대안으로 사용할 수 있는 여러 메서드나 클래스를 찾기도 하고, 토스 페이먼츠 API 문서를 여러번 읽거나 다른 API들의 로직 구조를 살펴보기도 하고, 몇날 며칠을 찾아봐도 잘 풀리지 않는 문제는 토스 페이먼츠 개발자 커뮤니티에 묻기도 했다. 그 덕분인지 결국 마지막에는 다른 분들의 도움+내 힘으로 API를 작동시킬 수 있었다. 결제 로직을 공부할 수 있어 뿌듯했던 기능!!
728x90반응형'💡My project > 셸위 : 게임 친구 매칭 사이트' 카테고리의 다른 글
[셸위:게임 친구 매칭 사이트] 카카오 페이 API - 결제 취소 기능 (5) 2024.09.25 [셸위:게임 친구 매칭 사이트] 카카오 페이 API - 결제 기능 (0) 2024.09.25 [셸위:게임 친구 매칭 사이트] 최종 정리 (2) 2024.09.25 [셸위:게임 친구 매칭 사이트] 부일기획 멘토링(9.6) (0) 2024.09.06 [셸위:게임 친구 매칭 사이트] 드롭다운 메뉴 구현 (1) 2024.09.04 다음글이전글이전 글이 없습니다.댓글