본문 바로가기
기타

포트원(구 아임포트)를 활용해서 결제 기능 구현

by bkuk 2023. 2. 18.

아래 사진은 포트원 라이브러리를 적용해서 결제완료까지의 흐름입니다.

 

사용자는 회원권을 선택합니다.

 

 

결제를 재 확인합니다.

 

 

결제하기 버튼을 누르면 위와 같이 결제창이 호출됩니다.

상품명, 상품금액을 확인하고 결제를 진행합니다.

결제금액은 실제로 결제가 되기때문에 100으로 나눈 후 결제창을 요청했습니다. 또한, 실제로 결제가 이루어져도 자정에 일괄 취소 되어서, 반환해줍니다.

 

카카오페이로 결제 후 결제요청을 하게되면,

 

위와 같은 정상처리를 의미하는 페이지로 이동하고, 

 

 

 

마이페이지에서 회원권을 확인할 수 있습니다.


JSP로 구현했습니다.

 

1) Controller를 통해서 멤버쉽 정보( seq 또는 idx, 가격, 이름 )을 전달받습니다.

2) 향상된 for문과 StringBuilder를 통해서 문자열을 더합니다.

int selectLopNum = 0;
for( MemberShipTO msto : msList ) {
    selectLopNum++;
    sbMembershipInfo.append( "<option value='" + msto.getMembership_seq() +"'>" + msto.getMembership_period() + "개월권" +"</option>" );
}

 

위에서 문자열을 더했던 객체를 toString()을 통해 문자열로 출력합니다..

<div class="mb-2 pb-3">
	<p class="fw-bold">옵션 선택</p>
    <select id="memberShip" name= "memberShip" onChange="change(this.options[this.selectedIndex].text)" class="form-select" aria-label="Default select example">
        <option>이용권을 선택하세요.</option>
        <%= sbMembershipInfo.toString() %>
    </select>
</div>

 

 

이를 브라우저를 통해서 보면, option의 value 속성에는 회원권의 고유 식별번호가 포함되어 있습니다.

(현재 1번째 글이라.. 1부터 시작합니다..)

 

회원권의 seq와, 로그인 시 부여받은 세션( 아이디, 닉네임, 권한 등..) 을 통해서 결제창을 호출할 수 있습니다.

 

 

이제, 스크립트 코트를 설명드리겠습니다.

마지막으로 아래 코드는 결제하기 버튼에 대한 속성을 설명하기 위한 사진입니다.

 

우선, jQuery를 통해서, 아래와 같은 이벤트를 생성합니다.

$('#payBtn').on( 'click', function(){
    if( document.getElementById("memberShip").selectedIndex == 0 ) {
        alert("회원권을 선택해주세요.");
        return false;
        }
    $('#myModal').modal("show");
});

 

여기서 #myModal이란, 모달창을 아래와 같이 따로 분리할 수 있습니다.

따라서, 초기에는 안보이디가. 버튼을 클릭하면 볼 수 있게 위와 같이 코드를 작성할 수 있습니다.

$('#myModal').modal("show");

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
	<!-- The Modal -->
	<div class="modal fade" id="myModal">
	  <div class="modal-dialog modal-dialog-centered">
	    <div class="modal-content">
	
	      <!-- Modal Header -->
	      <div class="modal-header">
	        <h4 class="modal-title">결제 확인</h4>
	        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
	      </div>
	
	      <!-- Modal body -->
	      <div id="confirmMebership" class="modal-body">
	      </div>
	
	      <!-- Modal footer -->
	      <div class="modal-footer">
	      	<button id="paymentOk" type="button" class=" btn btn-primary"  data-bs-dismiss="modal">결제하기</button>
	        <button id="paymentcancle" type="button" class="btn btn-danger" data-bs-dismiss="modal">취소하기</button>
	      </div>
	
	    </div>
	  </div>
	</div>

 

결제하기 버튼을 클릭하면, 다른 함수를 호출하고, 취소하기 버튼을 클릭하면 결제취소 경고창이 표시됩니다.

$("#paymentOk").on( 'click', function(){
    requestPayInfo();
  });

$("#paymentcancle").on( 'click', function(){
    alert("결제 취소를 눌렀습니다.");
  });

 

 

결제호출창에 대한 코드를 설명하기 전, 라이브러리를 추가해야합니다.

 

저는 아래와 같이 추가했습니다.

<script src="../resources/asset/script/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="https://cdn.iamport.kr/js/iamport.payment-1.2.0.js"></script>

 

 

다음으로는 결제창 연동을 위해 포트원에서 제공하는 객체를 초기화 해야합니다.

 

저는 추가로 아래와 같은 전역 변수를 선언했습니다.

 const IMP = window.IMP;
 IMP.init("imp00000000a");
 let msg;
 let merchant_uid
 let name
 let amount
 let buyer_seq
 let buyer_email
 let buyer_name
 let buyer_tel
 let buyer_addr
 let buyer_postcode
 let membership_seq

 

 

이제는 결제창을 호출하기 위해서 정보(상품명, 가격, 회원 이메일, 주소 등..)을 서버에서 가져와야 합니다.

 

아래 코드의 주석을 잘 확인해보면 알 수 있습니다.

서버와의 통신이 정상적으로 이루어졌다면, json 형태로 받은 value를 전역변수에 할당하고, 

requestPay() 함수를 호출 합니다.

function requestPayInfo() {

	// 로그인 시 부여받는 회원의 권한 세션, 업체회원은 구매 불가
    let type = '<%=request.getParameter("type")%>';
    if(type=="null"){ 
         alert("로그인 해주세요.");
         return false;
      } else if ( type == "C"){
          alert("기업 회원은 불가능 합니다. 일반 회원만 가능합니다.");
          return false;
      }
      
    // 세션 확인 후 ajax 요청
    // 1) 회원 이름으로 seq, email, name 등을 json형태로 전달받음.
    // 2) 회원권의 seq를 통해서 이름, 가격 등을 json형태로 전달받음.
    $.ajax({
        url: '/pay/information',
        type: 'get',
        data: {
            buyer_nickname : '<%=request.getParameter("nickname")%>',
            membership_seq : $("#memberShip option:checked").val()
        },
        dataType: 'json',
        success: function( jsonData ) {
            if( jsonData.flag == 0 ) {
            
                merchant_uid = jsonData.merchant_uid;
                name = jsonData.name;
                amount = jsonData.amount;
                buyer_seq = jsonData.buyer_seq;
                buyer_email = jsonData.buyer_email;
                buyer_name = jsonData.buyer_name;
                buyer_tel = jsonData.buyer_tel;
                buyer_addr = jsonData.buyer_addr;
                buyer_postcode = jsonData.buyer_postcode;

                requestPay();
                membership_seq = $("#memberShip option:checked").val();
            } else { alert( '서버 에러' ); }
        },
        error: function(err) { alert( '[에러] ' + err.status); } }); }

 

 

 

이제는 정말 결제 요청을 합니다.

pg: "kcp.{상점ID}" 는 포트원에서 설정 가능합니다.

 

function requestPay() {

	// 전역변수의 값을 가져옵니다.
    IMP.request_pay({
      pg: "kcp.T0000",
      pay_method: "card",
      merchant_uid: merchant_uid,
      name: name,
      amount: amount/100, 
      buyer_email: buyer_email,
      buyer_name: buyer_name,
      buyer_tel: buyer_tel,
      buyer_addr: buyer_addr,
      buyer_postcode: buyer_postcode
    }, function (rsp) { // callback
      if (rsp.success) {
        // 결제 성공 시 로직
        // pay 라는 url을 통해 pay 테이블에 insert하는 메서드가 실행됩니다.
          $.ajax({
              url: "/pay",
              type: "post",
              data: {
                  imp_uid: rsp.imp_uid,
                  merchant_uid: rsp.merchant_uid,
                  pay_method: "card",
                  membership_seq : membership_seq,
                  buyer_seq : buyer_seq
                  },
                  dataType: 'json',
                  success: function( result ){

                  if(result.flag == 0){
                     location.href = "/pay/success";

                  }else{
                     location.href = "/pay/fail";

                  }
                },
                error:function(){
                  location.href = "/pay/fail";
                }
            })
        } else{//결제 실패시
            location.href = "/pay/fail";
        }
    });
};