🔔 웹훅 구독 API 가이드 - 택배 상태 변경 자동 알림

📅 2026-01-13 ⏱️ 10분 읽기 🏷️ API 가이드, 웹훅, 실시간 알림

💡 이 가이드에서 배울 내용: 택배 상태가 변경될 때마다 자동으로 웹훅을 받는 방법, 웹훅 URL 등록부터 보안 검증까지 전체 플로우를 단계별로 설명합니다.

개요

웹훅 구독 API를 사용하면 택배사 송장번호를 등록하고, 배송 상태가 변경될 때마다 자동으로 알림을 받을 수 있습니다. 폴링(Polling) 방식 대신 이벤트 기반으로 알림을 받으므로 서버 리소스를 절약하고 실시간으로 배송 정보를 업데이트할 수 있습니다.

주요 특징

폴링 정책

상태별 폴링 주기

배송 상태 폴링 주기 설명
PENDING, REGISTERED, PICKUP_READY 2시간 상품 준비 단계
PICKED_UP, IN_TRANSIT, OUT_FOR_DELIVERY 30분 배송 진행 중 (빠른 업데이트)
DELIVERED, CANCELLED 중지 구독 자동 완료
FAILED, RETURNED, HOLD 2시간 예외 상태

시간대별 폴링 조정 (KST 기준)

15일 자동 중단

구독 등록 후 15일이 경과하면 자동으로 폴링이 중단됩니다. 장기간 배송되지 않는 건에 대한 불필요한 조회를 방지하기 위한 정책입니다.

💡 예시
등록일: 2026-01-01
중단일: 2026-01-16 (15일 후)
15일째부터는 폴링이 더 이상 수행되지 않습니다.

1단계: 웹훅 URL 사전 등록

구독을 등록하기 전에, 알림을 받을 웹훅 URL을 먼저 등록해야 합니다. API Key당 최대 10개까지 등록 가능합니다.

POST /v1/webhooks/endpoints

요청 예시

curl -X POST "https://api.deliveryapi.co.kr/v1/webhooks/endpoints" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer __API_KEY__:__SECRET_KEY__" \
  -d '{
    "url": "https://your-domain.com/webhook",
    "name": "주문 시스템"
  }'

응답 예시

{
  "isSuccess": true,
  "data": {
    "endpointId": "ep_6b78d0e9eac154e129847aae",
    "url": "https://your-domain.com/webhook",
    "name": "주문 시스템",
    "webhookSecret": "whsec_91289c5160ec743e0721b4a23fb5d33c",
    "dateCreated": "2026-01-13T10:30:33.292Z"
  }
}

⚠️ 중요: webhookSecret은 최초 등록 시 딱 1회만 반환됩니다. 반드시 안전한 곳에 저장하세요. 이 값은 웹훅 서명 검증에 사용됩니다.

2단계: 구독 등록

등록한 웹훅 URL의 endpointId를 사용하여 송장번호를 구독합니다. 1회 요청으로 최대 100건까지 일괄 등록 가능합니다.

POST /v1/tracking/subscriptions

요청 예시

curl -X POST "https://api.deliveryapi.co.kr/v1/tracking/subscriptions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer __API_KEY__:__SECRET_KEY__" \
  -d '{
    "items": [
      {
        "id": "order-001",
        "courierCode": "04",
        "trackingNumber": "123456789012",
        "endpointId": "ep_6b78d0e9eac154e129847aae",
        "subscribedStatuses": ["IN_TRANSIT", "DELIVERED"],
        "metadata": { "orderId": "ORD-001" }
      }
    ]
  }'

요청 필드 설명

필드 필수 설명
id 선택 클라이언트가 지정하는 ID (예: 주문번호). API Key 내에서 유니크해야 함
courierCode 필수 택배사 코드 (예: 04=CJ, 05=한진, 08=롯데)
trackingNumber 필수 송장번호
endpointId 필수 사전 등록한 웹훅 URL의 ID
subscribedStatuses 선택 알림받을 상태 목록. 미지정 시 모든 상태 알림
metadata 선택 추가 정보 (JSON 객체). 웹훅 발송 시 함께 전달됨

응답 예시

{
  "isSuccess": true,
  "data": {
    "results": [
      {
        "id": "order-001",
        "subscriptionId": "sub_cb0d4e05b5ca97f777b72215",
        "success": true,
        "currentStatus": "PENDING"
      }
    ],
    "summary": {
      "total": 1,
      "successful": 1,
      "failed": 0
    }
  }
}

✅ Dual ID 시스템: 응답에서 id(클라이언트 지정)와 subscriptionId(서버 생성) 둘 다 반환됩니다. 이후 조회/취소 시 둘 중 어느 것을 사용해도 됩니다.

3단계: 웹훅 수신 및 검증

배송 상태가 변경되면 등록한 URL로 웹훅이 전송됩니다.

웹훅 페이로드

{
  "event": "tracking.status_changed",
  "subscriptionId": "sub_cb0d4e05b5ca97f777b72215",
  "timestamp": "2026-01-13T10:30:00.000Z",
  "data": {
    "courierCode": "04",
    "trackingNumber": "123456789012",
    "previousStatus": "IN_TRANSIT",
    "currentStatus": "DELIVERED",
    "tracking": {
      "courierCode": "04",
      "trackingNumber": "123456789012",
      "status": "DELIVERED",
      "details": [...]
    }
  },
  "metadata": { "orderId": "ORD-001" }
}

보안 서명 검증 (Node.js)

const crypto = require('crypto');

function verifyWebhookSignature(req, webhookSecret) {
  const signature = req.headers['x-webhook-signature'];
  const timestamp = req.headers['x-webhook-timestamp'];
  const body = JSON.stringify(req.body);

  // 타임스탬프 검증 (5분 이내)
  const now = Math.floor(Date.now() / 1000);
  if (Math.abs(now - parseInt(timestamp)) > 300) {
    return false;
  }

  // HMAC 서명 계산
  const payload = `${timestamp}.${body}`;
  const expectedSignature = crypto
    .createHmac('sha256', webhookSecret)
    .update(payload)
    .digest('hex');

  return `sha256=${expectedSignature}` === signature;
}

4단계: 구독 관리

구독 목록 조회

GET /v1/tracking/subscriptions
curl "https://api.deliveryapi.co.kr/v1/tracking/subscriptions?status=active&limit=20" \
  -H "Authorization: Bearer __API_KEY__:__SECRET_KEY__"

구독 상세 조회

GET /v1/tracking/subscriptions/{id}
# subscriptionId로 조회
curl "https://api.deliveryapi.co.kr/v1/tracking/subscriptions/sub_cb0d4e05b5ca97f777b72215" \
  -H "Authorization: Bearer __API_KEY__:__SECRET_KEY__"

# clientId로 조회 (둘 다 가능!)
curl "https://api.deliveryapi.co.kr/v1/tracking/subscriptions/order-001" \
  -H "Authorization: Bearer __API_KEY__:__SECRET_KEY__"

구독 취소

DELETE /v1/tracking/subscriptions/{id}
curl -X DELETE "https://api.deliveryapi.co.kr/v1/tracking/subscriptions/order-001" \
  -H "Authorization: Bearer __API_KEY__:__SECRET_KEY__"

폴링 주기 정책

구독한 송장은 배송 상태에 따라 자동으로 다른 주기로 조회됩니다:

상태 폴링 주기 설명
배송 준비 (PENDING, REGISTERED) 2시간 상품 준비 단계
배송 중 (IN_TRANSIT, OUT_FOR_DELIVERY) 30분 빠른 업데이트 필요
배송 완료 (DELIVERED) 중지 구독 자동 완료
예외 (FAILED, RETURNED) 2시간 상태 변경 대기

실패 처리 및 재시도

1. 웹훅 전송 실패 시

시도 횟수 대기 시간
1차 실패1분 후 재시도
2차 실패5분 후 재시도
3차 실패30분 후 재시도
4차 실패2시간 후 재시도
5차 실패구독 비활성화 (status: 'failed')

2. 택배 조회 실패 시 (크롤러 오류)

택배사 웹사이트 조회 실패 시 지수 백오프(Exponential Backoff) 방식으로 재시도합니다.

⚠️ 중요: 웹훅 전송 실패와 택배 조회 실패는 별도로 카운트됩니다. 웹훅만 실패해도 구독은 계속 유지되며, 다음 상태 변경 시 다시 웹훅을 시도합니다.

베스트 프랙티스

테스트 방법

  1. webhook.site에서 무료 테스트 URL 생성
  2. 생성된 URL로 웹훅 엔드포인트 등록
  3. 실제 송장번호로 구독 등록
  4. webhook.site에서 실시간으로 웹훅 수신 확인
  5. 웹훅 테스트 페이지에서 직접 테스트 가능

다음 단계

🎉 준비 완료! 이제 실시간 택배 알림 시스템을 구축할 수 있습니다. 궁금한 점은 문의하기로 연락주세요.