Webhooks

앱이 HIOBuy 창고 풀필먼트(warehouse) 모드일 때 HIOBuy는 풀필먼트 라이프사이클 이벤트를 HTTPS 엔드포인트로 푸시합니다. Developer Portal → Webhooks 에서 설정하세요. 전송은 비동기이며 Public API 응답은 Webhook 서버를 기다리지 않습니다.

사전 조건: 채널 인증 → 풀필먼트 모드 = HIOBuy warehouse. Self 모드에서는 포털 안내만 볼 수 있으며 Endpoint 생성/활성화는 불가합니다.

개요 {#overview}

항목
전송POST JSON 를 엔드포인트로
타임아웃10 초
성공HTTP 2xx
서명 시크릿whsec_… (생성/교체 시 한 번만 표시)
서명 헤더HioBuy-Signature
이벤트 ID 헤더HioBuy-Event-Id
User-AgentHioBuy-Webhooks/1.0
재시도최대 5회: 즉시, 이후 1m / 5m / 30m / 2h
테스트 이벤트포털 테스트 전송livemode: false, id 접두사 evt_test_

등록, 시크릿 교체, 전송 기록, 수동 재시도는 포털 전용(세션 인증)입니다. v1에는 Public /v1/webhooks/* 관리 API가 없습니다.

이벤트 목록 {#events}

엔드포인트별로 구독합니다. 최소 1개 필요.

카테고리이벤트 유형발생 시점
조달procurement.failed창고 조달 실패
조달procurement.out_of_stock조달 중 SKU 품절
입고package.received국내 소포가 창고에 도착
입고package.exception입고 예외(data.exception_type)
합포장consolidation.completed합포장 완료(출고 준비)
출고shipment.created국제 운송장 생성
출고shipment.dispatched운송사에 인계
출고shipment.delivered수령인에게 배송 완료
출고shipment.exception출고 예외(data.exception_type)
계정balance.low창고 지갑이 임계값 미만

창고→개발자 라이브 푸시는 단계적으로 확대됩니다. 지금은 포털 테스트 전송으로 수신단을 검증하세요.

공개 엔벨로프 {#envelope}

모든 전송 본문은 다음 JSON입니다.

{
  "id": "evt_01HXYZ…",
  "type": "package.received",
  "created_at": "2026-08-16T04:00:00.000Z",
  "livemode": true,
  "app_id": "app_…",
  "data": {
    "package_id": "pkg_…",
    "order_id": "ord_…",
    "status": "received"
  }
}
필드타입설명
idstring공개 이벤트 ID(라이브 evt_…, 테스트 evt_test_…)
typestring카탈로그의 이벤트 유형
created_atstringISO-8601 타임스탬프
livemodeboolean포털 테스트는 false
app_idstring앱 ID
dataobject이벤트별 페이로드(창고 내부 필드 없음)

data 예시 {#data-shapes}

아래는 포털 테스트 샘플입니다. 라이브도 동일한 키를 사용합니다.

procurement.failed

{
  "order_id": "ord_…",
  "status": "failed",
  "reason": "supplier_rejected"
}

package.exception

{
  "package_id": "pkg_…",
  "order_id": "ord_…",
  "status": "exception",
  "exception_type": "DAMAGED"
}

shipment.dispatched

{
  "shipment_id": "shp_…",
  "tracking_number": "…",
  "status": "dispatched"
}

balance.low

{
  "available_amount": 12.5,
  "currency": "USD",
  "threshold": 50
}

HTTP 전송 {#delivery}

POST /your/webhook-path HTTP/1.1
Host: your-server.example
Content-Type: application/json
User-Agent: HioBuy-Webhooks/1.0
HioBuy-Event-Id: evt_01HXYZ…
HioBuy-Signature: t=1723780800,v1=abcdef0123456789…
  • 프로덕션 Endpoint URL은 HTTPS여야 합니다. 비프로덕션에서는 http://localhost/터널을 허용할 수 있습니다.
  • 10초 안에 2xx를 반환하세요. 그 외 상태/네트워크 오류는 재시도됩니다.
  • 전송은 최소 1회. id(및 선택적으로 HioBuy-Event-Id)로 멱등 처리하세요.

서명 검증 {#signature}

  1. HioBuy-Signature 읽기(t=<unix_seconds>,v1=<hex_hmac>).
  2. 서명 문자열 구성: "{t}.{raw_body}". raw_body는 수신한 원본 본문(UTF-8 JSON).
  3. HMAC-SHA256(secret, signed_payload) 계산 후 hex.
  4. v1과 상수 시간 비교.
  5. |now - t|가 너무 크면 거부(권장 허용: 5분).

Node.js 예제

import crypto from "node:crypto";
 
function verifyHioBuySignature(rawBody, signatureHeader, secret, toleranceSec = 300) {
  const match = /^t=(\d+),v1=([0-9a-f]+)$/i.exec(signatureHeader || "");
  if (!match) return false;
 
  const t = Number(match[1]);
  const expected = match[2].toLowerCase();
  if (!Number.isFinite(t)) return false;
  if (Math.abs(Math.floor(Date.now() / 1000) - t) > toleranceSec) return false;
 
  const signed = `${t}.${rawBody}`;
  const digest = crypto
    .createHmac("sha256", secret)
    .update(signed, "utf8")
    .digest("hex");
 
  const a = Buffer.from(digest, "utf8");
  const b = Buffer.from(expected, "utf8");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

whsec_…는 서버에만 저장. 포털 목록은 마스킹(끝 6자). 교체 후 다음 전송 전에 서버를 업데이트하세요.

재시도 및 전송 상태 {#retries}

시도이전 실패 후 지연
1즉시(큐 적재)
21 분
35 분
430 분
52 시간

최종 실패 후 failed. 포털 전송 상세에서 지금 재시도로 다시 큐에 넣을 수 있습니다.

전송 상태: pending · success · retrying · failed.

포털 워크플로 {#portal}

  1. 채널 인증 / 풀필먼트 설정에서 앱을 창고 풀필먼트로 설정.
  2. Webhooks 엔드포인트 추가.
  3. HTTPS URL, 선택 설명, 구독 이벤트 입력.
  4. 표시된 서명 시크릿을 즉시 복사(한 번만).
  5. 테스트 이벤트 전송 후 최근 전송/attempt 확인.
  6. 필요 시 시크릿 교체, 비활성화, 삭제.

한도 및 보관 {#limits}

한도
Payload≤ 64 KB
attempt에 저장되는 응답 본문≤ 4 KB
이벤트/전송 보관~30 일
Attempt~14 일

관련

Get Support

Need integration help? Contact Developer Support at support@hiobuy.com · Response within 1–2 business days

Email support