API Reference

문서 서명 페이지 연동 API

이 문서는 eSignon 서명 페이지에서 콜백 이벤트 또는 다음 문서 작성하기 버튼 생성 유무를 설정하려는 고객사를 위한 연동 가이드입니다.

API 개요

  • GET, POST /api/{companyId}/sign?token={비대면문서시작 응답토큰}.
  • 비대면 문서 서명 페이지를 호출하며, 완료 후 동작(callback, next_sign)을 제어할 수 있습니다.

요청 정보

  • token: 필수
    비대면 문서 시작 API를 통해 발급받은 토큰입니다.
    ※ export API에서는 is_embed=true인 경우 sign_url 내의 토큰 사용
  • callback_fn: 선택
    callback_fn=true로 설정하면, 서명 완료 후 팝업의 '닫기' 버튼 클릭 시 부모 페이지(opener, popup)로 콜백 이벤트가 전달됩니다.
  • next_sign: 선택
    next_sign=false로 설정하면, 문서작성 완료 후 완료 팝업에서 다음 문서 작성하기 버튼(사진 참조)이 나오지 않습니다.

요청 정보 활용 예시

1. 부모 페이지에서 콜백 받기 (팝업 닫기)

https://docs.esignon.net/api/{companyId}/sign?token={전달받은 토큰}&callback_fn=true

2. 다음 문서 작성 알림 비활성화

https://docs.esignon.net/api/{companyId}/sign?token={전달받은 토큰}&next_sign=false

기존 완료 팝업next_sign=false 적용 팝업

3. 콜백 + 다음 문서 작성 알림 비활성화

https://docs.esignon.net/api/{companyId}/sign?token={전달받은 토큰}&callback_fn=true&next_sign=false


비대면 시작 API 요청/응답 + 예시https://developer.esignon.net/reference/startworkflow

Request
POST https://docs.esignon.net/api/v3/workflows/start Content-Type: application/json Authorization: esignon {access_token}

{
  "language": "ko",
  "recipient_list": [
    {
      "email": "[email protected]",
      "name": "홍길동",
      "order": 1
    }
  ],
  "field_list": [
    {
      "name": "Text_1",
      "value": "1111111111111"
    }
  ],
  "workflow_name": "테스트 계약 문서",
  "template_id": "170"
}

 

Response

{
  "workflow_id": 12584,
  "workflow_name": "테스트 계약 문서",
  "language": "ko-KR",
  "token": "FAEx6i%2BuVzYeOrK%2BXvED8it%2BQSAY2nBuXywNRsydwpbvNKUdNf%2BL3rCQRSZpe15LP%2BDKtUmL3gY%3D"
}

export API 활용 예시

https://developer.esignon.net/reference/export-api


샘플 코드

사용되는 API 목록

  1. 인증 토큰 발급 API
    • POST /api/{companyId}/login?lang={language}
    • 설명: eSignon API 사용을 위한 access_token을 발급받습니다.
  2. 비대면 문서 시작 API
    • POST /api/v3/workflows/start
    • 설명: 비대면 문서를 생성하고, 서명 URL 생성을 위한 token을 반환합니다.
  3. 서명 URL
    • GET /api/{companyId}/sign?...
    • 설명: 비대면 문서 시작 API로 발급받은 token(필수)과 파라미터(선택)로 서명 페이지를 호출합니다.
  • demo.html
<html>
  <head>
    <meta charset="utf-8" />
    <!-- AXIOS REST API Library -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script>
    <!-- eSignon API Javascript Sample -->
    <script src="esignon-sample.js"></script>

    <script>
      //팝업에서 서명 완료 후 콜백받을 함수 선언
      window.addEventListener("message", function (e) {
        console.log(e.data);
        alert("이싸인온에서 서명을 완료하셨네요? callback 성공!");
      });

      /**
       * 문서 시작하기
       * 1. 인증
       * 2. 문서시작
       * 3. 서명창 띄우기(팝업)
       */
      async function start() {
        const domain = document.getElementById("domain").value;
        let language = document.getElementById("language");
        language = language.options[language.selectedIndex].value || "ko";

        const companyId = document.getElementById("company").value; // 회사 ID ( 회사명 X )
        const email = document.getElementById("email").value; // 계정 이메일
        const password = document.getElementById("password").value; // 계정 비밀번호

        const workflowName = document.getElementById("workflowName").value; //문서명
        const recipientName = document.getElementById("recipientName").value;
        const recipientEmail = document.getElementById("recipientEmail").value;
        const fieldName = document.getElementById("fieldName").value; // 필드 이름
        const fieldValue = document.getElementById("fieldValue").value;
        const templateId = document.getElementById("templateId").value; //서식아이디(이싸인온 로그인 후 서식 메뉴에서 확인 가능)

        //첫번째로 API 통신을 하기 위해 인증토큰을 발급한다.
        try {
          //Call API
          const retData = await getAccessToken(
            domain,
            companyId,
            email,
            password,
            language
          );

          //Request
          console.log("req", retData.req);
          //Response
          console.log("res", retData.res);

          //Success
          if (retData.res.header.result_code == "00") {
            let accessToken = retData.res.body.access_token;

            try {
              let recipientList = new Array(); //작성할 사람(서식의 문서 작성자 수와 일치해야함)
              recipientList.push(
                //이메일주소 또는 휴대폰번호
                //작성자 이름, 가입자의 경우 가입된 이름(프로필에 설정된 이름)으로 전송됩니다.
                new SetPlayer(recipientEmail, recipientName)
              );

              let fieldList = new Array(); //서식 필드에 입력값
              if (!isNull(fieldName) && !isNull(fieldValue)) {
                fieldList.push(
                  //필드 이름
                  //필드에 입력할 값
                  new SetFieldList(fieldName, fieldValue)
                );
              }

              //문서 시작
              let res = await startNonfaceWorkflow(
                domain,
                accessToken,
                workflowName,
                templateId,
                recipientList,
                fieldList,
                language
              );
              if (res.status === 200) {
                res = res.res;
                console.log("success", res);
                let url = `${domain}/api/${companyId}/sign?token=${res.token}`;
                url += `&callback_fn=true`; //문서작성 완료 후 완료 팝업에서 닫기 버튼을 누르면 부모페이지로 이벤트 발송
                url += `&next_sign=false`; //문서작성 완료 후 완료 팝업에서 다음작성하기 버튼 나오지 않도록 처리
                url += `&lang=${language}`;
                try {
                  window.open(url, "_blank");
                } catch (e) {
                  alert(
                    "팝업 차단 기능이 설정되어있습니다\n\n차단 기능을 해제(팝업허용) 한 후 다시 이용해 주십시오.\n\n만약 팝업 차단 기능을 해제하지 않으면\n정상적인 계약이 완료되지 않습니다."
                  );
                  return;
                }
              } else {
                if (error.response) {
                  alert(error.response.data.message);
                  console.log(error.response.data);
                }
              }
            } catch (error) {
              if (error.response) {
                  alert(error.response.data.message);
                  console.log(error.response.data);
              } else {
                  alert(error);
              }
            }
            //Fail
          } else {
            //Do Something
            alert(retData.res.header.result_msg);
          }
        } catch (error) {
          console.log(error);
          alert(error);
        }
      }

      function exportStart() {
        try {
            const domain = document.getElementById("domain").value;
            const companyId = document.getElementById("company").value;

            if(isNull(companyId)) {
                alert("companyId value is required.");
                document.getElementById("company").focus();
                return;
            }
            let exportToken = document.getElementById("exportToken").value; 
            let language = document.getElementById("language");
            language = language.options[language.selectedIndex].value || "ko";
            let testUrl = `${domain}/api/${companyId}/sign?token=${exportToken}`;
            testUrl += `&callback_fn=true`; //문서작성 완료 후 완료 팝업에서 닫기 버튼을 누르면 부모페이지로 이벤트 발송
            testUrl += `&next_sign=false`; //문서작성 완료 후 완료 팝업에서 다음작성하기 버튼 나오지 않도록 처리
            console.log(testUrl);
            window.open(testUrl, "_blank");

        }catch(e) {
            alert(e);
        }
      }
    </script>
  </head>
  <br>
  * 이싸인온 플레이어 화면에서 콜백을 받고자 하시는 고객분에게 제공하는 샘플 소스입니다.<br />
  * api 사이트에 설명되어있는 비대면 문서시작 방식으로 제공하는 URL은<br/>
    &nbsp;&nbsp;서명 완료 후 이싸인온 페이지로 redirect 시키기 때문에<br/>
    &nbsp;&nbsp;서명 후 팝업 종료가 가능하게 하시려면 아래 URL 형식으로 제공하시어 콜백 이벤트 처리해주셔야 합니다.<br />
      - https://docs.esignon.net/api/{companyId}/sign?token={token}&callback_fn=true&next_sign=false<br /><br />
  * 위에 token은 비대면 문서 시작 api를 성공적으로 발송하면 발급 받을 수 있습니다.<br />
  * (is_embed가 true인 경우 sign_url에 포함되어 있는 token 사용) <br /><br />
  domain: <input id="domain" value="https://docs.esignon.net" /><br />
  회사 아이디: <input id="company" value="" /><br /><br />

    Example 1) 일반 비대면 문서 시작의 경우(export api 사용 x)<br />
    <hr />
    계정 이메일: <input id="email" value="" /><br />
    계정 비밀번호:
    <input id="password" type="password" value="" /><br /><br />

    workflow_name(문서명):
    <input id="workflowName" type="text" value="테스트 계약 문서" /><br />
    template_id(시작할 서식의 ID):
    <input id="templateId" type="text" value="" /><br />
    language(언어):
    <select id="language" name="language">
      <option value="ko" selected>ko</option>
      <option value="en">en</option>
      <option value="ja">ja</option></select
    ><br /><br />

    recipient_lsit(문서 작성자 목록)<br />
    email:
    <input id="recipientEmail" type="text" value="" /><br />
    name: <input id="recipientName" type="text" value="홍길동" /><br /><br />

    field_list(필드 값 미리 입력)<br />
    필드 이름: <input id="fieldName" value="Text_0" /><br />
    필드 값: <input id="fieldValue" value="기본값" /><br /><br />
    <button id="btn_start" onclick="start();">문서시작하기</button><br/><br />
    
    Example 2)export api is_embed로 api 전송 성공시 응답 받은 token으로 테스트하기 <br />
    <hr />
    export api 사용하시는 경우, 호출 성공 후 응답 받은 sign_url에 포함되어 있는 token을 입력하시고 아래 버튼을 눌러서 테스트해주세요.<br />
    
    token: <input id="exportToken" value="" /><br/>
    <button id="btn_start" onclick="exportStart();">문서시작하기</button><br/><br />
  </body>
</html>
  • esignon-sample.js
/** Start :  ### ########################################### */
const isNull = function (str) {
  if (
    str !== "" &&
    str !== "undefined" &&
    str !== undefined &&
    str !== null &&
    str !== "null"
  ) {
    return false;
  } else {
    return true;
  }
};
const isNotNull = function (str) {
  return !isNull(str);
};
/* ################################################################################################## */
/** Start : Request 객체 생성, Create Request Object ##################### */
/* #################################################################################################### */
const RequestHeader = function (accessToken) {
  this["Content-Type"] = "application/json";
  if (isNotNull(accessToken)) {
    this.Authorization = "esignon " + accessToken;
  }
};

const EsignonRequest = function (header, body) {
  this.header = header;
  this.body = body;
};

const EsignonRequestHeader = function (reqeustCode, version) {
  this.request_code = reqeustCode;

  if (
    version == null ||
    version == undefined ||
    version == "" ||
    version == "null"
  ) {
    this.version = "9.9.99";
  } else {
    this.version = version;
  }
};
/* ################################################################################################## */
/** End : Request 객체 생성, Create Request Object #####################  */
/** Strat : 인증토큰 발급 : https://developer.esignon.net/reference/maketoken #######  */
/* ################################################################################################## */
//Request body 생성, Create Request body
const RequestBodyAccessToken = function (email, password) {
  this.memb_email = email;
  this.memb_pwd = password;
};

/** 인증토큰 발급
 * @param companyId 회사아이디 : 이싸이온 설정 > 회사프로필 메뉴에서 확인할 수 있습니다.(회사 개설한 사람-리더직책만 가능)
 * @param email 사용자 가입 이메일 : 로그인할때 사용하는 이메일
 * @param password 사용자 비밀번호
 * @param language API Response.header.result_msg를 선택언어로 표시
 */
const getAccessToken = async function (
  domain,
  companyId,
  email,
  password,
  language
) {
  if (isNull(domain)) {
    domain = "https://docs.esignon.net";
  }
  if (isNull(companyId)) {
    throw "getAccessToken.companyId value is required.";
  }

  if (isNull(email)) {
    throw "getAccessToken.email value is required.";
  }

  if (isNull(password)) {
    throw "getAccessToken.password value is required.";
  }

  if (isNull(language)) {
    language = "ko";
  } else {
    language = language.substring(0, 2);
  }

  let requestJson = new EsignonRequest(
    new EsignonRequestHeader("1001Q"),
    new RequestBodyAccessToken(email, password)
  );

  //API호출
  let response = await axios({
    url: domain + "/api/" + companyId + "/login?lang=" + language,
    method: "POST",
    headers: new RequestHeader(),
    data: requestJson,
  });

  response.res = response.data;
  response.req = requestJson;
  return response;
};
/* ################################################################################################## */
/** End : 인증토큰 발급 : https://developer.esignon.net/reference/maketoken ######### */
/** Strat : 비대면 문서 시작 : https://developer.esignon.net/reference/startworkflow */
/* ############################################################################################################ */
/** 비대면 문서 시작 Reqeust.Body.body */
const RequestBodyStartSimple = function (
  workflowName,
  templateId,
  recipientList,
  fieldList,
  language
) {
  let returnObj = {
    language,
    recipient_list: recipientList,
    field_list: fieldList,
    workflow_name: workflowName,
    template_id: templateId,
  };
  if (isNull(fieldList)) {
    returnObj = {
      language,
      recipient_list: recipientList,
      workflow_name: workflowName,
      template_id: templateId,
    };
  }
  return returnObj;
};

/** 작성할 사람 설정  */
const SetPlayer = function (emailOrMobileNo, name) {
  if (isNull(emailOrMobileNo)) {
    throw "SetPlayer.emailOrMobileNo value is required.";
  }

  if (isNull(name)) {
    throw "SetPlayer.name value is required.";
  }

  if (isNull(language)) {
    language = "ko-KR";
  }

  this.email = emailOrMobileNo; //필수 : 받는사람 이메일 또는 휴대폰 번호
  this.name = name; //필수 : 받는 사람 이름
};

/** 박스값을 입력하여 발송 */
const SetFieldList = function (fieldName, fieldValue) {
  if (isNull(fieldName)) {
    throw "SetFieldList.fieldName value is required.";
  }

  if (isNull(fieldValue)) {
    throw "SetFieldList.fieldValue value is required.";
  }

  this.name = fieldName; //필수 : 박스이름
  this.value = fieldValue; //필수 : 박스값
};

/**
 * 비대면 계약을 전송합니다.
 * @param accessToken 인증토큰 getAccessToken함수를 이용하여 발급받은 토큰
 * @param companyId 회사아이디 회사아이디 : 이싸이온 설정 > 회사프로필 메뉴에서 확인할 수 있습니다.(회사 개설한 사람-리더직책만 가능)
 * @param senderEmail 보내는 사람 이메일
 * @param workflowName 보내는 문서(계약서) 제목
 * @param docId 서식아이디
 * @param language msg 표시 언어
 * @param playerList (Array) 작성하는 사람들
 */
const startNonfaceWorkflow = async function (
  domain,
  accessToken,
  workflowName,
  templateId,
  recipientList,
  fieldList,
  language
) {
  if (isNull(domain)) {
    domain = "https://docs.esignon.net";
  }
  if (isNull(accessToken)) {
    throw "startNonfaceWorkflow.accessToken value is required.";
  }

  if (isNull(workflowName)) {
    throw "startNonfaceWorkflow.workflowName value is required.";
  }

  if (isNull(templateId)) {
    throw "startNonfaceWorkflow.templateId value is required.";
  }

  if (isNull(recipientList)) {
    throw "startNonfaceWorkflow.recipientList value is required.";
  }

  if (isNull(language)) {
    language = "ko";
  }

  //작성자 순서 자동 등록
  for (let index = 0; index < recipientList.length; index++) {
    recipientList[index].order = index + 1;
  }

  const requestJson = RequestBodyStartSimple(
    workflowName,
    templateId,
    recipientList,
    fieldList,
    language
  );

  language = language.substring(0, 2);

  //API호출
  const response = await axios({
    url: domain + "/api/v3/workflows/start",
    method: "POST",
    headers: new RequestHeader(accessToken),
    data: requestJson,
  });

  response.res = response.data;
  response.req = requestJson;

  return response;
};
/** End : 비대면 계약 시작 : https://developer.esignon.net/reference/startworkflow */
/* ########################################################################################################## */

기타 안내