[공유] 쿠팡 openapi Test 가이드 및 Pre-script 설명드려요
OPEN API Test 가이드
0. OPEN API 호출개발 절차
쿠팡에서는 셀러들의 Business Success를 위해 다양한 OPENAPI를 제공하고 있습니다. 하지만, IT 서비스 개발에 익숙하지 않은 셀러라면 어디서부터 어떻게 접근해야 할지 막막할 수도 있습니다. 일반적으로 API 를 활용한 비즈니스 개발은 다음과 같은 절차로 이루어 집니다.
- 1단계 : API 명세 확인 및 이해
- 2단계 : 전문(message) 기반 OPENAPI 호출 테스트
- 3단계 : 실제 API 호출코드 개발
여기서는 전문기반으로 OPENAPI를 호출해보는 방법을 Postman이라는 무료소프트웨어를 통해 설명합니다.
1. OPENAPI Key 발급
쿠팡의 OPENAPI를 사용하기 위해서는 먼저 판매자 포탈(Wing)에서 판매자 등록 및 OPENAPI 키를 발급받아야 합니다. 판매자 등록을 위해서는 사업자등록번호가 필요하며, 자세한 절차는 여기 을 통해 확인해주시기 바랍니다.
2. POSTMAN 설치
2-1. Postman?
Postman 은 무료로 설치 가능한 API 테스트 도구입니다.
직관적이고 편리한 UI 및 기능을 제공하고 있으며, 협업기능도 제공

2-2. 다운로드 및 설치
설치프로그램은 https://www.getpostman.com/ 에서 본인의 OS 환경에 맞는 설치파일을 다운 받아 설치하면 됩니다.
Postman은 Windows, Mac, Linux 환경에서 설치하여 사용가능합니다.
3. POSTMAN 환경설정(Environment)
Postman에서는 자주 사용되는 파라메터 값(API 호출에 사용되는 매개변수 값)을 Key/Value 쌍의 형태로 미리 정의해 놓고 필요시 변경하면서 사용할 수 있습니다.
본 가이드에서는 다음의 값들을 Environment에 설정해 놓고 사용하기를 권장합니다.
- vendorId : 업체 아이디(Wing 에서 확인 가능)
- OPENAPI KEY : 쿠팡 Wing에서 발급받은 Openapi Key
- SECRET KEY : 쿠팡 Wing에서 발급받은 Openapi secret Key

우측 상단의 콤보박스에서 Environment set을 변경하거나 설정할 수 있습니다.

Environment Set의 목록을 클릭하면 개별 항목을 추가하거나 변경 또는 삭제할 수 있습니다.

여기서는 Wing에서 제공되는 항목을 참고로 하여 위와 같이 구성하도록 합니다.
참고
업체아이디나 Openapi key 정보가 한 벌인 경우 굳이 Environment를 작성하지 않고 API 호출 시 직접 입력하여도 무방합니다만, 활용하는 편이 좀 더 간편하게 API Test 정보를 구성할 수 있습니다.
4. API 테스트
여기서는 상품 목록 페이징 조회 API를 Postman을 사용하여 호출하는 방법을 알아보겠습니다.
4-1. URI & Method 입력

개발자 포탈에서 해당 API의 URI(Path)와 Method(GET/POST/PUT/DELETE 등) 을 확인합니다. 이때 Path Segment Parameter 이 URI내에 존재하는지 같이 확인합니다. 여기서는 sellerProductId가 필요합니다.

개발자 포탈에서 확인한 내용을 바탕으로 위의 이미지와 같이 API 요청을 구성합니다.
Environment 설정
앞장에서 설명한 Environment가 올바르게 지정되어있는지 확인합니다.
바인딩 파라메터(:변수명) 활용
sellerProductId 값을 URI 입력창에 바로 입력해도 되지만, 해당 값을 바꾸어가면서 테스트할 경우에는 위와 같이 ":변수명" 형식으로 URI를 구성하면 위의 그림처럼 Params 탭에서 해당 항목의 값을 key/value 형태로 입력할 수 있습니다.
4-2. Request Header 입력

API 를 호출할 때는 URI와 Method외에도 Parameter와 Header 라는 값을 전달하여야 합니다. 쿠팡의 OPENAPI는 `Authorization` 과 `X-Requeted-By` 라는 두 개의 헤더 값을 필요로 합니다.
- Authorization : API 인증 처리를 위한 HMAC 문자열 값을 전달, 4-4 절에서 다룰 Pre-Script 를 통해 동적으로 생성하여 제공가능합니다. \{\{signature\}\} 와 같은 형식으로 입력하면 pre-request script에서 생성한 값을 global variable 형태로 참조하여 전달합니다.
- X-Reqeusted-By : API 요청자 확인을 위한 vendorId, \{\{vendorId\}\} 형식으로 입력하면 Environment에 설정한 vendorId값을 자동 제공합니다.
4-3. Request Parameter 입력
아래 예제 이미지 내의 출고지 조회 API 처럼 URI `?` 뒤에 searchType=FULL 처럼 부터는 파라메터를 `Querystring Parameter` 라고 합니다. 아래 이미지 처럼 URI 창 내에 입력된 querystring parameter는 하단 Params 탭에도 표시되며 여기서 수정한 값을 URI창에서 동시에 반영됩니다.

개발자 포탈에서 확인한 API 호출 명세에 맞게 Header와 Query String 파라메터를 입력/작성합니다.
4-4. HMAC 생성을 위한 Pre-script 작성
OPENAPI 테스트를 위해서는 HMAC(Hash-based Message Authentication Code) 문자열이 필요합니다. Postman은 pre-request script 기능을 통해 HMAC을 동적으로 생성할 수 있는데, pre-request script 코드는 아래와 같습니다.
var CLIENT_KEY = pm.environment.get('CLIENT_KEY');
var SECRET_KEY = pm.environment.get('SECRET_KEY');
var AUTH_TYPE = 'CEA algorithm=HmacSHA256';
function getPath(url) {
var pathRegex = /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/;
var result = url.match(pathRegex);
return result && result.length > 1 ? result[1] : '';
}
function getQueryString(url) {
var arrSplit = url.split('?');
return arrSplit.length > 1 ? url.substring(url.indexOf('?')+1) : '';
}
function getAuthHeader(httpMethod, requestUrl, requestBody) {
var requestPath = getPath(requestUrl);
var queryString = getQueryString(requestUrl);
var timestamp = new Date().toISOString().split('.')[0]+"Z";
timestamp = timestamp.replace(/:/gi, "").replace(/-/gi, "").substring(2);
var requestData = [timestamp, httpMethod, requestPath, queryString].join("");
requestData = replaceVariables(requestData);
var hash = CryptoJS.HmacSHA256(requestData, SECRET_KEY);
var hmacDigest = CryptoJS.enc.Hex.stringify(hash);
var authHeader = AUTH_TYPE + ", access-key=" + CLIENT_KEY + ', signed-date=' + timestamp + ', signature=' + hmacDigest;
return authHeader;
}
function replaceVariables(templateString) {
let tokens = _.uniq(templateString.match(/{{\w*}}/g))
_.forEach(tokens, t => {
let variable = t.replace(/[{}]/g, '')
let value = environment[variable] || globals[variable]
templateString = templateString.replace(new RegExp(t,'g'), value)
});
return templateString
}
pm.globals.set('signature', getAuthHeader(request['method'], request['url'], request['data']));
위 내용을 복사한 후 아래 이미지처럼 Pre-request script 탭 내에 붙여넣기 하시면 됩니다.

자세한 설명
// 환경 변수에서 CLIENT_KEY와 SECRET_KEY를 가져옵니다.
var CLIENT_KEY = pm.environment.get('CLIENT_KEY');
var SECRET_KEY = pm.environment.get('SECRET_KEY');
var AUTH_TYPE = 'CEA algorithm=HmacSHA256';
// URL에서 경로(path) 부분을 추출하는 함수입니다.
/**
* 정규식(/regex/)는 특정 패턴을 매치하는 데 사용됩니다.
* 전체 정규식: /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/
* - / : 정규식의 시작과 끝을 표시합니다.
* - .+? : 가능한 한 적은 수의 모든 문자를 의미합니다. +?는 최소 매칭을 의미합니다.
* - \:\/\/ : :// 문자열을 그대로 매칭합니다.
* - .+? : 가능한 한 적은 수의 모든 문자를 의미합니다.
* - (\/.+?) : 슬래시(/)로 시작하고 그 뒤에 최소 매칭되는 모든 문자를 그룹화하여 캡처합니다.
* - (?:#|\?|$) : 비캡처 그룹. #, ? 또는 문자열의 끝($)을 매칭합니다.
*
* 정규식 요소별 설명:
* - .+? : 가능한 한 적은 수의 모든 문자를 의미합니다.
* - \:\/\/ : :// 문자열을 그대로 매칭합니다.
* - .+? : 가능한 한 적은 수의 모든 문자를 의미합니다.
* - (\/.+?) : 슬래시(/)로 시작하고 그 뒤에 최소 매칭되는 모든 문자를 그룹화하여 캡처합니다.
* - (?:#|\?|$) : 비캡처 그룹. #, ? 또는 문자열의 끝($)을 매칭합니다.
*
* 예제 URL 매칭 설명:
* URL: https://www.example.com/path/to/resource?query=1#section
* 이 정규식은 위의 URL에서 다음 부분을 추출합니다:
* "/path/to/resource"
*/
function getPath(url) {
var pathRegex = /.+?\:\/\/.+?(\/.+?)(?:#|\?|$)/;
var result = url.match(pathRegex);
return result && result.length > 1 ? result[1] : '';
}
// URL에서 쿼리 문자열(query string)을 추출하는 함수입니다.
/**
* var arrSplit = url.split('?');
* url.split('?')는 URL을 ? 문자를 기준으로 나눕니다.
*
* 예를 들어, URL이 https://www.example.com/path?query=1이라면,
* arrSplit는 ["https://www.example.com/path", "query=1"]가 됩니다.
*
* url.split('?')의 반환 값은 배열이며, ? 문자를 기준으로 나눈 문자열들이 배열의 각 요소로 들어갑니다.
*
* return arrSplit.length > 1 ? url.substring(url.indexOf('?')+1) : '';
* 삼항 연산자 (?:)를 사용하여 arrSplit 배열의 길이가 1보다 큰지 확인합니다.
*
* arrSplit.length > 1이 참이면 url.substring(url.indexOf('?') + 1)를 반환하고,
* 그렇지 않으면 빈 문자열 ''을 반환합니다.
*
* url.substring(url.indexOf('?') + 1)는 ? 이후의 모든 문자열을 반환합니다.
* 예를 들어, https://www.example.com/path?query=1인 경우 query=1을 반환합니다.
*
* 이 함수는 URL에 쿼리 문자열이 있는지 확인하고,
* 만약 있다면 이를 추출하여 반환합니다. 쿼리 문자열이 없는 경우 빈 문자열을 반환합니다.
*/
function getQueryString(url) {
// URL을 '?' 기준으로 분리합니다.
var arrSplit = url.split('?');
// URL에 '?'가 포함되어 있으면 arrSplit 배열의 길이가 2 이상이 됩니다.
// 이 경우 '?' 이후의 문자열을 반환합니다.
// 그렇지 않으면 빈 문자열을 반환합니다.
return arrSplit.length > 1 ? url.substring(url.indexOf('?')+1) : '';
}
// HMAC 기반의 인증 헤더를 생성하는 함수입니다.
/**
* HMAC (Hash-based Message Authentication Code)는 메시지의 무결성과 인증을 보장하는 데 사용되는 암호화 기법입니다.
* HMAC는 비밀 키와 해시 함수를 결합하여 생성된 값을 사용하여 데이터의 무결성을 확인하고 인증하는 데 사용됩니다.
* 여기서 HMAC 기반의 인증 헤더를 설명해드릴게요.
*
* HMAC의 구성 요소:
* 비밀 키 (Secret Key): HMAC을 생성하는 데 사용되는 비밀 키입니다. 송신자와 수신자가 공유하는 비밀 키입니다.
*
* 메시지 (Message): 인증하고자 하는 데이터입니다.
*
* 해시 함수 (Hash Function): 데이터와 키를 해싱하는 데 사용되는 함수입니다. 일반적으로 SHA-256과 같은 해시 알고리즘이 사용됩니다.
*
* HMAC 생성 과정:
* 키 패딩 (Key Padding): 비밀 키가 해시 함수의 블록 크기보다 짧으면 패딩을 통해 길이를 맞춥니다. 일반적으로 0으로 패딩합니다.
*
* 내부 해시 (Inner Hash):
* - key와 ipad의 XOR 연산 (ipad는 블록 크기만큼의 0x36으로 채워진 바이트).
* - XOR 결과와 메시지를 결합하여 해시합니다.
*
* 외부 해시 (Outer Hash):
* - key와 opad의 XOR 연산 (opad는 블록 크기만큼의 0x5C로 채워진 바이트).
* - XOR 결과와 내부 해시 결과를 결합하여 해시합니다.
*
* 최종 HMAC 값: 외부 해시의 결과가 HMAC 값이 됩니다.
*/
function getAuthHeader(httpMethod, requestUrl, requestBody) {
var requestPath = getPath(requestUrl);
var queryString = getQueryString(requestUrl);
// 현재 시간을 타임스탬프로 변환합니다.
var timestamp = new Date().toISOString().split('.')[0]+"Z";
timestamp = timestamp.replace(/:/gi, "").replace(/-/gi, "").substring(2);
// 요청 데이터를 구성합니다.
var requestData = [timestamp, httpMethod, requestPath, queryString].join("");
requestData = replaceVariables(requestData);
// HMAC 해시를 생성합니다.
var hash = CryptoJS.HmacSHA256(requestData, SECRET_KEY);
// 해시 값을 16진수 문자열로 변환합니다.
var hmacDigest = CryptoJS.enc.Hex.stringify(hash);
// 인증 헤더 값을 생성합니다.
var authHeader = AUTH_TYPE + ", access-key=" + CLIENT_KEY + ', signed-date=' + timestamp + ', signature=' + hmacDigest;
return authHeader;
}
// 템플릿 문자열에서 변수들을 실제 값으로 대체하는 함수입니다.
function replaceVariables(templateString) {
// 정규식 {{\w*}}에 매치되는 모든 항목을 찾아 고유한 값만 tokens 배열에 저장합니다.
let tokens = _.uniq(templateString.match(/{{\w*}}/g))
// tokens 배열의 각 항목에 대해 반복 작업을 수행합니다.
_.forEach(tokens, t => {
// 변수 이름에서 중괄호를 제거하여 변수명만 추출합니다.
let variable = t.replace(/[{}]/g, '')
// 환경 변수(environment)나 전역 변수(globals)에서 변수명을 키로 하여 값을 가져옵니다.
let value = environment[variable] || globals[variable]
// 템플릿 문자열에서 변수명을 실제 값으로 대체합니다.
templateString = templateString.replace(new RegExp(t,'g'), value)
});
// 값을 대체한 최종 템플릿 문자열을 반환합니다.
return templateString
}
// 생성된 인증 헤더 값을 글로벌 변수 'signature'에 저장합니다.
pm.globals.set('signature', getAuthHeader(request['method'], request['url'], request['data']));
4-5. Message Body 입력
API 요청 Method가 `POST`나 `PUT` 인 경우에는 파라메터를 메시지 본문에 작성해야 하는 경우가 있습니다. 이러한 파라메터를 메시지 Body라고 합니다. 상품 등록 API를 예제로 확인해 보겠습니다.

Body 탭을 선택한 후 메시지 형식을 `raw` 로 그리고 컨텐트 타입을 `JSON(aplication/json)` 으로 선택하고 개발자 포탈의 API 명세를 참고하여 Message Body를 작성합니다.
4-6. API 호출
여기까지 API 호출에 필요한 URI, Method, Header, Parameter, Message 를 모두 입력하였다면 Send 버튼을 클릭하여 실제 API 요청을 전달할 수 있습니다. 여기에 응답받은 결과값을 가지고 성공했다면, 어떤식으로 응답이 돌아오는지, 실패했다면, 어떤 전달 요청에 문제가 있었는지를 확인해 볼 수 있습니다.

정상적으로 응답이 온 경우 하단 Response 창에 응답메시지가 출력되며, HTTP 200 응답코드가 전달됩니다.

오류가 발생한 경우에는 해당 오류코드와 함께 오류 메시지가 전달됩니다.
5. API 호출 트러블 슈팅
API 서비스 개발과정에 있어서 중요한 건 Postman의 사용법을 잘 아는 것이 아니라 API 호출시 돌려받은 응답메시지를 잘 이해하는 데 있습니다.
5-1. FAQ 활용
쿠팡 개발자 포탈은 FAQ를 통해 응답메시지 이해를 위한 가이드를 제공하고 있습니다.
자주 문의되는 질문들을 검색기능을 사용하여 쉽게 확인할 수 있으니, 문의 전 FAQ 검색을 추천드립니다.
5-2. 오류 코드 및 메시지 확인
- 4XX 오류 :
- 5XX 오류 :
6. POSTMAN 호출 및 응답메시지 확인 방법
쿠팡 OPENAPI 호출 시 발생한 문제를 문의를 통해 접수하실 때 아래 내용을 참고하여 호출 전문과 응답메시지를 함께 기재하여 접수해주시면 보다 빠른 대응이 가능합니다.
6-1. 호출 전문 제공
전송 창 우측 상단의 code 버튼을 클릭합니다.

팝업 창과 함께 호출 전문을 클립보드로 복사할 수 있습니다.
호출 전문은 여러 형태로 표시할 수 있으나 `cURL` 형식을 추천합니다.

6-2. 응답 메시지 제공

다운로드 버튼을 사용하여 json 형태로 전문을 다운받거나, 클립보드 복사버튼을 통해 본문에 붙여넣기 하는 것도 가능합니다. 그리고 http 응답코드도 같이 포함하여 전달해주시면 됩니다.
'API Test > POSTMAN' 카테고리의 다른 글
001. API 테스트 도구 Postman에 대해 알아보니.. (1) | 2025.03.14 |
---|---|
쿠팡 상품조회 API 테스트 케이스 및 Post-response script (1) | 2025.01.30 |
Postman을 연습할 수 있는 다양한 API를 제공하는 사이트 (0) | 2024.07.22 |
Postman에서 CURL 명령어를 가져와서 실행하는 방법 (0) | 2024.04.22 |
Postman의 환경 변수 (0) | 2020.08.31 |