주문은 넣고, 송장은 바로 받고
쇼핑몰·통합 관리 프로그램·자체 ERP 가 담칸과 주문·입고·재고를 자동으로 주고받는 API 입니다. 출고가 확정되면 택배사와 송장 번호를 웹훅으로 바로 보내 드립니다.
https://damkan.com/api/v1무료로 키 만들기시작하기
- 01키 만들기
담칸 고객 화면 → 연동 → API·웹훅에서 키를 만듭니다. (회사 관리자, 'API·웹훅' 기능)
- 02키 확인
GET /me 를 불러 회사·권한이 맞는지 봅니다.
- 03주문 넣고 송장 받기
POST /orders 로 주문을 넣고, 웹훅이나 GET /orders 로 송장을 받습니다.
curl https://damkan.com/api/v1/me \ -H "Authorization: Bearer dk_live_…"
모든 요청·응답은 UTF-8 JSON 입니다. 성공하면 { "data": … }, 실패하면 { "error": { "code", "message" } } — message 는 사람이 읽는 한국어 설명입니다. 시각은 ISO 8601(UTC), 날짜는 YYYY-MM-DD 입니다.
키·권한
머리글 Authorization: Bearer dk_live_… 로 보냅니다. 키는 만들 때 한 번만 보이고 담칸은 원문을 저장하지 않습니다. 새거나 쓸모없어진 키는 고객 화면에서 바로 끄면 그 순간부터 막힙니다.
read조회 — 주문·입고·재고·품목·창고·택배사를 읽습니다.orders주문 등록·취소 — 출고 주문을 넣고, 작업 전 주문을 취소합니다.inbounds입고 예정 등록 — 들어올 물건(입고 예정)을 미리 알려 줍니다.items품목 등록·수정 — 품목 코드(SKU) 기준으로 새로 넣거나 고칩니다.
3PL(물류 대행) 은 화주사마다 키를 따로 만들 수 있습니다. 화주사 키는 그 화주사 주문·재고만 보이고 shipperCode 를 보내지 않아도 됩니다. 회사 전체 키는 주문·입고·품목마다 shipperCode 를 넣습니다. 자사 물류 회사는 화주사 코드가 필요 없습니다.
통합 관리 프로그램 연결 (사방넷·플레이오토·이지어드민 등)
여러 쇼핑몰 주문을 한 곳에 모으는 프로그램을 쓰신다면, 그 프로그램이 주문을 담칸으로 넘기고 송장을 돌려받게 하면 됩니다.
- 1. 그 프로그램의 외부 창고(WMS·3PL) 연동 메뉴나 연동 담당에게 이 문서 주소(
https://damkan.com/developers)와 키를 전달합니다. - 2. 주문은
POST /orders— 그쪽 주문번호를orderNo로 넣으면 같은 주문이 두 번 들어가지 않습니다. - 3. 송장은 웹훅
order.shipped로 바로 받거나,GET /orders?status=shipped&since=…로 가져갑니다. - 4. 쇼핑몰 재고는
GET /stocks의 available 로 맞춥니다.
담칸은 위 회사들과 별도 제휴 관계가 아니며, 각 회사 이름은 연결 방법을 설명하려고만 씁니다. 그쪽에 외부 창고 연동 기능이 없으면 주문 내보내기·Make·n8n 같은 중간 연결 서비스로 이 API 를 부를 수 있습니다. 직접 연결이 어려우면 지금처럼 엑셀 올리기도 그대로 됩니다.
기본 정보
키가 맞는지, 어떤 화주사·창고·택배사를 쓰는지 확인합니다.
/api/v1/me권한 read이 키의 회사·화주사·권한을 돌려줍니다. 연결을 처음 시험할 때 부르세요.
{ "data": { "company": { "name": "한빛로지스", "type": "3pl" }, "key": { "name": "사방넷 연동", "prefix": "dk_live_a1b2", "scopes": ["read", "orders"], "shipper": { "code": "S001", "name": "오늘의브루" } } } }/api/v1/shippers권한 read3PL 회사 전체 키일 때 화주사 코드를 확인합니다. 화주사 전용 키면 그 화주사 하나만 나옵니다.
/api/v1/warehouses권한 read주문·입고에 넣을 창고 코드(warehouseCode)를 확인합니다.
/api/v1/carriers권한 read주문에 넣을 택배사 코드(carrierCode)를 확인합니다. 웹훅의 택배사 코드도 같은 값입니다.
출고 주문
쇼핑몰·통합 관리 프로그램의 주문을 넣고, 출고 결과(송장 번호)를 가져갑니다.
/api/v1/orders권한 orders주문 한 건 또는 {"orders": [...]} 로 100건까지. orderNo(외부 주문번호)는 꼭 넣어야 하고, 같은 화주사에 같은 orderNo 는 한 번만 들어갑니다 — 다시 보내면 처음 주문을 그대로 돌려줍니다(duplicate: true). 여러 건 중 하나라도 틀리면 아무것도 들어가지 않습니다.
- orderNo * string외부 주문번호 (60자 이내)
- shipperCode string3PL 회사 전체 키일 때 화주사 코드 (화주사 전용 키·자사 물류는 안 넣음)
- warehouseCode string창고 코드. 없으면 첫 번째 창고
- carrierCode string택배사 코드. 없으면 기본 택배사
- recipient * objectname · phone · address 는 꼭, zip · memo(배송 메모)는 선택
- lines * arraysku(품목 코드 또는 바코드) · qty(1 이상 정수). 세트상품은 구성품으로 펼쳐집니다
- memo string창고에 전할 메모
{
"orderNo": "SB-20261019-0001",
"recipient": { "name": "김담칸", "phone": "010-1234-5678", "zip": "06236", "address": "서울 강남구 테헤란로 1", "memo": "문 앞" },
"lines": [ { "sku": "BREW-200", "qty": 2 } ]
}{ "data": { "no": "OUT-261019-0012", "orderNo": "SB-20261019-0001", "status": "received", "statusLabel": "접수", ... } }/api/v1/orders권한 read송장 번호를 가져갈 때는 status=shipped 와 since(마지막으로 가져간 시각)를 같이 쓰세요. since 가 있으면 그 뒤에 바뀐 것을 바뀐 순서대로 limit 건 돌려주고, 다음에 쓸 since 를 next 로, 더 남았으면 more: true 를 알려 줍니다. since 가 없으면 최근에 바뀐 것부터 돌려줍니다.
- orderNo string외부 주문번호로 찾기 (쉼표로 여러 개, 50개까지)
- status stringreceived · short · allocated · picking · picked · packed · shipped · hold · canceled
- since ISO 시각이 시각 뒤에 바뀐 것만 (출고 확정·취소·접수 시각 기준)
- limit number기본 100, 최대 200
{ "data": [ { "no": "OUT-261019-0012", "orderNo": "SB-20261019-0001", "status": "shipped", "carrier": { "code": "CJ", "name": "CJ대한통운" }, "trackingNo": "6012345678901", "shippedAt": "2026-10-19T07:41:00.000Z", "lines": [ { "sku": "BREW-200", "qty": 2 } ] } ], "next": "2026-10-19T07:41:00.000Z" }/api/v1/orders/{번호}권한 read담칸 출고 번호(OUT-…) 또는 외부 주문번호로 찾습니다. 단계별 기록(timeline)도 함께 옵니다.
/api/v1/orders/{번호}/cancel권한 orders피킹을 시작하기 전(접수·재고 부족·출고 준비·보류) 주문만 API 로 취소됩니다. 이미 작업이 시작됐으면 409 — 창고에 연락해 주세요.
{ "reason": "고객 변심" }입고 예정
공급처에서 들어올 물건을 미리 알려 두면 창고가 검수 준비를 합니다.
/api/v1/inbounds권한 inbounds한 건 또는 {"inbounds": [...]} 로 50건까지. refNo(외부 입고 번호)를 넣으면 같은 번호는 한 번만 들어갑니다.
- refNo string외부 입고(발주) 번호
- shipperCode string3PL 회사 전체 키일 때 화주사 코드
- warehouseCode string창고 코드. 없으면 첫 번째 창고
- expectedDate * YYYY-MM-DD들어올 날
- lines * arraysku · qty, 유통기한 관리 품목은 lot · expiry(YYYY-MM-DD)
- memo string메모
{ "refNo": "PO-1019", "expectedDate": "2026-10-21", "lines": [ { "sku": "BREW-200", "qty": 120, "lot": "L2610", "expiry": "2027-10-01" } ] }/api/v1/inbounds/{번호}권한 read담칸 입고 번호(IN-…) 또는 refNo 로 찾습니다. 품목별 예정·검수·불량·적치 수량이 나옵니다.
재고·품목
쇼핑몰 재고 수량을 맞추거나, 품목을 한꺼번에 등록합니다.
/api/v1/stocks권한 read품목·창고별 수량. available(지금 출고할 수 있는 수량)은 정상 재고에서 출고 준비로 잡힌 것·유통기한 지난 것·보관 구역이 아닌 것을 뺀 값입니다. 쇼핑몰 판매 수량은 이 값으로 맞추세요.
- sku string품목 코드 (쉼표로 여러 개, 200개까지)
- warehouseCode string창고 하나만
{ "data": [ { "sku": "BREW-200", "name": "콜드브루 200ml", "warehouseCode": "WH1", "onHand": 340, "allocated": 12, "available": 318, "damaged": 2 } ] }/api/v1/items권한 read사용 중인 품목. q 로 이름·코드 찾기, limit·offset 으로 나눠 받기(최대 500).
/api/v1/items권한 itemssku 가 이미 있으면 보낸 항목만 고치고, 없으면 새로 만듭니다. 한 건 또는 {"items": [...]} 로 500건까지.
- sku * string품목 코드
- name * string품목 이름 (새로 만들 때)
- barcodes string[]바코드 (첫 번째가 대표)
- category · brand string분류·브랜드
- width · height · depth · weight numbercm · kg (박스 추천에 씀)
- safetyStock number안전 재고
{ "items": [ { "sku": "BREW-200", "name": "콜드브루 200ml", "barcodes": ["8801234567890"] } ] }웹훅 — 일이 생기면 바로 알려 드립니다
고객 화면 → 연동 → API·웹훅 → 웹훅 탭에서 받는 주소(https)와 받을 일을 고릅니다.
order.shipped출고 확정 — 택배사·송장 번호가 함께 갑니다. 쇼핑몰·통합 관리 프로그램에 송장을 넣을 때 씁니다.order.received주문 접수 — API·엑셀·직접 등록 등 어떤 길로든 출고 주문이 새로 들어왔을 때.order.canceled주문 취소 — 창고나 API 로 주문이 취소됐을 때.order.short재고 부족 — 출고 준비를 하려는데 재고가 모자라 멈췄을 때.inbound.done입고 완료 — 검수·적치가 끝나 재고가 늘었을 때. 들어온 수량·불량 수량이 함께 갑니다.
POST https://받는-주소
Content-Type: application/json
X-Damkan-Event: order.shipped
X-Damkan-Delivery: whd_…
X-Damkan-Signature: t=1760859660,v1=5f2c…
{
"id": "whd_…",
"event": "order.shipped",
"createdAt": "2026-10-19T07:41:00.000Z",
"company": { "slug": "hanbit", "name": "한빛로지스" },
"data": {
"no": "OUT-261019-0012",
"orderNo": "SB-20261019-0001",
"status": "shipped",
"carrier": { "code": "CJ", "name": "CJ대한통운" },
"trackingNo": "6012345678901",
"shippedAt": "2026-10-19T07:41:00.000Z",
"lines": [ { "sku": "BREW-200", "name": "콜드브루 200ml", "qty": 2 } ]
}
}- 받는 쪽이 10초 안에 2xx 로 답하면 성공입니다. 아니면 1분·5분·30분·2시간·6시간 뒤 다시 보내고, 연속 20번 실패하면 그 웹훅을 끄고 고객 화면에 알립니다.
- 다른 주소로 넘기기(3xx)는 따라가지 않습니다. 회사 내부망·사설 IP 로는 보내지 않습니다.
- 같은 알림이 두 번 갈 수 있으니 본문의
id로 한 번만 처리해 주세요. 순서는 꼭 맞지 않을 수 있어data.changedAt을 함께 보세요. - 주문 알림의 data 는
GET /orders/{번호}와 같은 모양입니다 (받는 분은 이름만).
서명 확인
X-Damkan-Signature: t=초,v1=서명 — 서명은 웹훅 비밀값(whsec_…)으로 "초.본문" 을 HMAC-SHA256 한 16진수입니다.
// Node.js (Express) — 받은 알림이 담칸에서 온 것인지 확인
app.post("/damkan", express.raw({ type: "application/json" }), (req, res) => {
const raw = req.body.toString("utf8");
const [t, v1] = req.get("x-damkan-signature").split(",").map((p) => p.split("=")[1]);
const mine = crypto.createHmac("sha256", process.env.DAMKAN_WEBHOOK_SECRET).update(`${t}.${raw}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300; // 5분 넘은 것은 버림
if (!fresh || !crypto.timingSafeEqual(Buffer.from(mine), Buffer.from(v1))) return res.sendStatus(401);
const evt = JSON.parse(raw);
// 같은 알림이 두 번 올 수 있습니다 — evt.id 로 한 번만 처리하세요
res.sendStatus(200);
});오류·횟수 제한
| 상태 | code | 뜻 |
|---|---|---|
| 400 | bad_request | 보낸 값이 틀렸습니다. message 에 몇 번째 줄·어떤 항목인지 나옵니다. |
| 401 | invalid_key | 키가 없거나, 틀렸거나, 꺼진 키입니다. |
| 403 | missing_scope · feature_off | 이 키에 그 권한이 없거나, 회사에서 API·웹훅 기능이 꺼져 있습니다. |
| 404 | not_found | 그 주문·입고·주소가 없습니다. |
| 409 | conflict | 지금 상태에서는 할 수 없습니다 (예: 작업이 시작된 주문 취소). |
| 422 | rejected | 담칸 규칙에 걸렸습니다 (예: 품목 코드 없음, 다른 화주사 품목). |
| 423 | company_locked | 이용 정지·체험 종료 회사입니다 (체험 종료는 조회만 됩니다). |
| 429 | rate_limited | 키 하나에 1분 120번을 넘었습니다. 잠시 뒤 다시 보내세요. |
키 하나에 1분 120번까지 부를 수 있습니다. 한 번에 주문 100건 · 입고 50건 · 품목 500건까지, 본문은 1MB 까지입니다. 여러 건을 보낼 때 하나라도 틀리면 아무것도 들어가지 않고, message 에 몇 번째가 왜 틀렸는지 나옵니다. 모든 호출은 고객 화면의 호출 기록에 30일 남습니다.
자주 묻는 질문
사방넷(또는 플레이오토·이지어드민)과 바로 연결되나요?
담칸이 그 회사들과 따로 제휴한 것은 아닙니다. 그 프로그램에 외부 창고(WMS·3PL) 연동 기능이 있으면 이 문서와 키를 그쪽 연동 담당에게 전달해 연결하고, 없으면 그 프로그램의 주문 내보내기 기능이나 중간 연결 서비스(Make·n8n 등)로 이 API 를 부르면 됩니다. 연결이 어려우면 고객센터로 알려 주세요 — 함께 확인합니다.
주문을 같은 번호로 또 보내면 어떻게 되나요?
같은 화주사에 같은 orderNo 는 한 번만 들어갑니다. 다시 보내면 처음 만든 주문을 그대로 돌려주고 duplicate: true 를 붙입니다. 네트워크가 끊겨 결과를 못 받았을 때 안심하고 다시 보내세요.
송장 번호는 어떻게 받나요?
두 가지 중 편한 쪽을 쓰세요. ① 웹훅에 출고 확정(order.shipped)을 켜 두면 출고되는 순간 택배사·송장 번호를 보내 드립니다. ② 몇 분마다 GET /orders?status=shipped&since=… 로 가져가고, 응답의 next 를 다음 since 로 씁니다.
재고 수량은 무엇을 기준으로 맞추나요?
GET /stocks 의 available 입니다. 이미 다른 주문에 잡힌 수량, 유통기한이 지난 것, 불량·보류, 입고장에 있는 것은 빠져 있어 지금 팔아도 되는 수량입니다.
받는 분 개인정보는 웹훅으로 가나요?
가지 않습니다. 웹훅과 주문 조회에는 받는 분 이름만 들어가고 연락처·주소는 빠집니다. 주문을 넣을 때 받은 정보는 담칸 안에서 출고에만 씁니다.
테스트용 환경이 따로 있나요?
따로 없습니다. 가입하면 무료 체험 회사가 생기니, 그 회사에서 키를 만들어 시험하고 실제 운영 회사에서 새 키를 만드세요. 체험이 끝난 회사의 키는 조회만 됩니다.
버전 v1 · 2026-10-19 처음 공개. 항목을 더할 때는 기존 항목을 바꾸지 않고 덧붙입니다. 궁금한 점은 문의하기로 알려 주세요.
