보라코딩
Day105_230526_스프링부트 카카오 페이 결제하기 (공부중...) 본문
일단 따라해서 구현이 되긴 되었는데...
DB 저장하는 것과
실제 내 카드로 결제되게 해봐야겠다..!!!
HTML
참고로 html은 pay 폴더 안에 있음!
kakaoPay.html
<!DOCTYPE html>
<html lagn="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:replace="header_footer/header :: headerFragment"></th:block>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" th:href="@{/css/store_css.css}">
<style>
.kakaoBtn{
background-color: #F7E600;
padding: 10px;
border: none;
outline: none;
border-radius: 10px;
}
</style>
</head>
<body>
<div class = "container">
<h1 class="purple"> 결제화면 </h1>
<form method="post" action="/pay/kakaoPay">
<button class="kakaoBtn">카카오페이 결제</button>
</form>
</div>
<th:block th:replace="header_footer/footer :: footerFragment"></th:block>
</body>
</html>
<html lagn="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:replace="header_footer/header :: headerFragment"></th:block>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" th:href="@{/css/store_css.css}">
<style>
.kakaoBtn{
background-color: #F7E600;
padding: 10px;
border: none;
outline: none;
border-radius: 10px;
}
</style>
</head>
<body>
<div class = "container">
<h1 class="purple"> 결제화면 </h1>
<form method="post" action="/pay/kakaoPay">
<button class="kakaoBtn">카카오페이 결제</button>
</form>
</div>
<th:block th:replace="header_footer/footer :: footerFragment"></th:block>
</body>
</html>
kakaoPaySuccess.html
<!DOCTYPE html>
<html lagn="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:replace="header_footer/header :: headerFragment"></th:block>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" th:href="@{/css/store_css.css}">
</head>
<body>
카카오페이 결제가 정상적으로 완료되었습니다.
결제일시: [[${info.approved_at}]]<br/>
주문번호: [[${info.partner_order_id}]]<br/>
상품명: [[${info.item_name}]]<br/>
상품수량: [[${info.quantity}]]<br/>
결제금액: [[${info.amount.total}]]<br/>
결제방법: [[${info.payment_method_type}]]<br/>
<h2>[[${info}]]</h2>
<th:block th:replace="header_footer/footer :: footerFragment"></th:block>
</body>
</html>
<html lagn="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<th:block th:replace="header_footer/header :: headerFragment"></th:block>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" th:href="@{/css/store_css.css}">
</head>
<body>
카카오페이 결제가 정상적으로 완료되었습니다.
결제일시: [[${info.approved_at}]]<br/>
주문번호: [[${info.partner_order_id}]]<br/>
상품명: [[${info.item_name}]]<br/>
상품수량: [[${info.quantity}]]<br/>
결제금액: [[${info.amount.total}]]<br/>
결제방법: [[${info.payment_method_type}]]<br/>
<h2>[[${info}]]</h2>
<th:block th:replace="header_footer/footer :: footerFragment"></th:block>
</body>
</html>
domain
AmountVO
package com.tastemate.domain;
import lombok.Data;
@Data
public class AmountVO {
private Integer total, tax_free, vat, point, discount;
}
import lombok.Data;
@Data
public class AmountVO {
private Integer total, tax_free, vat, point, discount;
}
CardVO
package com.tastemate.domain;
public class CardVO {
private String purchase_corp, purchase_corp_code;
private String issuer_corp, issuer_corp_code;
private String bin, card_type, install_month, approved_id, card_mid;
private String interest_free_install, card_item_code;
}
public class CardVO {
private String purchase_corp, purchase_corp_code;
private String issuer_corp, issuer_corp_code;
private String bin, card_type, install_month, approved_id, card_mid;
private String interest_free_install, card_item_code;
}
KakaoPayApprovalVO
package com.tastemate.domain;
import lombok.Data;
import java.util.Date;
@Data
public class KakaoPayApprovalVO {
//response
private String aid, tid, cid, sid;
private String partner_order_id, partner_user_id, payment_method_type;
private AmountVO amount;
private CardVO card_info;
private String item_name, item_code, payload;
private Integer quantity, tax_free_amount, vat_amount;
private Date created_at, approved_at;
}
import lombok.Data;
import java.util.Date;
@Data
public class KakaoPayApprovalVO {
//response
private String aid, tid, cid, sid;
private String partner_order_id, partner_user_id, payment_method_type;
private AmountVO amount;
private CardVO card_info;
private String item_name, item_code, payload;
private Integer quantity, tax_free_amount, vat_amount;
private Date created_at, approved_at;
}
KakaoPayReadyVO
package com.tastemate.domain;
import lombok.Data;
import java.util.Date;
@Data
public class KakaoPayReadyVO {
private String tid, next_redirect_pc_url;
private Date created_at;
}
import lombok.Data;
import java.util.Date;
@Data
public class KakaoPayReadyVO {
private String tid, next_redirect_pc_url;
private Date created_at;
}
Controller
PayController
package com.tastemate.controller;
import com.tastemate.service.KakaoPay;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/pay/*")
@Slf4j
public class PayController {
@Setter(onMethod_ = @Autowired)
private KakaoPay kakaopay;
@GetMapping("/kakaoPay")
public void kakaoPayGet() {
log.info("kakaoPay get............................................");
}
@PostMapping("/kakaoPay")
public String kakaoPay() {
log.info("kakaoPay post............................................");
return "redirect:" + kakaopay.kakaoPayReady();
}
@GetMapping("/kakaoPaySuccess")
public void kakaoPaySuccess(@RequestParam("pg_token") String pg_token, Model model) {
log.info("kakaoPaySuccess get............................................");
log.info("kakaoPaySuccess pg_token : " + pg_token);
model.addAttribute("info", kakaopay.kakaoPayInfo(pg_token));
}
}
import com.tastemate.service.KakaoPay;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/pay/*")
@Slf4j
public class PayController {
@Setter(onMethod_ = @Autowired)
private KakaoPay kakaopay;
@GetMapping("/kakaoPay")
public void kakaoPayGet() {
log.info("kakaoPay get............................................");
}
@PostMapping("/kakaoPay")
public String kakaoPay() {
log.info("kakaoPay post............................................");
return "redirect:" + kakaopay.kakaoPayReady();
}
@GetMapping("/kakaoPaySuccess")
public void kakaoPaySuccess(@RequestParam("pg_token") String pg_token, Model model) {
log.info("kakaoPaySuccess get............................................");
log.info("kakaoPaySuccess pg_token : " + pg_token);
model.addAttribute("info", kakaopay.kakaoPayInfo(pg_token));
}
}
Service
KakaoPay
package com.tastemate.service;
import com.tastemate.domain.KakaoPayApprovalVO;
import com.tastemate.domain.KakaoPayReadyVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.net.URISyntaxException;
@Service
@Slf4j
public class KakaoPay {
private static final String HOST = "https://kapi.kakao.com";
private KakaoPayReadyVO kakaoPayReadyVO;
private KakaoPayApprovalVO kakaoPayApprovalVO;
//결제 요청
public String kakaoPayReady() {
log.info("kakaoPayReady..................");
RestTemplate restTemplate = new RestTemplate();
// 서버로 요청할 Header
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "KakaoAK " + "admin키!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8");
// 서버로 요청할 Body
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("cid", "TC0ONETIME");
params.add("partner_order_id", "1234");
params.add("partner_user_id", "bora");
params.add("item_name", "강사님과 식사하기");
params.add("quantity", "1");
params.add("total_amount", "1234");
params.add("tax_free_amount", "100");
params.add("approval_url", "http://localhost:8080/pay/kakaoPaySuccess");
params.add("cancel_url", "http://localhost:8080/kakaoPayCancel");
params.add("fail_url", "http://localhost:8080/kakaoPaySuccessFail");
HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<MultiValueMap<String, String>>(params, headers);
try {
kakaoPayReadyVO = restTemplate.postForObject(new URI(HOST + "/v1/payment/ready"), body, KakaoPayReadyVO.class);
//log.info("" + kakaoPayReadyVO);
return kakaoPayReadyVO.getNext_redirect_pc_url();
} catch (RestClientException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return "/pay/kakaoPay";
}
//결제 승인
public KakaoPayApprovalVO kakaoPayInfo(String pg_token) {
log.info("KakaoPayInfoVO............................................");
log.info("-----------------------------");
RestTemplate restTemplate = new RestTemplate();
// 서버로 요청할 Header
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "KakaoAK " + "admin키!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8");
// 서버로 요청할 Body
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("cid", "TC0ONETIME");
params.add("tid", kakaoPayReadyVO.getTid());
params.add("partner_order_id", "1234");
params.add("partner_user_id", "bora");
params.add("pg_token", pg_token);
params.add("total_amount", "1234");
HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<MultiValueMap<String, String>>(params, headers);
try {
kakaoPayApprovalVO = restTemplate.postForObject(new URI(HOST + "/v1/payment/approve"), body, KakaoPayApprovalVO.class);
log.info("" + kakaoPayApprovalVO);
return kakaoPayApprovalVO;
} catch (RestClientException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
}
import com.tastemate.domain.KakaoPayApprovalVO;
import com.tastemate.domain.KakaoPayReadyVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import java.net.URI;
import java.net.URISyntaxException;
@Service
@Slf4j
public class KakaoPay {
private static final String HOST = "https://kapi.kakao.com";
private KakaoPayReadyVO kakaoPayReadyVO;
private KakaoPayApprovalVO kakaoPayApprovalVO;
//결제 요청
public String kakaoPayReady() {
log.info("kakaoPayReady..................");
RestTemplate restTemplate = new RestTemplate();
// 서버로 요청할 Header
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "KakaoAK " + "admin키!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8");
// 서버로 요청할 Body
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("cid", "TC0ONETIME");
params.add("partner_order_id", "1234");
params.add("partner_user_id", "bora");
params.add("item_name", "강사님과 식사하기");
params.add("quantity", "1");
params.add("total_amount", "1234");
params.add("tax_free_amount", "100");
params.add("approval_url", "http://localhost:8080/pay/kakaoPaySuccess");
params.add("cancel_url", "http://localhost:8080/kakaoPayCancel");
params.add("fail_url", "http://localhost:8080/kakaoPaySuccessFail");
HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<MultiValueMap<String, String>>(params, headers);
try {
kakaoPayReadyVO = restTemplate.postForObject(new URI(HOST + "/v1/payment/ready"), body, KakaoPayReadyVO.class);
//log.info("" + kakaoPayReadyVO);
return kakaoPayReadyVO.getNext_redirect_pc_url();
} catch (RestClientException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return "/pay/kakaoPay";
}
//결제 승인
public KakaoPayApprovalVO kakaoPayInfo(String pg_token) {
log.info("KakaoPayInfoVO............................................");
log.info("-----------------------------");
RestTemplate restTemplate = new RestTemplate();
// 서버로 요청할 Header
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", "KakaoAK " + "admin키!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8");
// 서버로 요청할 Body
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
params.add("cid", "TC0ONETIME");
params.add("tid", kakaoPayReadyVO.getTid());
params.add("partner_order_id", "1234");
params.add("partner_user_id", "bora");
params.add("pg_token", pg_token);
params.add("total_amount", "1234");
HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<MultiValueMap<String, String>>(params, headers);
try {
kakaoPayApprovalVO = restTemplate.postForObject(new URI(HOST + "/v1/payment/approve"), body, KakaoPayApprovalVO.class);
log.info("" + kakaoPayApprovalVO);
return kakaoPayApprovalVO;
} catch (RestClientException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return null;
}
}
이 블로그 참고함!
[Spring Boot] 카카오페이 API
#[Spring Boot] 카카오페이 API 생각보다 카카오페이 API에 대한 글이 적어서 포스팅을 해보려한다. 스프링 부트에서 카카오페이를 붙이는 데 도움이 되었으면 한다.본 글은 단건결제 프로세스만 설
scorpio-mercury.tistory.com
도움 많이 받음!!
스프링부트에서 카카오 페이 API 연동하기
자꾸 미루고 있었는데 면접준비도 할겸 오늘은 포스팅을 하기로 마음먹었습니다...ㅎㅎ왜, 어떻게 구현하는지 상세하게 적었으니 빠르게 구현하실분은 그냥 코드부분만 보시면 됩니다.먼저 카
velog.io
카카오 페이( Kakao pay) 기능구현
이번에 간편결제 기능인 카카오 페이 구현을 진행했으며 작업이 모두 끝나서 이를 정리해두려 한다. 준비하기 관리자 모드 > 환경설정 > 전자결제 설정 > 국내 전자 결제에서 PG를 신청하면서 동
jungkeung.tistory.com
Kakao Developers
카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
developers.kakao.com
'코딩 > Spring' 카테고리의 다른 글
Day107_230531_ 프로젝트 시작한지 2주째.. 시간이 없다! (0) | 2023.05.31 |
---|---|
Day106_230530_카카오페이 결제 api (ajax로, 결제 취소까지) (0) | 2023.05.30 |
Day104_230525_ 프로젝트 진행사항(UI 위주) (0) | 2023.05.25 |
스프링부트 맛집별 별점구현 (Join, SQL문) (1) | 2023.05.25 |
스프링부트 JOIN 하여 사용하기 (1:N) resultMap, collection 사용하기 (0) | 2023.05.24 |