장바구니 crud 작업한 것을 수정 및 테스트를 이번 주에 끝내고 나서, 뒤늦게 결제 API를 설계하기 시작했다. 카카오 페이 API를 사용해서 해보려고 하는데, 생각만큼 쉽지 않았다. 어디서 본 건데 만들어진 API를 가져와서 쓰는 것도 능력이라고..ㅋㅋ
그래도 해야지 어쩌겠나.
카카오 페이 API 문서를 보니 되게 다양한 API를 소개해 놓았다. 결제 요청도 보안상 서버를 통해 요청을 해야 된다고 한다. 그리고 넘겨 주고 받는 파라미터도 굉장히 많다. 실거래를 위해 만들어진 API라 확실히 다르긴 하다.
개인적인 프로젝트 수준에서 테스트 결제를 위해 필요한 데이터를 추리는 작업은 참 골치 아픈 일인 것 같다.
일단 결제 요청 부터 시작하기로 결정했다. 내가 설계한 프로젝트에서는 크게 보면 두 가지 종류의 결제가 있는데 첫 째는 단건 결제이고, 두 번째는 장바구니 상품 결제이다.
그렇게 kakao api를 이용해서 결제 요청을 구현한 과정을 나열해보겠다.
카카오 페이 API 공식 문서
https://developers.kakao.com/docs/latest/ko/kakaopay/common
보다 보면 다양한 기능들이 있다. 필요한 걸 골라 쓰면 될 것 같다.
분석하면서 이 API를 만든 사람들이 정말 대단하다고 느꼈다.
DB 설계 여부
기존에는 DB 설계를 하려고 했었다.
주문, 결제 데이터를 보관하여 이용하려 했으나, 카카오 페이에서 결제 건에 대한 정보를 조회할 수 있게 해 준다.
그래서 DB 설계를 따로 하지 않았다.
(근데 문제가 생겼다. 즉각적인 결제 건에 대한 정보만 일회성으로 제공되는 것이다.. 알바 다녀와서 주문 조회까지 만들어야겠다..!)
단건 결제
제목과 그대로 단일 상품 주문 및 결제 요청 API를 설계한다.
카카오 페이 rest Api를 통해 결제를 하기 때문에 자체적으로 넘겨줄 데이터를 받는 api를 설계해야 한다.
단건 결제 건인데도 넘겨줄 데이터가 참 많다.
프로젝트를 보니 대부분 사람들은 프런트를 같이 하며 ajax나 프론트 엔진을 이용해 쉽게 넘겨주는데 나는 rest api만 설계하다 보니 postman으로 직접 json을 만들어서 넘겨주는 게 참 골치 아픈 일이었다.
결제 로직 (내가 생각한 rest api 설계 시 흐름도)
클라이언트를 제외한 흐름도를 생각했다.
1. 결제 준비
클라이언트 (postman으로 json 요청) => local host server(header, body) => kakao pay server
2. 카카오 페이 서버의 응답
kakao pay server (응답 객체) => localhost server (결제 요청 url) => 클라이언트에게 url 데이터로 응답 (postman)
3. 클라이언트(postman or chrome 브라우저)가 결제 요청
클라이언트 url 요청 => kakao pay server 응답(qr 코드 or 전화번호)
4. 결제 처리
qr 코드로 핸드론으로 테스트 결제 처리
5. 결제 데이터를 응답
kakao pay server (결제 정보를 가진 url로 리다이렉트 응답) : 자동 요청 이므로 이 주소를 가져다가 postman에서 다시 요청해야 한다.
6. url을 postman으로 요청
클라이언트 (postman) => localhost => kakao pay server
7. 결제 정보를 응답
kakao pay server (응답 객체) => localhost => 클라이언트 데이터 응답
카카오 페이 서버에 Request 요청
넘겨줄 데이터는 친절히 명시해 놓았다. 그거에 맞춰서 헤더와 바디를 적절히 넣어 post 방식으로 서버에 요청하면 될 것 같다.
public String kakaoPayReady(OrderReadyDTO orderReadyDTO, UserDTO user) {
/* 서버로 요청할 헤더*/
HttpHeaders headers = new HttpHeaders();
setHeaders(headers);
order_id = user.getUserId() + orderReadyDTO.getItem_name();
userId = user.getUserId();
itemName = orderReadyDTO.getItem_name();
totalAmount = orderReadyDTO.getTotal_Amount();
/* 서버로 요청할 body */
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
setParams(params);
params.add("partner_order_id", order_id);
params.add("partner_user_id", userId);
params.add("item_name", itemName);
params.add("quantity", String.valueOf(orderReadyDTO.getQuantity()));
params.add("total_amount", String.valueOf(totalAmount));
params.add("tax_free_amount", String.valueOf(TAX_FREE_AMOUNT));
return getUrl(headers, params);
}
private String getUrl(HttpHeaders headers, MultiValueMap<String, String> params) {
HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<>(params, headers);
try {
/* 서버 요청 후 응답 객체 받기 */
kakaoPayReadyVO = restTemplate.postForObject(new URI(HOST + KAKAO_PAY_READY),
body, KakaoPayReadyVO.class);
return kakaoPayReadyVO != null ? kakaoPayReadyVO.getNext_redirect_pc_url() : null;
} catch (RestClientException e) {
log.error(e.getMessage());
} catch (URISyntaxException e) {
log.error(e.getMessage());
}
return null;
}
메서드가 중복이 많이 되어서 축약을 했는데 이런 식으로 헤더와 바디 객체를 담아 uri를 생성 후 restTemplate의 postForObject 메서드를 통해 카카오 페이 서버로 요청을 하면
=> (밑에까지 엄청 많다..) 이런 식으로 값을 객체로 넘겨준다.
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;
}
=> 결제 준비 넘겨받을 객체
이하 알바 다녀와서 쓰자
리팩토링!
'📕 Spring Framework > Spring Project' 카테고리의 다른 글
2022.06.02 「DB 동시성 문제」 (0) | 2022.06.02 |
---|---|
2022.06.01 「결제 API - Ver.2」 (2) | 2022.06.01 |
2022.05.28 「쿠키 수정」 (0) | 2022.05.28 |
2022.05.26 「트래픽이 몰렸을 경우」 (0) | 2022.05.26 |
2022.05.25 「Email 인증」 (0) | 2022.05.25 |