팀프로젝트가 끝나고 되돌아보는 시간 (4) 간편결제 API를 이용하여 결제/환불 기능 구현
iamport api를 이용하여 결제시스템을 구현했습니다.
문서도 예제도 크게 변형할 필요가 없어 프로젝트 사용하면서 가장 활용하기 쉬웠던 api인 것 같습니다.
아임포트 api 사용법
1. 먼저 아임포트 사이트에 가입을 합니다. www.iamport.kr/
2. 회원가입후 시스템설정으로 이동합니다.
3. PG설정(일반결제 및 정기결제) 를 클릭합니다.
4. PG사 카카오페이 선택 후 테스트모드 ON 합니다.
5.전체저장을 누르면 가맹점식별코드(CID)가 발급됩니다.
6. 아임포트 라이브러리를 추가합니다.
import (iamport api) document🚀
<!-- 제이쿼리 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous" type="text/javascript"></script>
<!-- 아임포트 -->
<script src ="https://cdn.iamport.kr/js/iamport.payment-1.1.5.js" type="text/javascript"></script>
cominfo_pay.jsp (구매/환불)
<h5>이용권</h5>
<table class = pay border="1">
<tr><td rowspan="2" class="pay_detail">이용권</td><td>월 기본 제공 </td><td><%=bvo.getFree_coupon() %>/5</td></tr>
<tr><td>남은 구매 이용권 횟수</td><td id = "pay_coupon"><%=bvo.getPay_coupon() %> </td></tr>
</table>
<div class ="btns">
<input type="button" id="check1" value="구매">
<input type="button" id="check2" value="환불">
</div>
button(check1, check2) 클릭 이벤트로 아임포트 api를 이용합니다.
<!-- pay js -->
<script type="text/javascript">
$(document).ready(function(){
var pay = <%=bvo.getPay_coupon() %>;
console.log(pay);
var IMP = window.IMP;
var code = "imp********"; //가맹점 식별코드
IMP.init(code);
$("#check1").click(function(e){
//결제요청
IMP.request_pay({
//name과 amout만있어도 결제 진행가능
//pg : 'kakao', //pg사 선택 (kakao, kakaopay 둘다 가능)
pay_method: 'card',
merchant_uid : 'merchant_' + new Date().getTime(),
name : '결제테스트', // 상품명
amount : 1,
buyer_email : '<%=email%>',
buyer_name : '<%=mvo.getName()%>',
buyer_tel : '<%= mvo.getPhone()%>', //필수항목
//결제완료후 이동할 페이지 kko나 kkopay는 생략 가능
//m_redirect_url : 'https://localhost:8080/payments/complete'
}, function(rsp){
if(rsp.success){//결제 성공시
var msg = '결제가 완료되었습니다';
var result = {
"imp_uid" : rsp.imp_uid,
"merchant_uid" : rsp.merchant_uid,
"biz_email" : '<%=email%>',
"pay_date" : new Date().getTime(),
"amount" : rsp.paid_amount,
"card_no" : rsp.apply_num,
"refund" : 'payed'
}
console.log("결제성공 " + msg);
$.ajax({
url : '/samsam/insertPayCoupon.do',
type :'POST',
data : JSON.stringify(result,
['imp_uid', 'merchant_uid', 'biz_email',
'pay_date', 'amount', 'card_no', 'refund']),
contentType:'application/json;charset=utf-8',
dataType: 'json', //서버에서 보내줄 데이터 타입
success: function(res){
if(res == 1){
console.log("추가성공");
pay += 5;
$('#pay_coupon').html(pay);
}else{
console.log("Insert Fail!!!");
}
},
error:function(){
console.log("Insert ajax 통신 실패!!!");
}
}) //ajax
}
else{//결제 실패시
var msg = '결제에 실패했습니다';
msg += '에러 : ' + rsp.error_msg
}
console.log(msg);
});//pay
}); //check1 클릭 이벤트
$("#check2").click(function(e){
console.log("남은이용권"+$('#pay_coupon').text());
if($('#pay_coupon').text() >= 5){
$.ajax({
url: "/samsam/coupon_cancel.do",
type:"post",
//datatype:"json",
contentType : 'application/x-www-form-urlencoded; charset = utf-8',
data : {
"biz_email" : '<%=email%>' // 주문번호
//"cancle_request_amount" : 2000, //환불금액
//"reason": "테스트 결제 환불", //환불사유
//"refund_holder": "홍길동", //[가상계좌 환불시 필수입력] 환불 가상계좌 예금주
//"refund_bank":"88", //[가상계좌 환불시 필수입력] 환불 가상계좌 은행코드(ex Kg이니시스의 경우 신한은행 88)
//"refund_account": "56211105948400" // [가상계좌 환불시 필수입력] 환불 가상계좌 번호
}
}).done(function(result){ //환불 성공
pay -= 5;
$('#pay_coupon').html(pay);
console.log("환불 성공 : "+ result);
}).fail(function(error){
console.log("환불 실패 : "+ error);
});//ajax
} else{
console.log("환불 실패 : 남은 결제권 환불 불가");
}
}); //check2 클릭
}); //doc.ready
ImportController (구매/환불)
@RequestMapping(value = "/insertPayCoupon.do")
@ResponseBody
public int pay(@RequestBody Payed_listVO pvo) {
System.out.println("pvo.getMerchant_uid : " + pvo.getMerchant_uid());
int res = paySV.insert_pay(pvo);
if(res == 1) {
Biz_memberVO bvo = memberSV.selectBizMember(pvo.getBiz_email());
bvo.setPay_coupon(bvo.getPay_coupon()+5);
System.out.println("paycoupon: " + bvo.getPay_coupon());
res = paySV.updateBiz_pay(bvo);
if(res == 1)
System.out.println("biz_member pay coupon insert complete");
}
return res;
}
@RequestMapping(value = "/coupon_cancel.do")
@ResponseBody
public String cancel(@RequestParam(value= "biz_email") String biz_email) {
System.out.println("biz_email = " + biz_email);
Payed_listVO pvo = paySV.recentlyPay(biz_email);
PaymentCheck obj = new PaymentCheck();
String token = obj.getImportToken();
System.out.println("merchant_uid :" + pvo.getMerchant_uid());
int res = obj.cancelPayment(token, pvo.getMerchant_uid());
if(res == 1) {
Biz_memberVO bvo = memberSV.selectBizMember(pvo.getBiz_email());
bvo.setPay_coupon(bvo.getPay_coupon()-5);
System.out.println("paycoupon: " + bvo.getPay_coupon());
res = paySV.updateBiz_refund(bvo);
if(res ==1) {
res = paySV.refund_pay(pvo.getMerchant_uid());
if(res ==1) { return "Success";}
}else { return "biz_refund Failure"; }
return "thanks";
}
else
return "anyway Failure";
}
문서 내용에 따르면 init은 가장 먼저하는 것이 좋다하여 $(document).ready(function(){} 의 맨 윗부분에 기재했습니다.
결제 성공시 결제리스트(테이블)에 데이터를 추가하기위해 key-value 형태의 데이터(변수명 result)를 만들고 JSON.stringify로 JSON 형식으로 변환하여 ajax로 전달합니다.
데이터가 적용완료되면(결제리스트 추가, 사업자 테이블의 이용권 갯수 업데이트) 다시 데이터를 조회하지 않고 현재페이지의 데이터를 변경합니다. (pay += 5; $('#pay_coupon').html(pay); )
환불은 이용권 구매시 이용권이 +5 되기 때문에 구매한 이용권의 남은 갯수가 5개 이상이어야만 가능하도록 구현하였습니다.
iamport 환불시 merchant_uid가 필요합니다, 구매를 한번 이상 했을수도 있어 구매시 생성된 merchant_uid가 아닌 환불하지 않은
최신 merchant_uid를 조회하여 환불 진행시 사용했습니다.
Mapper (Mybatis)
<!-- 이용권 결제내역 추가 -->
<insert id ="insert_pay" parameterType="Payed_listVO">
insert into payed_list
values(#{imp_uid},#{merchant_uid}, #{biz_email}, #{pay_date}, #{amount}, #{card_no}, #{refund})
</insert>
<!-- 이용권 결제내역 조회 -->
<select id="recentlyPay" parameterType="String" resultType="Payed_listVO">
select imp_uid, merchant_uid, biz_email, pay_date, amount, card_no, refund from
(select rownum, imp_uid, merchant_uid, biz_email, pay_date, amount, card_no, refund from
(select * from payed_list where biz_email = #{biz_email})where refund ='payed' order by pay_date)
where rownum = 1
</select>
<!-- 이용권 결제 사업자에 반영 -->
<update id="updateBiz_pay" parameterType="Biz_MemberVO">
update biz_member set pay_coupon = #{pay_coupon} where biz_email = #{biz_email}
</update>
<!-- 이용권 환불 사업자에 반영 -->
<update id="updateBiz_refund" parameterType="Biz_MemberVO">
update biz_member set pay_coupon = #{pay_coupon} where biz_email = #{biz_email}
</update>
<!-- 이용권 결제내역 환불 -->
<update id="refund_pay" parameterType="String">
update payed_list set refund = 'refund' where merchant_uid = #{merchant_uid}
</update>
'Devme > Project' 카테고리의 다른 글
JAVA / SPRING 프로젝트 삼삼하개(5) CHART.JS를 통해 데이터정보 시각화 (2) | 2021.03.02 |
---|---|
JAVA / SPRING 프로젝트 삼삼하개(3) 마이페이지(개인/업체) 내 작성글, 작성댓글 조회 구현 (0) | 2021.03.02 |
JAVA / SPRING 프로젝트 삼삼하개(2) LOCAL DATA API를 이용하여 판매허가번호 인증 구현 (0) | 2021.02.27 |
JAVA / SPRING 프로젝트 삼삼하개(1) 이메일 인증으로 비밀번호찾기 (2) | 2021.02.26 |