2022.06.01 ใ๊ฒฐ์ API - Ver.2ใ
์ง๋๋ฒ ํฌ์คํ ์ ์ด์ด ์์ฑํ๊ฒ ๋ค!
https://sweeeetgoguma.tistory.com/entry/20220529-%E3%80%8C%EA%B2%B0%EC%A0%9C-API%E3%80%8D
2022.05.29 ใ๊ฒฐ์ APIใ
์ฅ๋ฐ๊ตฌ๋ crud ์์ ํ ๊ฒ์ ์์ ๋ฐ ํ ์คํธ๋ฅผ ์ด๋ฒ ์ฃผ์ ๋๋ด๊ณ ๋์, ๋ค๋ฆ๊ฒ ๊ฒฐ์ API๋ฅผ ์ค๊ณํ๊ธฐ ์์ํ๋ค. ์นด์นด์ค ํ์ด API๋ฅผ ์ฌ์ฉํด์ ํด๋ณด๋ ค๊ณ ํ๋๋ฐ, ์๊ฐ๋งํผ ์ฝ์ง ์์๋ค. ์ด๋์ ๋ณธ ๊ฑด๋ฐ
sweeeetgoguma.tistory.com
์นด์นด์คํ์ด Rest API๋ฅผ ์ด์ฉํด ๊ฒฐ์ ์ค๋น์ ํ์ํ ๊ฐ์ฒด๋ฅผ ์ค๊ณํ๋ ๊ฒ๊น์ง ์๋ฃํ๋ค. ์นด์นด์ค ํ์ด ํ๋ก์ธ์ค์ ๋ฐ๋ผ ์ค๋น์ ๊ฒฐ์ ๋ฐ ์น์ธ์ ์ํ ํต์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผ ํ๋ค. ์ด ๊ณผ์ ์์์ ์๋ง์ ์ฝ์ง์ด ์์๋ค. ์ฌ์ค ์ฝ์ง์ด๋ผ๊ธฐ๋ณด๋ค๋ ๋ด๊ฐ ์ ํํ ๊ฐ๋ ์ ์ดํดํ์ง ๋ชปํ๊ณ API๋ฅผ ์ ์ฉ์ํจ ๊ฒ์ด๋ค. API๋ฅผ ๋์ด๋ค ์ฐ๋ ๊ฒ์ ๋ง๋งํ ๊ฒ ์๋ ๊ฒ ๊ฐ๋ค.
์ด์ ๊ฒฐ์ ์น์ธ๊น์ง์ ๊ณผ์ ์ ๋์ดํด ๋ณด๊ฒ ๋ค.
์ด๋ฒ ๊ฒฐ์ ๊ณผ์ ์ ์ฅ๋ฐ๊ตฌ๋๋ฅผ ํตํ ์ฃผ๋ฌธ ๋ฐ ๊ฒฐ์ ๋ก ์งํํด๋ณด๊ฒ ๋ค.
Postman tool ์ฌ์ฉ
1. ๊ฒฐ์ ์ค๋น
๊ฒฐ์ ๋ฅผ ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ด ์๋ฒ์ ๋๊ธฐ๋ฉฐ, ๋ด ์๋ฒ์์ ์นด์นด์คํ์ด๋ก ํ์ํ ํ๋ผ๋ฏธํฐ๋ค์ ๋ด์ ์์ฒญํ๋ ์ผ์ด๋ค.
์ฐ์ ๋ก๊ทธ์ธ ๋จผ์ ํด๋ณด์!
๋ก๊ทธ์ธ์ ์์ฒญํ๋ฉด ํ ํฐ ๊ฐ์ data๋ก ๋ฐ๋๋ค.
=> ํ ํฐ ๊ฐ ์ ์ฅ
์ฅ๋ฐ๊ตฌ๋ ์ํ ์ถ๊ฐ
=> ํ์ฌ ์ฅ๋ฐ๊ตฌ๋๊ฐ ์๋ค.
์ํ์ ์ถ๊ฐํด๋ณด์.
=> ์ฅ๋ฐ๊ตฌ๋ ๋ชฉ๋ก ์กฐํ
์ด์ ์ด ์ฅ๋ฐ๊ตฌ๋ ์ํ์ ๊ฐ์ง๊ณ ๊ฒฐ์ ์ค๋น๋ฅผ ํด๋ณด๊ฒ ๋ค
์ฐ์ ๋ด ์๋ฒ๋ก ๊ฒฐ์ ์์ฒญ์ ๋ณด๋ธ๋ค.
@Auth(role = Auth.Role.BASIC_USER)
@PostMapping("/cart")
public Message cartOrderAction(HttpServletRequest request) throws UnsupportedEncodingException {
Cookie[] cookies = request.getCookies();
Optional<Cookie> cartCookie = CookieUtil.getCartCookie(cookies);
if (cartCookie.isEmpty()) {
return new Message
.Builder(EMPTY_CART_DATA)
.httpStatus(HttpStatus.BAD_REQUEST)
.build();
}
String url = kakaoPayService.getCartKakaoPayUrl(CookieUtil.getItemNoArr(cartCookie.get()),
request,
CookieUtil.getTotalAmount(cartCookie.get()));
if (url == null) {
return getFailedPayMessage();
}
return new Message
.Builder(url)
.httpStatus(HttpStatus.OK)
.message(PAY_URI_MSG)
.build();
}
public String getCartKakaoPayUrl(String[] productNoArr, HttpServletRequest request, int totalAmount) {
/* ์๋ฒ๋ก ์์ฒญํ ํค๋*/
HttpHeaders headers = new HttpHeaders();
setHeaders(headers);
user = userService.findById((String) request.getAttribute("tokenUserId"));
itemName = productService.findByNumber(Integer.parseInt(productNoArr[0])).getProductName() + " ๊ทธ ์ธ " + (productNoArr.length - 1) + "๊ฐ";
orderId = user.getUserId() + ", " + itemName;
userId = user.getUserId();
this.totalAmount = totalAmount;
/* ์๋ฒ๋ก ์์ฒญํ body */
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
setParams(params, request);
params.add("partner_order_id", orderId);
params.add("partner_user_id", userId);
params.add("item_name", itemName);
params.add("item_code", String.join(", ", productNoArr));
params.add("quantity", String.valueOf(productNoArr.length));
params.add("total_amount", String.valueOf(totalAmount));
params.add("tax_free_amount", String.valueOf(TAX_FREE_AMOUNT));
return getPayUrl(headers, params);
}
private void setHeaders(HttpHeaders headers) {
restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
headers.add("Authorization", "KakaoAK " + ADMIN_KEY);
headers.add("Accept", MediaType.APPLICATION_JSON_VALUE);
headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8");
}
private void setParams(MultiValueMap<String, String> params, HttpServletRequest request) {
params.add("cid", TEST_CID);
params.add("approval_url", getUrl(request) + APPROVAL_URI);
params.add("cancel_url", getUrl(request) + CANCEL_URI);
params.add("fail_url", getUrl(request) + FAIL_URI);
}
private String getPayUrl(HttpHeaders headers, MultiValueMap<String, String> params) {
HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<>(params, headers);
try {
/* ์๋ฒ ์์ฒญ ํ ์๋ต ๊ฐ์ฒด ๋ฐ๊ธฐ */
kakaoPayReadyDTO = restTemplate.postForObject(HOST + KAKAO_PAY_READY,
body, KakaoPayReadyDTO.class);
return kakaoPayReadyDTO != null ? kakaoPayReadyDTO.getNext_redirect_pc_url() : null;
} catch (RestClientException e) {
log.error(e.getMessage());
}
return null;
}
private String getUrl(HttpServletRequest request) {
return request.getRequestURL().toString().replace(request.getRequestURI(), "");
}
public class KakaoPayReadyVO {
private String tid, next_redirect_pc_url;
private Date created_at;
@ConstructorProperties({"tid","next_redirect_pc_url","created_at"})
public KakaoPayReadyVO(String tid, String next_redirect_pc_url, Date created_at) {
this.tid = tid;
this.next_redirect_pc_url = next_redirect_pc_url;
this.created_at = created_at;
}
=> ์์ฒญ์ ํ๋ฉด ์นด์นด์ค ํ์ด๋ ์ด ๊ฐ์ฒด๋ฅผ ํตํด ํ๋ผ๋ฏธํฐ๋ฅผ json ํํ์์ ๊ฐ์ฒด๋ก ๋ณํํด ์๋ตํด์ค๋ค. ์ ๊ธฐ ์๋ next_redirect_url์ด ๊ฒฐ์ ์์ฒญ url!
2. ๊ฒฐ์ ์น์ธ
์ด์ ์ URL๋ก ๋ธ๋ผ์ฐ์ ์์ ์์ฒญํด๋ณด์!
=> ๋ธ๋ผ์ฐ์ ์์ ์์ฒญ์ ํ๋ฉด ๋ฐ๋ชจ QR ์ฝ๋๊ฐ ๋ฌ๋ค. ์ด๊ฒ์ ํด๋ํฐ์ผ๋ก ๊ฒฐ์ ํด๋ณด์
=> ํด๋ํฐ์ผ๋ก ํ ์คํธ ๊ฒฐ์ ๋ฅผ ๋ง์น๊ณ ๋๋ฉด ๊ฒฐ์ ์ฑ๊ณต URL๋ก ๋ฆฌ๋ค์ด๋ ํธ ๋๋ค.
ํ์ง๋ง ๋๋ RESTAPI ๋ง์ ์ค๊ณํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ๋ณด์ฌ์ค Front๊ฐ ์๋ค. ๊ทธ๋์ Postman์์ ์ URL๋ก ์์ฒญ์ ํด๋ณด๊ฒ ๋ค.
=> ์ด๋ ๊ฒ ๊ฒฐ์ ์น์ธ ๋ฐ ๊ฒฐ์ ์ ๋ณด๋ฅผ ์ข ํฉ์ ์ผ๋ก ์ป์ ์ ์๋ค.
์ด์ ์ด ๊ฒ์ ๊ฐ์ฒด๋ฅผ ํตํด DB์ ์ ์ฅ์ ํ ์ ์์ ๊ฒ ๊ฐ๋ค.
๋ฆฌํฉํ ๋ง!
๊ฒฐ์ API ๋ฆฌํฉํ ๋ง - [2] (feat. WebClient)
https://sweeeetgoguma.tistory.com/entry/%EA%B2%B0%EC%A0%9C-API-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81-1-feat-%EC%A0%84%EB%9E%B5-%ED%8C%A8%ED%84%B ๊ฒฐ์ API ๋ฆฌํฉํ ๋ง - [1] (feat. ์ ๋ต ํจํด) ๊ฒฐ์ API๋ฅผ ๋ฆฌํฉํ ๋ง ์์ํ๋ฉฐ ์ธ๋ถ API๋ฅผ ์ฐ๋
sweeeetgoguma.tistory.com