콘텐츠로 이동

인증

팝빌 API를 사용하기 위한 공통 정의 사항과 인증 토큰 발급 및 사용 방법을 안내합니다.

팝빌 API 규격은 다음과 같이 정의합니다.

  • RESTful API
  • HTTPS 통신 / TLS 1.3, 1.2 지원
  • JSON 메시지 포맷

API 호출과 응답에 필요한 문자 인코딩은 모두 UTF-8 Character Set 을 사용합니다.

팝빌 API에서 사용하는 Base URL은 다음과 같습니다.

환경Base URLServiceID
팝빌 인증 서버https://auth.linkhub.co.kr-
팝빌 API 테스트 서버https://popbill-test.linkhub.co.krPOPBILL_TEST
팝빌 API 운영 서버https://popbill.linkhub.co.krPOPBILL

※ ServiceID는 팝빌 API 테스트/운영을 구별하는 고유식별정보입니다.

위 도메인의 IP는 가변적으로 변경됩니다.
방화벽으로 인해 고정 IP가 필요한 경우에는 아래의 Outbound 정보를 등록해야 합니다. 고정 IP를 설정한 뒤에는 아래의 안내된 도메인으로 호출해야 합니다.

환경Base URLIPPORT
팝빌 인증 서버https://static-auth.linkhub.co.kr52.78.164.186
13.124.222.90
443
팝빌 API 테스트 서버https://static-popbill-test.linkhub.co.kr52.78.164.186
13.124.222.90
443
팝빌 API 운영 서버https://static-popbill.linkhub.co.kr52.78.164.186
13.124.222.90
443

팝빌 인증 방식은 팝빌 인증 서버로부터 토큰을 발급받고, 이후 모든 API 호출 시 발급받은 토큰을 함께 전송하는 방식입니다.

  1. 팝빌 인증 서버에서 토큰을 발급받으려면 HTTP Authorization Header에 다음 형식으로 인증 정보를 기재해야 합니다.
Authorization: LINKHUB {LinkID} {Signature}

LinkID는 파트너를 식별하기 위한 값으로 팝빌에서 API Key 발급 시 제공됩니다. Signature는 요청 본문의 변조 방지를 위한 서명 값으로, API Key 발급 시 함께 제공되는 SecretKey를 이용해 HMAC-SHA256 알고리즘으로 생성합니다.

Signature 생성 방법은 다음과 같습니다.

// 팝빌에서 발급받은 API Key의 LinkID
String linkID = "TESTER";
// 팝빌에서 발급받은 API key의 SecretKey
String secretKey = "SwWxqU+0TErBXy/9TVjIPEnI0VTUMMSQZtJf3Ed8q3I=";
// 팝빌회원 사업자번호
String accessID = "1234567890";
// 토큰 사용 허용 IP -> 요청 헤더 X-LH-Forwarded 에 사용
String forwardedIP = "*";
// API 버전 -> 요청 헤더 X-LH-Version 에 사용
String apiVersion = "2.0";
// 테스트 환경: POPBILL_TEST, 운영 환경 : POPBILL
String serviceID = "POPBILL_TEST";
// Request Body
String requestBody = "{\"access_id\":\"" + accessID + "\", \"scope\":[\"110\", \"member\"]}";
byte[] bodyBytes = requestBody.getBytes(StandardCharsets.UTF_8);
// BodyDigest (SHA-256 -> Base64 encode)
byte[] sha256Bytes = MessageDigest.getInstance("SHA-256").digest(bodyBytes);
String bodyDigest = Base64.getEncoder().encodeToString(sha256Bytes);
// 요청 일시(UTC) -> 요청 헤더 X-LH-Date 에 사용
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String requestDT = sdf.format(new Date());
// 요청 URI
String resourceURI = "/" + serviceID + "/Token";
// StringToSign 구성
String stringToSign = "POST" + "\n"
+ bodyDigest + "\n"
+ requestDT + "\n"
+ forwardedIP + "\n"
+ apiVersion + "\n"
+ resourceURI;
// Signature
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(Base64.getDecoder().decode(secretKey), "HmacSHA256"));
byte[] hmacBytes = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
String signature = Base64.getEncoder().encodeToString(hmacBytes);
// Authorization Header
String authorization = "LINKHUB" + " " + linkID + " " + signature;
  • bodyDigest : 요청 본문(Request Body)의 SHA-256 해시값을 Base64로 인코딩한 문자열입니다.
  • requestDT : 요청 일시로, 반드시 UTC 시간으로 기재해야 합니다.
  • forwardedIP : 토큰 사용을 허용할 IP를 의미하며, 미입력 시 인증 서버에 토큰 발급 요청을 보낸 IP에서만 사용할 수 있습니다. 모든 IP에서 API 호출을 허용하려면 *로 입력합니다.
  • apiVersion : 팝빌 API 버전으로 2.0을 입력합니다.
  • resourceURI : 토큰을 발급받을 API의 요청 URI로, /{serviceID}/Token 형식으로 구성합니다.
  • stringToSign : HTTP Method, bodyDigest, requestDT, forwardedIP, apiVersion, resourceURI를 줄바꿈(\n)으로 연결한 문자열입니다.

stringToSign을 secretKey로 HMAC-SHA256 서명하고 Base64로 인코딩하면 signature가 생성됩니다. 생성된 signature를 Authorization Header에 입력하여 인증 토큰 발급을 요청합니다.

  1. 발급받은 인증 토큰은 팝빌 API를 호출할 때 권한을 검증하는데 사용됩니다. 토큰은 발급 시점부터 30분간 유효하며, 유효 기간이 지난 후에는 새 토큰을 재발급받아 사용해야 합니다.

팝빌 API를 호출할 때 Bearer 방식으로 Authorization Header에 토큰 값을 입력합니다.

Authorization: Bearer {session_token}
POST https://auth.linkhub.co.kr/POPBILL_TEST/Token
  • 팝빌 API를 사용하기 위한 인증 토큰을 발급합니다.

인증 토큰은 사업자번호별로 별도 발급이 필요합니다.
토큰은 발급 시점부터 30분 동안만 유효하며, 만료시에는 새 토큰을 재발급받아야 합니다.

Request

요청 헤더
순번 변수명 필수 설명
1AuthorizationY
인증 토큰
2Content-TypeY
요청 본문 형식
  • application/json
3X-LH-VersionY
API 버전
  • 2.0
4X-LH-DateY
요청 일시(UTC)
형식 : yyyy-MM-ddTHH:mm:ssZ
5X-LH-ForwardedN
토큰 사용 허용 IP
  • * 모든 IP 허용
미입력: 토큰 발급을 요청한 IP에서만 토큰 사용 가능
요청 본문
순번 변수명 타입 길이 필수 설명
1access_idstring10Y
팝빌회원 사업자번호
2scopearray-Y
API 접근 권한
  • 110 전자세금계산서
  • 140 현금영수증
  • 121 전자명세서 - 거래명세서
  • 122 전자명세서 - 청구서
  • 123 전자명세서 - 견적서
  • 124 전자명세서 - 발주서
  • 125 전자명세서 - 입금표
  • 126 전자명세서 - 영수증
  • 111 홈택스수집 - 전자세금계산서
  • 141 홈택스수집 - 현금영수증
  • 170 사업자등록상태조회
  • 171 기업정보조회
  • 182 예금주조회 - 성명조회
  • 183 예금주조회 - 실명조회
  • 180 계좌조회
  • 153 카카오톡 - 알림톡
  • 156 카카오톡 - 브랜드 메시지(I)
  • 157 카카오톡 - 브랜드 메시지(N)
  • 158 카카오톡 - 브랜드 메시지(M)
  • 150 문자 - SMS
  • 151 문자 - LMS
  • 152 문자 - MMS
  • 160 팩스 - 일반망
  • 161 팩스 - 지능망
  • member 공통
요청 예시
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, IOException {
// 팝빌에서 발급받은 API Key의 LinkID
String linkID = "TESTER";
// 팝빌에서 발급받은 API Key의 SecretKey
String secretKey = "SwWxqU+0TErBXy/9TVjIPEnI0VTUMMSQZtJf3Ed8q3I=";
// 팝빌회원 사업자번호
String accessID = "1234567890";
// 토큰 사용 허용 IP -> 요청 헤더 X-LH-Forwarded에 사용
String forwardedIP = "*";
// API 버전 -> 요청 헤더 X-LH-Version에 사용
String apiVersion = "2.0";
// 테스트 환경: POPBILL_TEST, 운영 환경 : POPBILL
String serviceID = "POPBILL_TEST";
// Request Body
String requestBody = "{\"access_id\":\"" + accessID + "\", \"scope\":[\"110\", \"member\"]}";
byte[] bodyBytes = requestBody.getBytes(StandardCharsets.UTF_8);
// BodyDigest (SHA-256 -> Base64 encode)
byte[] sha256Bytes = MessageDigest.getInstance("SHA-256").digest(bodyBytes);
String bodyDigest = Base64.getEncoder().encodeToString(sha256Bytes);
// 요청 일시(UTC) -> 요청 헤더 X-LH-Date에 사용
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String requestDT = sdf.format(new Date());
// 요청 URI
String resourceURI = "/" + serviceID + "/Token";
// StringToSign 구성
String stringToSign = "POST" + "\n"
+ bodyDigest + "\n"
+ requestDT + "\n"
+ forwardedIP + "\n"
+ apiVersion + "\n"
+ resourceURI;
// Signature
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(Base64.getDecoder().decode(secretKey), "HmacSHA256"));
byte[] hmacBytes = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
String signature = Base64.getEncoder().encodeToString(hmacBytes);
// Authorization Header
String authorization = "LINKHUB" + " " + linkID + " " + signature;
URL url = new URL("https://auth.linkhub.co.kr" + resourceURI);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Authorization", authorization);
conn.setRequestProperty("x-lh-forwarded", forwardedIP);
conn.setRequestProperty("x-lh-date", requestDT);
conn.setRequestProperty("x-lh-version", apiVersion);
try (OutputStream os = conn.getOutputStream()) {
os.write(bodyBytes);
}
int status = conn.getResponseCode();
InputStream is = (status == HttpURLConnection.HTTP_OK) ? conn.getInputStream() : conn.getErrorStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[8192];
int n;
while ((n = is.read(buf)) != -1) {
baos.write(buf, 0, n);
}
is.close();
String responseBody = new String(baos.toByteArray(), StandardCharsets.UTF_8);
System.out.println("Body : " + responseBody);
}
}

Response

응답 본문
순번 변수명 타입 길이 설명
1session_tokenstring-
인증 토큰
2serviceIDstring-
테스트/운영 환경 구분 고유식별정보
  • POPBILL_TEST 테스트
  • POPBILL 운영
3linkIDstring-
LinkID
4userIDstring-
팝빌회원 사업자번호
5partnerCodestring-
파트너코드
6usercodestring-
팝빌회원 코드
7scopearray-
API 접근 권한
  • 110 전자세금계산서
  • 140 현금영수증
  • 121 전자명세서 - 거래명세서
  • 122 전자명세서 - 청구서
  • 123 전자명세서 - 견적서
  • 124 전자명세서 - 발주서
  • 125 전자명세서 - 입금표
  • 126 전자명세서 - 영수증
  • 111 홈택스수집 - 전자세금계산서
  • 141 홈택스수집 - 현금영수증
  • 170 사업자등록상태조회
  • 171 기업정보조회
  • 182 예금주조회 - 성명조회
  • 183 예금주조회 - 실명조회
  • 180 계좌조회
  • 153 카카오톡 - 알림톡
  • 156 카카오톡 - 브랜드 메시지(I)
  • 157 카카오톡 - 브랜드 메시지(N)
  • 158 카카오톡 - 브랜드 메시지(M)
  • 150 문자 - SMS
  • 151 문자 - LMS
  • 152 문자 - MMS
  • 160 팩스 - 일반망
  • 161 팩스 - 지능망
  • member 공통
8ipaddressstring-
토큰 사용 허용 IP
9expirationstring-
토큰 만료일시(UTC)
형식 : yyyy-MM-ddTHH:mm:ssZ
응답 예시
{
"session_token": "dGfY0osTAoWNdlNwmugjEDTu...4MuWhVplgLrlQ7FzenX98qiZYDSqQ0ISEOJP",
"serviceID": "POPBILL_TEST",
"linkID": "TESTER",
"userID": "1234567890",
"partnerCode": "014040000003",
"usercode": "025070002467",
"scope": [ "member", "110" ],
"ipaddress": "*",
"expiration": "2025-11-19T03:41:17.839Z"
}