신용카드 본인인증 연동하기


신용카드 본인인증 서비스란, 신용카드 인증을 통하여 해당 신용카드 소지자의 개인정보(이름, 생년월일, 성별, 외국인여부, KISA고유식별값)를 확인할 수 있는 서비스입니다.회원가입 단계에서 정확한 개인정보(이름, 생년월일, 성별)를 입력받을 수 있고, KISA고유식별값을 통해 기존 가입여부를 조회할 수도 있습니다. 또한, 상품 또는 서비스 이용에 연령제한을 둬야하는 경우 등 휴대폰-본인인증이 사용되는 부분에 함께 사용하시면 사용자의 편의성을 증가시킬 수 있습니다.

인증 후 취득 정보

고객이 신용카드 본인인증을 마쳤다면 가맹점은 고객의 정보를 취득하여 활용할 수 있습니다. 가맹점은 다음의 정보를 취득할 수 있습니다.
  • 이름(name)
  • 성별(gender)
  • 생년월일(birth)
  • 개인식별 고유 키(unique_key) : KISA에서 발행되는 CI값
  • 사이트 별 개인식별 고유 키(unique_in_site) : KISA에서 발행되는 DI값

연동 방법

다음의 과정을 통해 아임포트 신용카드 본인인증 서비스를 웹사이트에 설치하고 인증 결과를 취득할 수 있습니다.
STEP1아임포트 라이브러리 추가하기
웹사이트의 인증페이지의 HTML에 아래의 <script>를 삽입합니다. 아임포트 라이브러리는 jQuery 기반으로 동작하기 때문에 jQuery 1.0 이상이 반드시 설치되어 있어야합니다. 신용카드 본인인증 기능은 아임포트 JavaScript v1.1.7부터 지원합니다.
  <!-- jQuery -->
  <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" ></script>
  <!-- iamport.payment.js -->
  <script type="text/javascript" src="https://cdn.iamport.kr/js/iamport.payment-1.1.7.js"></script>
STEP2가맹점 식별하기
IMP객체의 init함수의 인자에 [가맹점 식별코드](/implementation/account-info?lang=ko)를 삽입하고 웹사이트의 인증 페이지에서 호출합니다.
  var IMP = window.IMP; // 생략해도 괜찮습니다.
  IMP.init("imp00000000"); // "imp00000000" 대신 발급받은 "가맹점 식별코드"를 사용합니다.
코드에서는 init()함수의 인자에 임의의 번호를 작성했습니다. 여러분의 관리자 대시보드에서 가맹점 식별번호를 확인 후 함수의 인자에 작성하면 됩니다.
STEP3인증창 호출코드 추가하기
IMP.certification(param, callback)을 호출합니다. 함수의 첫번째 인자인 param객체의 속성을 활용하여 인증에 대해 설정할 수 있습니다.

  • PC환경 : 팝업창이 열리면서 신용카드 본인인증 화면이 나타납니다. 본인인증 완료 후, 두 번째 인자로 지정된 callback 함수가 실행됩니다.
  • 모바일환경 :
    • popup : false(기본값) : 기존 페이지가 리디렉션되어 본인인증 페이지로 이동합니다. 본인인증 완료 후 m_redirect_url 로 다시 리디렉션됩니다.
    • popup : true : PC환경과 마찬가지로 팝업창을 통해 진행됩니다. 본인인증 완료 후, 두 번째 인자로 지정된 callback 함수가 실행됩니다.(WebView 등 팝업차단되는 환경에서는 popup : false로 진행하는 것을 권장)
  // IMP.certification(param, callback) 호출
  IMP.certification({ // param
    merchant_uid: "ORD20180131-0000011",
    m_redirect_url : "https://www.myservice.com/certifications/redirect", // 모바일환경에서 popup:false(기본값) 인 경우 필수
    popup : false // PC환경에서는 popup 파라메터가 무시되고 항상 true 로 적용됨
  }, function (rsp) { // callback
    if (rsp.success) {
      ...,
      // 인증 성공 시 로직,
      ...
    } else {
      ...,
      // 인증 실패 시 로직,
      ...
    }
  });

IMP.certification의 param객체 속성

속성명자료형설명기본값비고
merchant_uid
(v1.1.7부터 지원)
string가맹점에서 생성/관리하는 고유 주문번호random(선택항목) 본인인증과 연관된 가맹점 내부 주문번호
m_redirect_url
(v1.1.7부터 지원)
string모바일환경에서 본인인증 후 리디렉션될 URLfalse(선택항목) Query String 으로 imp_uid, merchant_uid, success 가 전달됨
popup
(모바일환경에서만 적용되는 옵션. v1.1.7부터 지원)
boolean새 창(window)에 본인인증 화면 생성 여부false(선택항목) PC의 경우 popup : true 옵션이 강제로 적용되어있음. 모바일의 경우 popup : false 사용시, m_redirect_url이 반드시 선언되어야 함
STEP4서버에 데이터조회 값(imp_uid) 전달하기
1PC환경 또는 모바일환경에서 popup(true)인 경우
callback에서 인증이 성공(rsp.success: true)하면 rspimp_uid를 서버에 전달하는 로직을 작성합니다.
  IMP.certification({
    /* ...중략... */
  }, function (rsp) { // callback
    if (rsp.success) { // 인증 성공 시
      // jQuery로 HTTP 요청
      jQuery.ajax({
        url: "https://www.myservice.com/certifications", // 서비스 웹서버
        method: "POST",
        headers: { "Content-Type": "application/json" },
        data: { imp_uid: rsp.imp_uid }
      });
    } else {
      alert("인증에 실패하였습니다. 에러 내용: " +  rsp.error_msg);
    }
  });
가맹점 서버에 imp_uid(고유 번호)를 전달하면 아임포트 서버에서 imp_uid로 인증 정보를 조회할 수 있습니다. 조회한 정보를 통해 고객의 정보를 취득하고 로직을 처리할 수 있습니다.
2모바일환경에서 popup(false)인 경우
IMP.certification() 호출 시 전달된, m_redirect_url파라메터로 아래의 Query 파라메터와 함께 302 리디렉션 됩니다.
  • imp_uid : 본인인증 건의 아임포트 본인인증 고유번호
  • merchant_uid : 본인인증 건의 가맹점 고유번호
  • status : 본인인증 성공여부. string 이며, true 또는 false
GET {m_redirect_url}?imp_uid={}&merchant_uid={본인인증 건의 merchant_uid}&success={true 또는 false}
m_redirect_url 에 해당되는 가맹점 서버의 Endpoint에서 GET파라메터로 imp_uid를 획득하여 아임포트 REST API 로 인증 정보를 조회할 수 있습니다.
STEP5서버에서 인증 조회하기
인증이 완료되면 서버에서 imp_uid값으로 인증 정보를 조회하여 고객의 정보를 취득하고 로직을 처리할 수 있습니다.
1API Endpoint 생성하기
먼저, 서버에서 imp_uid를 전달받는 API Endpoint를 생성합니다.
  app.use(bodyParser.json());
  ...
  // "/certifications"에 대한 POST 요청을 처리하는 controller : callback 방식 
  app.post("/certifications", async (request, response) => {
    const { imp_uid } = request.body; // request의 body에서 imp_uid 추출
  })
  ...
  // "/certifications/redirect"에 대한 GET 요청을 처리하는 controller : 리디렉션 방식
  app.get("/certifications/redirect", async (request, response) => {
    const { imp_uid } = request.query; // request의 query에서 imp_uid 추출
  })
2인증정보 조회하기
그 후, REST API 키REST API Secret 을 활용하여 https:\//api.iamport.kr/users/getToken에서 인증토큰을 발급받고, 해당 인증토큰과 추출한 imp_uidhttps:\//api.iamport.kr/certifications/$imp_uid를 통해 결제정보를 조회합니다.
  app.use(bodyParser.json());
  ...
  // "/certifications"에 대한 POST 요청을 처리하는 controller
  app.post("/certifications", async (request, response) => {
    const { imp_uid } = request.body; // request의 body에서 imp_uid 추출
    try {
      // 인증 토큰 발급 받기
      const getToken = await axios({
        url: "https://api.iamport.kr/users/getToken",
        method: "post", // POST method
        headers: { "Content-Type": "application/json" }, // "Content-Type": "application/json"
        data: {
          imp_key: "imp_apikey", // REST API키
          imp_secret: "ekKoeW8RyKuT0zgaZsUtXXTLQ4AhPFW3ZGseDA6bkA5lamv9OqDMnxyeB9wqOsuO9W3Mx9YSJ4dTqJ3f" // REST API Secret
        }
      });
      const { access_token } = getToken.data.response; // 인증 토큰
      ...
      // imp_uid로 인증 정보 조회
      const getCertifications = await axios({
        url: \`https://api.iamport.kr/certifications/\${imp_uid}\`, // imp_uid 전달
        method: "get", // GET method
        headers: { "Authorization": access_token } // 인증 토큰 Authorization header에 추가
      });
      const certificationsInfo = getCertifications.data.response; // 조회한 인증 정보
      ...
    } catch(e) {
      console.error(e);
    }
  });
위의 코드에서, 결제정보를 조회하기 위해 아임포트 계정에 발급되는 REST API키REST API Secret으로 인증 토큰을 발급받았습니다. 인증토큰 발급은 https:\//api.iamport.kr/users/getTokenContent-Typeapplication/json, 그리고 body에 imp_key: REST API키, imp_secret: REST API Secret을 포함하여 POST방식으로 요청을 생성했습니다.

해당 요청에 대한 응답이 오면, 응답 데이터에 담겨있는 인증토큰인 access_token을 저장합니다. 그 다음 https:\//api.iamport.kr/certifications/{imp_uid}imp_uid를 작성하고 Authorization에 발급받은 인증토큰인 access_token을 지정하고 GET방식으로 요청을 생성하여 인증정보를 조회했습니다.
3인증 정보 활용하기
조회한 인증정보에서 고객 정보를 추출합니다. 그 후 서비스에 필요한 로직을 작성합니다.
  // "/certifications"에 대한 POST 요청을 처리하는 controller
  app.post("/certifications", async (request, response) => {
    const { imp_uid } = request.body; // request의 body에서 imp_uid 추출
    try {
      // 인증 토큰 발급 받기
      /* ...중략... */
      // imp_uid로 인증 정보 조회
      /* ...중략... */
      const certificationsInfo = getCertifications.data.response; // 조회한 인증 정보
      // unique_key: 개인식별 고유 키, unique_in_site: 사이트 별 개인식별 고유 키
      const { unique_key, unique_in_site, name, gender, birth } = certificationsInfo;
      ...
      // 연령 제한 로직
      if (new Date(birth).getFullYear() <= 1999) {
        // 연령 만족
      } else {
        // 연령 미달
      }
      ...
      // 1인 1계정 허용 로직
      // DB에서 unique_key 조회 후 가입여부 검사
      Users.find({ certificationKey: unique_key })
      .then((user) => {
        if (!user) {
          // 신규 고객
        } else {
          // 이미 가입된 고객
        }
      });
    } catch(e) {
      console.error(e);
    }
  });
아임포트 서버로부터 조회한 인증정보에서 unique_key,unique_in_site, name, gender, birth 정보를 추출했습니다. 연령 제한이 필요하다면 birth정보를 통해 기준연령과 비교를 통해 연령 통과 여부를 검사할 수 있고 1인 1계정 정책이 필요하다면 unique_key를 활용하여 가입 여부를 검사할 수 있습니다.

unique_key와 unique_in_site의 의미

본인인증에 사용된 신용카드가 여러 장이어도 신용카드 소유자가 같다면 매번 unique_keyunique_in_site는 같은 값이 응답됩니다.

unique_key값은 KISA에서 발행하는 CI값으로, 개인마다 고유한 값을 가지므로 주민등록번호를 대체하여 개인을 식별/특정하는 용도로 사용할 수 있습니다.

unique_in_site값 또한 KISA에서 발행하는 DI값으로, 서비스(사이트) 단위 내에서 고유하므로 unique_key와 달리 동일한 개인이라도 서비스가 다르면 다른 값이 응답됩니다.