본문으로 바로가기

여기를 참고하면 편합니다.

github.com/iamport/iamport-manual/blob/master/%EC%9D%B8%EC%A6%9D%EA%B2%B0%EC%A0%9C/README.md

 

iamport/iamport-manual

아임포트(iamport) 결제연동을 위한 매뉴얼입니다. Contribute to iamport/iamport-manual development by creating an account on GitHub.

github.com

 

실제 작성한 코드는 개인사업자 등록 이후 다루도록하겠습니다.

 

 

 

아임포트 관련 문서와 특징

 

공식 홈페이지 : www.iamport.kr/

github : github.com/iamport

iamport manual : github.com/iamport/iamport-manual

iamport-react-exmaple(IMP.request_pay 메서드) : github.com/iamport/iamport-react-example

iamporter (아임포트에서 제공하는 REST API를 node에서 쉽게 활용하기 위함) : github.com/iamport/iamport-rest-client-nodejs 그러나 저는 그냥 문서보고 알아서 날리는 게 더 나은 것 같음.

api 문서(서버 검증을 위한 import API) : api.iamport.kr/

docs(아직 미완성이란다) : docs.iamport.kr/

 

  • 결제뿐만 아니라 계좌인증 api도 제공. 계좌 인증하여 실명 인증 대신 사용 가능. (계좌 인증 사용법 및 후기)
  • SMS 고객 인증 서비스도 구현되어 있음 (manual)
  • PG사에 따라 정기 결제(빌링, 쉽게 말해 구독비)도 가능함 (다른 분의 후기)

 

payment in action!

 

k-결제는 가맹점 서버와 PG 서버에서 카드 정보를 저장할 수 없으므로 아래와 같은 방법과 같이 결제가 진행된다고 하였다. 실제로 코드로 살펴보자. darrengwon.tistory.com/1231

 

 

 

실제로 결제가 진행되는 코드를 살펴보자

 

 

 

1️⃣ jquery와 iamport 삽입하기

 

아임포트는 jQuery를 기반으로 만들어져있기 때문에 jQuery를 임포트해야만 한다. 단, 사용하는 로직이 1.0부터 제공되는 것들로만 구성되었기 때문에 jQuery이기만 하면 된다.

 

React와 같은 SPA 환경에서는 root id를 가져 render하는 html의 head 부분에 넣어주자.

// jQuery
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" ></script>

// iamport 추가. 2021-02-01 기준으로 최신 버전은 1.1.8임.
<script src="https://cdn.iamport.kr/js/iamport.payment-1.1.8.js" type="text/javascript"></script>

// 굳이 낮은 버전을 사용하겠다면.. ㅇㅇ
<script src="https://cdn.iamport.kr/js/iamport.payment-1.1.5.js" type="text/javascript"></script>

 

jQuery를 아무 버전이나 넣어도 된다면 용량이 적은 녀석을 넣는 것이 좋아보인다.

거 보니 버전별 차이보다 압축이 되었는지의 여부가 훨씬 중요한 듯하다. 그냥 1.12.4 minified 된 거쓰자.

https://mathiasbynens.be/demo/jquery-size

 

2️⃣ IMP 객체 init 하기

 

IMP 객체를 가져와 생성합니다.

가맹점 식별코드를 넣어 init할 수 있는데 아임포트 가입 후 관리자 페이지 admin.iamport.kr/users/login 에서 확인 가능합니다.

const { IMP } = window;
IMP.init("imp00000000");

 

3️⃣ request_pay로 결제창 띄워 결제 시작하고, 결제 성공시 서버에 정보 보내기

 

request_pay 메서드를 통해 결제창을 띄워 결제 프로세스를 시작할 수 있습니다.

docs.iamport.kr/tech/imp 공식문서에 따르면 이 메서드는 param와 콜백을 받습니다.

form에서 pg, pay_method, merchant_uid, amount 등의 정보를 받을 수 있습니다. 이 내용이 param이 됩니다.

 

IMP.request_pay(param, callback)

 

param 객체에 무엇을 넣어야 하는지에 대해서는 공식 문서를 직접 참고합시다.

docs.iamport.kr/tech/imp#param

 

한편 param 정보를 이용해  결제 프로세스가 완료되면 콜백이 호출됩니다. 콜백 함수의 인자에 전달되는 response는 결제 성공 여부, 결제 승인 시간 등의 정보를 확인할 수 있습니다. 세부적인 속성 역시 공식문서 docs.iamport.kr/tech/imp#callback 에서 확인합시다.

 

여기서 받은 response 정보는 우리 서버에 보내서 아임포트 API를 이용해 거래가 위변조되지 않았는지 검증해야 합니다.

결론적으로 request_pay 메서드를 사용하는 방법을 쉽게 보여주자면 다음과 같습니다.

IMP.request_pay({
    pg : 'nice',
    pay_method : 'card', //card(신용카드), trans(실시간계좌이체), vbank(가상계좌), phone(휴대폰소액결제)
    merchant_uid : 'merchant_' + new Date().getTime(), //상점에서 관리하시는 고유 주문번호를 전달
    name : '주문명:결제테스트',
    amount : 14000,
    buyer_email : 'iamport@siot.do',
    buyer_name : '구매자이름',
    buyer_tel : '010-1234-5678',
    buyer_addr : '서울특별시 강남구 삼성동',
    buyer_postcode : '123-456'
}, function(rsp) {
    if ( rsp.success ) {
    	//[1] 서버단에서 결제정보 조회를 위해 jQuery ajax로 imp_uid 전달하기
    	jQuery.ajax({
    		url: "/payments/complete", //cross-domain error가 발생하지 않도록 주의해주세요
    		type: 'POST',
    		dataType: 'json',
    		data: {
	    		imp_uid : rsp.imp_uid
	    		//기타 필요한 데이터가 있으면 추가 전달
    		}
    	}).done(function(data) {
    		//[2] 서버에서 REST API로 결제정보확인 및 서비스루틴이 정상적인 경우
    		if ( everythings_fine ) {
    			var msg = '결제가 완료되었습니다.';
    			msg += '\n고유ID : ' + rsp.imp_uid;
    			msg += '\n상점 거래ID : ' + rsp.merchant_uid;
    			msg += '\결제 금액 : ' + rsp.paid_amount;
    			msg += '카드 승인번호 : ' + rsp.apply_num;
    			
    			alert(msg);
    		} else {
    			//[3] 아직 제대로 결제가 되지 않았습니다.
    			//[4] 결제된 금액이 요청한 금액과 달라 결제를 자동취소처리하였습니다.
    		}
    	});
    } else {
        var msg = '결제에 실패하였습니다.';
        msg += '에러내용 : ' + rsp.error_msg;
        
        alert(msg);
    }
});

 

🚨 모바일에서 브라우저를 켜서 결제하는 경우 주의점

 

대부분의 PG사(나이스, 이니페이 등등...)들은 모바일에서 브라우저로 결제를 시작하면 Modal 창을 띄우는 것이 아니라 다른 페이지로 이동시켜버립니다. 때문에, 결제를 완료해도 request_pay 메서드가 메모리해제되어 callback이 제대로 실행되지 않습니다.

 

m_redirect_url을 이용하여 리다이렉트된 경우에 대처하는 방법을 포함하여, 일반 결제가 이루어지는 전체 프로세스는 최하단부에 정리해두었습니다.

 

특정 PG사마다 모바일 검증에 세부적으로 다른 부분은 아래를 참고합시다.

 

4️⃣ 결제 정보를 받은 서버에서는 무엇을 검증해야 하는가?

 

우선, 왜 거래 내역을 검증해야 하는가?

 

결제 요청은 한국의 법적 문제상 브라우저에서 요청하게 되는데, 그렇다면 브라우저의 개발자 도구를 켜서 자바스크립트를 통해 결제 금액 등을 위변조할 수 있기 때문이다. 따라서 결제가 완료되었다면, 변조되지 않았는지 확인해야 한다.

 

그러면 무엇을 검증해야 하는가?

 

요에 따라 검증하기만 기본적으론,

결제되었어야 하는 제품의 금액과 결제된 금액이 같은지 비교하고,

실제 결제가 최종적으로 완료가 되었는지(status)를 검증합니다.

 

🎉 최종 정리

 

1. IMP.request_pay(param, callback) 호출로 결제창 호출

 

2. PG사 페이지로 이동(redirect)하면서 결제 프로세스 시작한다. 이 때 특정 PG사는 모바일 환경에서 redirect 시키므로 m_redirect_url을 지정해야 한다.

 

3-1. 결제 후 m_redirect_url에 지정된 주소로 페이지 이동. 이 때, m_redirect_url에 query string로 imp_uid  merchant_uid 가 추가된 주소로 이동됨.

https://www.myservice.com/payment/mobile/success로 지정하면

https://www.myservice.com/payment/mobile/success ?imp_uid=imp1234567890&merchant_uid=order12345 로 이동됨)

 

3-2. m_redirect_url을 지정할 필요 없는 경우에도 마찬가지로 imp_uid와 merchant_uid를 서버에 전달해야 합니다. 

 

4. imp_uid와 merchant_uid를 서버에서 받았다면, 서버는 import가 제공하는 api를 이용하여 거래를 검증한다. 예를 들면 api.iamport.kr/payments/{imp_uid}를 통해 아임포트 고유번호로 결제내역을 확인하는 것입니다.

아임포트에서 제공하는 api의 목록은 api.iamport.kr/ 에서 확인할 수 있습니다. 검증해야할 내용은 조회된 결제 정보가 status == 'paid' && amount == {결제되었어야 할 금액} 조건에 해당되는지 등을 체크하는 것입니다.

 

5. 거래가 위변조되지 않았음이 검증되었으므로 가맹점 서버측에서 이용자의 결제 내역 등을 DB에 저장하고 적절한 서비스 로직을 수행합니다.

 

 

* 모바일 감지

UA로 감지하더라.

import { withUserAgent } from "react-useragent";

function isMobile() {
  if (ua.mobile) return true;
  return false;
}

export default withUserAgent(PaymentForm);

 

 

참고한 글)

livelikeabel.tistory.com/81

 

darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체