[프로젝트 개선] - 웹사이트 제작 16. (Spring/Java) 결제시스템 구현하기(+ 아임포트 API이용)

JINI·2023년 5월 9일
0
post-thumbnail

프로젝트 진행했을 때 구현하고 싶었던 기능 중 하나가 결제 부분이었다. 원래는 예약하기 버튼을 클릭하면 선택한 값들이 DB에 저장되는 간단한 기능이었는데 이번에는 Ajax를 이용해 결제 후 예약이 가능하도록 구현했다.
결제 시스템을 구현하기 위해 아임포트 API를 이용했다.
(현재는 아임포트에서 포트원으로 변경된듯하다.)


🚩변경 전 ➡️ 예약하기
🚩변경 후 ➡️ 결제 완료시 예약가능


💳 결제 준비


회원가입 / PG정보 설정

api를 이용하기 위해 회원가입을 해서 계정을 생성한다.

아임포트(포트원) 👉 https://portone.io/korea/ko

결제연동 -> 테스트 연동 관리 탭에서 연동하고자 하는 PG사를 선택한 후 정보를 저장한다.
여기서 중요한 건 실 연동이 아닌 테스트 연동을 해야한다❗

설정하면 식별코드, REST API KEY, Secret Key를 확인할 수 있다.

내 경우는 KG이니시스를 이용해 결제 시스템을 구현하지만
카카오페이, 토스, 네이버페이 등 다양하게 있으니 필요에 맞게 선택하면 된다.



💳 결제 연동


1. 라이브러리 추가

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript"	src="https://cdn.iamport.kr/js/iamport.payment-1.2.0.js"></script>


2.결제 구현 코드

전체 코드가 아닌 중요한 코드들만 정리했다.

💵시작

var IMP = window.IMP;
IMP.init("imp");   /* imp~ : 가맹점 식별코드*/

imp로 시작하는 가맹점 식별코드를 이용하여 IMP 객체를 초기화 해서 결제창 연동을 준비한다.


💵 결제 요청

📕 jQuery

$('#money-btn').click(function() {
	IMP.request_pay({
		pg: 'html5_inicis',
		pay_method: 'card',
		merchant_uid: 'merchant_' + new Date().getTime(),

		name: '예약 지점명 : ' + bookCity + '점',
		amount: bookMoney,
		buyer_email: "",  /*필수 항목이라 "" 로 남겨둠*/
		buyer_name: bookName,
	}, function(rsp) {
		console.log(rsp);
		
		 //결제 성공 시
		if (rsp.success) {
			var msg = '결제가 완료되었습니다.';
			console.log("결제성공 ");

			$.ajax({
				type: "GET",
				url: 'bookingPay',
				data: {
					amount: bookMoney,
					imp_uid: rsp.imp_uid,
					merchant_uid: rsp.merchant_uid
				}
			});
		} else {
			var msg = '결제에 실패하였습니다.';
			msg += '에러내용 : ' + rsp.error_msg;
		}
		alert(msg);
	});
});

결제하기 버튼을 클릭하면 해당 코드가 실행된다.
결제창 호출시 필요한 파라미터를 request_pay 함수 첫번째 파라미터 인자로 설정하고 결제 처리를 서버단에서도 알 수 있게 ajax를 이용하여 결제자의 ID와 상품ID, 결제 금액을 담아 Controller에 전송했다.

결제 성공/실패시 msg 변수를 생성하여 사용자에게 내용을 출력해 주었다.



📕input 값 name으로 가져오기

var bookMoney = $('input[name="price"]').val();
	bookMoney = parseInt(bookMoney);   
	console.log(bookMoney);

현재 프로젝트에 구현한 총 금액 부분은 사용자 선택에 따라 값이 달라지기 때문에 결제할 때 계산된 금액이 그대로 뜨기를 원했다.

그래서 amount에 들어갈 bookMoney변수를 생성하고 input창에 들어온 총 금액의 name을 가져오기로 했다.


🚧여기서 발생한 오류❗

bookMoney = parseInt(bookMoney);
테스트 결제할 때 계속 0원이 떴고 여기서 시간을 잡아먹었다...
값을 제대로 불러오지 못하는 이유는 너무~~~ 간단했다.
dto를 확인하니 가격을 int가 아니라 String 타입으로 저장했던 터라 오류가 터졌던 것!!!

🛠️해결 방법
String 타입을 int형으로 형변환하기 ➡️ parseInt

원하는 값들을 선택하고 결제하기 버튼을 클릭하면

선택한 지점과 가격이 제대로 불러와진다.

console로 선택한 값들이 맞는지 확인했다.



📕 Controller

서버단으로 사용자 정보가 넘어와서 제대로 결제가 되었는지 확인하는 코드이다.

@GetMapping("bookingPay")
	@ResponseBody
	public void bookPay(int amount,String imp_uid, String merchant_uid) throws Exception{

		System.out.println("결제 성공");
		System.out.println("결제 금액 : " + amount);
		System.out.println("imp_uid : " + imp_uid);
		System.out.println("merchant_uid : " + merchant_uid);
	}

ajax에 설정한 url로 이동해 @ResponseBody로 데이터를 받는다.
여기서는 금액, 회원 정보 ID, 상품ID 값이 전달된다.


💵 결제 테스트

💵결제 성공시

테스트라도 실제 입력한 카드에서 결제 금액이 빠져나간다.
물론 관리자 모드에서 바로 취소 가능하다.
그리고 KG이니시스는 결제 최소금액이 100원이라 이 금액으로 테스트를 진행했다.

컨트롤러에 잘 넘어온다.

아무것도 선택하지 않고 결제하기 클릭시 에러 내용과 함께 alert창이 뜨면서 페이지가 넘어가지 않는다.


💵결제 취소시


👩‍💻관리자 모드

테스트 결제 후 취소할 때 관리자 모드로 들어가서 확인할 수 있다.

결제승인내역에서 검색하기를 클릭하면 테스트했던 결제 내역이 뜬다.

테스트를 위해 카드 정보를 입력하고 100원을 결제했고
실제 계좌에서 해당 금액이 제대로 빠져나간 것을 확인했다.

이렇게 상태를 확인할 수 있고 취소 가능하다.
취소된 금액은 계좌로 다시 들어온다.🙂


profile
꾸준히 성장하는 개발자

0개의 댓글