본문 바로가기

Web Application/Spring boot

[spring] 간편결제 - 카카오페이(kakao pay) 결제 api (1) 단건결제 기능 구현

728x90
반응형
SMALL

많이 사용하는 간편 결제 서비스 중 카카오페이 api를 사용하여 결제 기능을 구현하는 방법이다.

 

카카오페이 API 제공 기능
  1. 단건 결제
  2. 정기 결제
  3. 주문 조회
  4. 결제 취소

카카오페이 API에서는 위 4가지 기능을 제공하며, 개발 전 결제 프로세스를 먼저 이해하여야 한다.

 

1.  카카오페이 API 결제 프로세스

카카오페이 단건결제를 이용하기 위해서는 크게 결제 준비 / 결제 승인 api 요청을 해야 결제가 완료된다. 

 

먼저, 결제 전 "결제준비" 단계의 request 요청은 가맹점코드, 주문번호 등 결제 단계에 필요한 상세 정보들을 먼저 카카오페이 서버단으로 전송하여 결제를 "시작"하는 단계이다.

 

결제 준비 요청 단계에서 응답 받은 응답값을 통해 "결제승인" request 요청을 하여 최종적으로 결제를 완료한다.

사용자가 페이 버튼을 누르면 결제 준비 api를 먼저 호출한다.

 

2-1. 결제 요청 Script 

<button id="kaobtn" style="background: #fee500; color:#000; border-radius: 12px; padding: 10px 20px;">
                        카카오페이</button>

카카오페이 결제 버튼을 만든 후 버튼 클릭 시 실행할 스크립트 함수를 만든다.

$("#kaobtn").click(function (){
        /**
         * 결제 버튼 클릭 시
         * 이름 / 배송지 등등.. 필수정보 입력 유효성 체크
         * 여기서는 생략
         */

        /**
         * @ data 화면에서 입력받을 수 있는 기본 결제 정보만 넘겨주기 (나머지는 뒤에서 처리)
         * @ return 카카오톡 결제요청 페이지
         */

        $.ajax({
            type:'get',
            url:'/pay/ready',
            data:{
                item_name : "아이폰 14 pro",
                quantity : "1",
                total_amount : "1400000",
                tax_free_amount : "0"
            },
            success:function(res){
                location.href = res.next_redirect_mobile_url;
            }
        })
    })

스크립트 단에서는 화면에서만 입력 받을 수 있는 필수 값만 입력 받고,

나머지는 컨트롤러 또는 서비스에서 처리한다.

 

2-2. VO, Controller, Serivce 생성

1. 결제준비

VO생성

@Getter
@Setter
@ToString
public class KakaoPayReadyVO {
    private String tid; //결제고유번호
    private String next_redirect_mobile_url; //요청한 클라이언트가 모바일 웹
    private String next_redirect_pc_url; //요청한 클라이언트가 PC 웹
    private String partner_order_id; //가맹점 주문번호
}

 

컨트롤러

// 결제 버튼 클릭 시 호출
@GetMapping("/pay/ready")
public @ResponseBody KakaoPayReadyVO kakaoPay(@RequestParam Map<String, Object> params){
    KakaoPayReadyVO res = payService.kakaoPay(params);
    log.info(res.toString());
    return res;
}

 

서비스

public KakaoPayReadyVO kakaoPay(Map<String, Object> params){
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "KakaoAK {key}"); //발급받은 adminkey

        /*
        * 결제번호는 고유한 결제번호로 생성해줘야 한다.
        * 여기서는 임시로 그냥 KAO20230318001
        * */
        MultiValueMap<String, Object> payParams = new LinkedMultiValueMap<String, Object>();

        payParams.add("cid", "TC0ONETIME");
        payParams.add("partner_order_id", "KAO20230318001");
        payParams.add("partner_user_id", "kakaopayTest");
        payParams.add("item_name", params.get("item_name"));
        payParams.add("quantity", params.get("quantity"));
        payParams.add("total_amount", params.get("total_amount"));
        payParams.add("tax_free_amount", params.get("tax_free_amount"));
        payParams.add("approval_url", "http://localhost:8080/pay/success"); // 결제승인시 넘어갈 url
        payParams.add("cancel_url", "http://localhost:8080/pay/cancel"); // 결제취소시 넘어갈 url
        payParams.add("fail_url", "http://localhost:8080/pay/fail"); // 결제 실패시 넘어갈 url

        //카카오페이 결제준비 api 요청
        HttpEntity<Map> request = new HttpEntity<Map>(payParams, headers);

        RestTemplate template = new RestTemplate();
        String url = "https://kapi.kakao.com/v1/payment/ready";

        //요청결과
        KakaoPayReadyVO res = template.postForObject(url, request, KakaoPayReadyVO.class);
        
        /*
        * 요청결과에서 응답받은 tid 값을 데이터베이스에 저장하는 로직 추가
        * 주문번호랑-tid랑 연결하여 결제이력테이블로 관리?
        */
        return res;
    }

카카오페이 버튼 시 카카오결제로 이동

 

여기까지 완료하면, 결제 준비 단계는 끝난다.

사용자가 확인 버튼 클릭 시 결제승인 api 를 호출하여 최종적으로 결제 승인을 하여야 한다.

 

2. 결제승인

VO생성

-> 나중에 db에 저장할 항목들 전부 담기 (지금은 일부 생략)

@Getter
@Setter
@ToString
public class KakaoPayApproveVO {
    private String aid;
    private String tid;
    private String partner_order_id;
    private String partner_user_id;
    private String payment_method_type;
    ... 등등
}

컨트롤러

=> 결제 요청 후 받은 데이터를 db에 저장하는 로직은 추후 추가한다.

@GetMapping("/pay/success")
public String Success(@RequestParam("pg_token") String pgToken) {
    KakaoPayApproveVO res = payService.kakaoPayApprove(pgToken);

    /*
     * 요청 결과에 대해서 데이터 베이스에 저장 또는 업데이트 할 로직 추가
     * */

    return "/pay/success";
}

서비스

 

public KakaoPayApproveVO kakaoPayApprove(String pgToken){
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "KakaoAK {adminkey}"); //발급받은 adminkey
        headers.set("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        MultiValueMap<String, Object> payParams = new LinkedMultiValueMap<String, Object>();

        /*
         * 결제번호는 결제준비 api와 일치 하여야 한다.
         * tid 불러오는 로직 추가
         * */

        String tid = "";
        payParams.add("cid", "TC0ONETIME");
        payParams.add("tid", tid         );
        payParams.add("partner_order_id", "KAO20230318001");
        payParams.add("partner_user_id", "kakaopayTest");
        payParams.add("pg_token", pgToken);

        //카카오페이 결제요청 api 요청
        HttpEntity<Map> request = new HttpEntity<Map>(payParams, headers);

        RestTemplate template = new RestTemplate();
        String url = "https://kapi.kakao.com/v1/payment/approve";

        //요청결과
        KakaoPayApproveVO res = template.postForObject(url, request, KakaoPayApproveVO.class);

        return res;
    }

 

결제완료

 

일단 tid를 하드코딩해서 결제 완료되는 부분까지 확인했다.

db 저장 로직이라던지, 주문번호 불러오는 로직이라던지 장바구니와 연계한 로직을 추가하면 될 것 같다.

 

 

 

https://developers.kakao.com/docs/latest/ko/kakaopay/common

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

728x90
반응형
LIST