์๋ด๊ธ
- ๊ฒฐ์ ํ๋ฆ์ ๋ณด๊ธฐ ์ํด debug ๋ชจ๋์ ๋ก๊ทธ ์ถ๋ ฅ์ด ๋ง์ต๋๋ค
- ๊ตฌํ ์ด๊ธฐ์ ์ฝ๋๋ผ ๋ถ์กฑํ ๋ถ๋ถ์ด ์์ ์ ์์ต๋๋ค. ์ํดํด์ฃผ์ธ์!
- ํ๋ฆ์ ์ดํดํ๊ธฐ ์ํด ๋ฉ์๋ ์์์ ๋ชจ๋ ์ฒ๋ฆฌ๋ฅผ ์ง์ ํ๋๋ก ์ฝ๋๋ฅผ ๋จ์ํํจ
์นด์นด์คํ์ด ๊ฒฐ์ ์ค๋น ์์ฒญ ์ฒ๋ฆฌ๋ฅผ ์ํ
REST ์ปจํธ๋กค๋ฌ ๋ฉ์๋ ๊ตฌํ
- @RestController
- public class KakaoPayController
- @PostMapping("/api/pay/kakaopay")
public ResponseEntity<?> processKakaoPayRequest(@RequestBody OrderInfoDTO orderInfoDTO)
- @PostMapping("/api/pay/kakaopay")
@Transactional
@PostMapping("/api/pay/kakaopay")
public ResponseEntity<?> processKakaoPayRequest(@RequestBody OrderInfoDTO orderInfoDTO) {
try {
// ์ฌ์ฉ์ ์ ๋ณด
String userEmail = SecurityUtils.getCurrentUserEmail();
Long userId = SecurityUtils.getCurrentUserId();
// ํฌ์ธํธ ๋ฐ ๊ฒฐ์ ๊ธ์ก ๊ณ์ฐ
int total_amount = orderInfoDTO.getPoint_100_Quantity() * 110 + orderInfoDTO.getPoint_1000_Quantity() * 1000;
int totalPointAmount = orderInfoDTO.getPoint_100_Quantity() * 100 + orderInfoDTO.getPoint_1000_Quantity() * 1000;
// ๊ฒฐ์ ์์ฒญ ๊ฐ์ฒด ์ค๋น
KakaoPaymentReadyRequestDTO requestDTO = KakaoPaymentReadyRequestDTO.builder()
.cid(kakaoPayConfig.getCid())
.partner_order_id(orderInfoDTO.getPaymentId())
.partner_user_id(userEmail)
.item_name("RiddleBox ํฌ์ธํธ")
.item_code("RB-Point")
.quantity(1)
.total_amount(total_amount)
.tax_free_amount(500)
.approval_url("http://localhost:8080/kakaopay/approval_url")
.cancel_url("http://localhost:8080/kakaopay/approval_url")
.fail_url("http://localhost:8080/kakaopay/approval_url")
.build();
// ๊ฒฐ์ ์ ๋ณด ์์ฑ
PaymentInfo paymentInfo = new PaymentInfo();
RBUser user = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("User not found"));
paymentInfo.firstPaymentInformation(user, orderInfoDTO.getPaymentId(), userEmail, "RiddleBox ํฌ์ธํธ", "RB-Point", total_amount, totalPointAmount);
paymentInfo.updatePaymentStatus(PaymentStatus.INITIATED);
paymentInfoRepository.save(paymentInfo);
// ์นด์นด์คํ์ด API ํธ์ถ
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "SECRET_KEY " + kakaoPayConfig.getSecretKeyDev());
String jsonRequest;
try {
jsonRequest = objectMapper.writeValueAsString(requestDTO);
} catch (JsonProcessingException e) {
throw new RuntimeException("Error converting PaymentRequestDTO to JSON", e);
}
String kakaopayReadyRequestUrl = kakaoPayConfig.getReadyRequestUriCompletion();
HttpEntity<String> entity = new HttpEntity<>(jsonRequest, headers);
ResponseEntity<String> response = restTemplate.postForEntity(kakaopayReadyRequestUrl, entity, String.class);
if (!response.getStatusCode().is2xxSuccessful()) {
throw new RuntimeException("์นด์นด์คํ์ด ํธ์ถ ์คํจ");
}
// ์๋ต ์ฒ๋ฆฌ
KakaoPaymentReadyResponseDTO responseDTO = objectMapper.readValue(response.getBody(), KakaoPaymentReadyResponseDTO.class);
paymentInfo.secondPaymentInformation(responseDTO.getTid(), responseDTO.getCreated_at());
paymentInfo.updatePaymentStatus(PaymentStatus.AWAITING_PAYMENT);
paymentInfoRepository.save(paymentInfo);
// ์ฌ์ฉ์์๊ฒ ์นด์นด์ค ๊ฒฐ์ QR ๋งํฌ ์ ๋ฌ
return ResponseEntity.ok(Collections.singletonMap("nextRedirectPcUrl", responseDTO.getNext_redirect_pc_url()));
} catch (EntityNotFoundException e) {
return new ResponseEntity<>("์ฌ์ฉ์๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.", HttpStatus.NOT_FOUND);
} catch (JsonProcessingException e) {
return new ResponseEntity<>("์๋ฒ ์ค๋ฅ๋ก ์ธํด ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.", HttpStatus.INTERNAL_SERVER_ERROR);
} catch (RuntimeException e) {
return new ResponseEntity<>("๋ด๋ถ ์๋ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
์นด์นด์คํ์ด ๊ฒฐ์ ์น์ธ ์์ฒญ ์ฒ๋ฆฌ๋ฅผ ์ํ
์ปจํธ๋กค๋ฌ ๋ฉ์๋ ๊ตฌํ
- @Controller
- public class PointController
- //์นด์นด์คํ์ด์ ์๋ต(์ฑ๊ณต, ์ทจ์, ์คํจ)์ ๋ค๋ฃจ
- public String handleKakaoPayResponse(@RequestParam(value = "pg_token", required = false) String pgToken, HttpServletRequest request, Model model)
@Transactional
@GetMapping("/kakaopay/approval_url")
public String handleKakaoPayResponse(@RequestParam(value = "pg_token", required = false) String pgToken,
HttpServletRequest request, Model model) throws JsonProcessingException {
// ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์ ID๋ฅผ ํตํด ๋๊ธฐ ์ค์ธ ๊ฒฐ์ ์ ๋ณด ์กฐํ
Long currentUserId = SecurityUtils.getCurrentUserId();
PaymentInfo paymentInfo = kakaoPayService.findAwaitingPaymentPaymentInfo(currentUserId);
// pg_token ์ ๋ฌด ํ์ธ
if (pgToken == null || pgToken.isEmpty()) {
paymentInfo.updatePaymentStatus(PaymentStatus.FAILED);
paymentInfoRepository.save(paymentInfo);
// pg_token์ด ์๋ ๊ฒฝ์ฐ, ๊ฒฐ์ ์คํจ๋ก ๊ฐ์ฃผํ๊ณ ์ฌ์ฉ์์๊ฒ ์๋ด
model.addAttribute("pageType", "paymentCompleted");
model.addAttribute("title", "paymentCompleted");
model.addAttribute("paymentResult", "Fail");
return "layout/layout_base"; // ๊ฒฐ์ ์คํจ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
}
// pg_token์ด ์๋ ๊ฒฝ์ฐ, ๊ฒฐ์ ์น์ธ ์ฒ๋ฆฌ ์งํ
String tid = paymentInfo.getTid();
String partner_order_id = paymentInfo.getPartnerOrderId();
String partner_user_id = paymentInfo.getPartnerUserId();
String cid = kakaoPayConfig.getCid();
paymentInfo.updatePaymentStatus(PaymentStatus.AUTHORIZED);
paymentInfoRepository.save(paymentInfo);
String pg_token = request.getParameter("pg_token");
logger.debug("\n");
logger.debug(" =================== 4 =================== ");
logger.debug("pg_token: {}", pg_token);
logger.debug("\n");
// ์นด์นด์คํ์ด ๊ฒฐ์ ์น์ธ ์์ฒญ
KakaoPaymentApproveRequestDTO approvalDTO = new KakaoPaymentApproveRequestDTO(cid, tid, partner_order_id, partner_user_id, pg_token);
RestTemplate restTemplate2 = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "SECRET_KEY " + kakaoPayConfig.getSecretKeyDev());
HttpEntity<KakaoPaymentApproveRequestDTO> entity = new HttpEntity<>(approvalDTO, headers);
logger.debug("\n");
logger.debug(" =================== 5 =================== ");
logger.debug("HttpEntity<String> entity: {}", entity);
logger.debug("\n");
ResponseEntity<String> response = restTemplate2.postForEntity(kakaoPayConfig.getApproveRequestUriCompletion(), entity, String.class);
logger.debug("\n");
logger.debug(" =================== 6 =================== ");
logger.debug("Response Status Code: {}", response.getStatusCode());
logger.debug("Response Body: {}", response.getBody());
logger.debug("\n");
String responseBody = response.getBody();
if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
// ๊ฒฐ์ ์น์ธ ์ฑ๊ณต, ๊ฒฐ์ ์ ๋ณด ์
๋ฐ์ดํธ
KakaoPaymentApproveResponseDTO completionDTO = objectMapper.readValue(responseBody, KakaoPaymentApproveResponseDTO.class);
paymentInfo.thirdPaymentInformation(completionDTO.getAid(), completionDTO.getAmount(), completionDTO.getCardInfo(), completionDTO.getApprovedAt());
paymentInfo.updatePaymentStatus(PaymentStatus.APPROVED);
paymentInfoRepository.save(paymentInfo);
//ํฌ์ธํธ ์ ์ฅ
kakaoPayService.updateAccountBalanceAfterPurchase(currentUserId, paymentInfo.getTotalPointAmount());
model.addAttribute("pageType", "paymentCompleted");
model.addAttribute("title", "paymentCompleted");
model.addAttribute("newPoint", paymentInfo.getTotalPointAmount());
model.addAttribute("paymentResult", "Success");
return "layout/layout_base"; // ๊ฒฐ์ ์ฑ๊ณต ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
} else {
// ๊ฒฐ์ ์น์ธ ์คํจ ์ฒ๋ฆฌ
paymentInfo.updatePaymentStatus(PaymentStatus.FAILED);
paymentInfoRepository.save(paymentInfo);
model.addAttribute("pageType", "paymentCompleted");
model.addAttribute("title", "paymentCompleted");
model.addAttribute("paymentResult", "Fail");
return "layout/layout_base"; // ๊ฒฐ์ ์คํจ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ
}
}