본문 바로가기
IT/프로젝트

KakaoPay

by 봉즙 2019. 9. 30.

API admin키를 받아 온다음 웹 플랫폼에 자신이 사용하는 플랫폼을 등록해주어야 한다.

 

KakaoPay.java

package com.btl.findjob.utils;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.UUID;

import com.btl.findjob.model.KakaoPayApprovalVO;
import com.btl.findjob.model.KakaoPayReadyVO;
import lombok.extern.log4j.Log4j;
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;

@Service
@Log4j
public class KakaoPay {

    private static final String HOST = "https://kapi.kakao.com";

    private static final String QUANTITY = "1";//주문수량 고정
    private static final String TOTAL_AMOUNT = "1000000"; //가격 고정
    private static final String TAX_FREE_AMOUNT = "10000";//제세
    private static final String APPROVAL_URL ="http://localhost:8282/findjob/kakaoPaySuccess";//성공 URL
    private static final String CANCEL_URL ="http://localhost:8282/findjob/kakaoPayCancel";//취소 URL
    private static final String FAIL_URL ="http://localhost:8282/findjob/kakaoPaySuccessFail";//실패 URL
    private static final String ITEM_NAME ="프리미엄회원권";//성공 URL
    private static final String partner_order_id = UUID.randomUUID().toString();//주문 고유번호 생성 위해서 or random?

    private KakaoPayReadyVO kakaoPayReadyVO;
    RestTemplate restTemplate = new RestTemplate();
    
    public static HttpHeaders headers() {
    	// 서버로 요청할 Header
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "KakaoAK " + "키");
        headers.add("Accept", "application/x-www-form-urlencoded;charset=utf-8");
        headers.add("Content-Type", MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8");

    	return headers; 
    }
    
    public String kakaoPayReady(String user_id) {
    	
    	// 서버로 요청할 Body
        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("cid", "TC0ONETIME");//사업장 고유번호
        params.add("partner_order_id", partner_order_id);//주문번호 uuid 사용
        params.add("partner_user_id",  user_id);//
        params.add("item_name", ITEM_NAME);
        params.add("quantity", QUANTITY);
        params.add("total_amount", TOTAL_AMOUNT);
        params.add("tax_free_amount", TAX_FREE_AMOUNT);
        params.add("approval_url",APPROVAL_URL);
        params.add("cancel_url", CANCEL_URL);
        params.add("fail_url", FAIL_URL);

        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 | URISyntaxException e) {
            e.printStackTrace();
        }

        return "pay";
        //실패시

    }

    public KakaoPayApprovalVO kakaoPayInfo(String pg_token, String user_id) {

    	// 서버로 요청할 Header
    	
        // 서버로 요청할 Body
        MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
        params.add("cid", "TC0ONETIME");
        params.add("tid", kakaoPayReadyVO.getTid());
        params.add("partner_order_id", partner_order_id);
        params.add("partner_user_id", user_id);
        params.add("pg_token", pg_token);
        params.add("total_amount",TOTAL_AMOUNT);//금액

        HttpEntity<MultiValueMap<String, String>> body = new HttpEntity<MultiValueMap<String, String>>(params, headers());

        try {
            KakaoPayApprovalVO kakaoPayApprovalVO = restTemplate.postForObject(new URI(HOST + "/v1/payment/approve"), body, KakaoPayApprovalVO.class);
            log.info("" + kakaoPayApprovalVO);

            return kakaoPayApprovalVO;

        } catch (RestClientException | URISyntaxException e) {
            e.printStackTrace();
        }

        return null;
    }

}

 

KakaoPayController

package com.btl.findjob.controller;

import com.btl.findjob.service.KakaoPayService;
import com.btl.findjob.utils.KakaoPay;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
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.RequestParam;

import org.springframework.web.bind.annotation.SessionAttributes;

import javax.servlet.http.HttpSession;

@Log4j
@Controller
@SessionAttributes("user_id")
@AllArgsConstructor
public class KakaoPayController {

    private KakaoPay kakaopay;

    private KakaoPayService kakaoPayService;

    @GetMapping("kakaoPay")
    public void kakaoPayGet() {
    }

    @PostMapping("kakaoPay")
    public String kakaoPay(HttpSession httpSession) {
        String user_id = (String) httpSession.getAttribute("user_id");

        log.info(user_id);
        log.info(kakaopay.kakaoPayReady(user_id));
        return "redirect:" + kakaopay.kakaoPayReady(user_id);

    }

    @GetMapping("kakaoPaySuccess")
    public void kakaoPaySuccess(@RequestParam(value="pg_token") String pg_token, Model model, HttpSession httpSession) {
        String user_id = (String) httpSession.getAttribute("user_id");
        log.info("kakaoPaySuccess get............................................");
        log.info("kakaoPaySuccess pg_token : " + pg_token);

        model.addAttribute("info",kakaopay.kakaoPayInfo(pg_token, user_id));

        log.info(model);

    }

}

 

AmountVO

package com.btl.findjob.model;

import lombok.Data;

@Data
public class AmountVO {
 
    private Integer total, tax_free, vat, point, discount;//전체 결제 금액, 비과세 금액, 부가세금액, 사용한 포인트금액, 할인금액
}
 

 

CardVO

package com.btl.findjob.model;

import lombok.Data;

@Data
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; //카드bin, 카드타입, 할부 개월수, 카드사 승인번호, 카드사 가맹점번호
    private String interest_free_install, card_item_code;//무이자 할부 여부, 카드 상품코드
    
 
}

 

KakaoPayApprovalVO

package com.btl.findjob.model;

import java.util.Date;

import lombok.Data;

@Data
public class KakaoPayApprovalVO {
    
    //response
    private String aid, tid, cid, sid;//cid 가맹점 필수 코드, tid 결제 고유번호 unique값
    private String partner_order_id, partner_user_id, payment_method_type;//가맹점주문번호, 가맨정회원id, 페이 방
    private AmountVO amount;
    private CardVO card_info;//카드정보
    private String item_name, item_code, payload;//상품이름, 상품코드, 해당 request와 저장해서 매핑하고 싶은 값?
    private Integer quantity, tax_free_amount, vat_amount;//수랑, 비과세금액, 부과세금액   로 수정, vat_amount가 null 받아와서 total_amount 수정
    private Date created_at, approved_at;//결제 준비요청시간, 결제 승인시각
   
    
}
 

 

KakaoPayReadyVO

package com.btl.findjob.model;

import java.util.Date;

import lombok.Data;

@Data
public class KakaoPayReadyVO {

    //response
    private String tid, next_redirect_pc_url;//결제 고유번호(20자), 요청한 클라이언트가 pc 웹일 경우 redirect. 카카오톡으로 TMS를 보내기 위한 사용자입력화면이으로 redirect
    private Date created_at;//결제 준비 요청시간

}
 

 

KakoPay.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>

<%@ include file="includes/header.jsp"%>
<div class="container">
    <div class="card-body text-center mt-5">
<h1> 멤버쉽 결제 </h1>


<form method="post" action="kakaoPay" target="popup_window">
    <button class="btn btn-light " id="kakaoBtnSubmit"><img src="${path}/resources/img/kakopay_small.png" alt=""></button>

</form>
    </div>
</div>

<%@ include file="includes/footer.jsp"%>

<script>
    $("#kakaoBtnSubmit").on("click", function(){
        window.open("", "popup_window", "width=500, height=700, scrollbars=no");
    });
</script>

 

kakaoPaySuccess.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>

<%@ include file="includes/header.jsp" %>

<div class="container">
    <div class="card-body text-center mt-5">
        <h2>결제가 완료되었습니다.</h2>
        <table>

            <tr>
                <td>
                    주문번호
                </td>
                <td>
                    ${info.partner_order_id}
                </td>
            </tr>
            <tr>
                <td>
                    결제일시
                </td>
                <td>
                    ${info.approved_at}
                </td>
            </tr>
            <tr>
                <td>
                    상품명
                </td>
                <td>
                    ${info.item_name}
                </td>
            </tr>
            <tr>
                <td>
                    결제금액
                </td>
                <td>
                    ${info.total}
                </td>
            </tr>
            <tr>
                <td>
                    결제방법
                </td>
                <td>
                    ${info.payment_method_type}
                </td>
            </tr>
        </table>
        <button class="btn btn-outline-info mt-1" onclick="opener.parent.location.reload(); self.close() ">확인</button>
    </div>
</div>

<%@ include file="includes/footer.jsp" %>

 

KakaoPayCancel.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

<%@ include file="includes/header.jsp" %>
<div class="container">
    <div class="card-body text-center mt-5">
        <h1>결제가 취소되었습니다.</h1>
        <button class="btn btn-outline-primary" onclick="location.href='${path}/'">홈으로</button>
    </div>
</div>
<%@ include file="includes/footer.jsp" %>

 

'IT > 프로젝트' 카테고리의 다른 글

모달 외부 JSP에서 불러오기  (0) 2020.03.19
pushstate (ajax 뒤로가기)  (0) 2020.02.06
국제화 JSP 이용  (0) 2019.12.02
공공API 데이터 파싱 후 db  (0) 2019.09.04

댓글