Webhook 참조
요약
HTTPS 엔드포인트를 등록하면 주문 또는 결제 상태가 바뀔 때마다 Elim이 여러분의 시스템으로 직접 호출합니다. 상태를 계속 폴링할 필요가 없습니다. 이 페이지는 이벤트, 관리 엔드포인트, 페이로드 구조, 서명 검증, 재시도 정책을 다룹니다.
Webhook이 주문 수명 주기에서 차지하는 위치는 주문 가이드와 주문 API 참조를 참고하세요.
모든 엔드포인트는 JWT 인증(Authorization: Bearer <token>) 또는 API 키(x-api-key)가 필요합니다.
이벤트
| 이벤트 | 전송 시점 |
|---|---|
order.updated | 주문 status 변경: 플랫폼 동기화, 예약 동기화, 취소 |
payment.updated | payment_status 변경: 결제 요청, 요청 취소, 승인, 거절, 플랫폼 결제 성공/실패, 환불 |
구독한 이벤트만 수신합니다. 보통 둘 다 구독합니다.
구독 관리 엔드포인트
접두사 /v1/webhooks.
| 엔드포인트 | 메서드 | 설명 |
|---|---|---|
/v1/webhooks | GET | 기존 구독 목록 |
/v1/webhooks | POST | 구독 생성 — secret을 한 번만 반환 |
/v1/webhooks/:id | PATCH | url, events, is_active 수정 |
/v1/webhooks/:id | DELETE | 구독 삭제 |
/v1/webhooks/:id/rotate-secret | POST | secret 재발급 — 새 값을 한 번만 반환 |
/v1/webhooks/:id/deliveries | GET | 최근 전송 로그 |
/v1/webhooks/:id/test | POST | 등록된 url로 테스트 전송 |
생성 본문
{
"url": "https://your-system.example/webhooks/elim",
"events": ["order.updated", "payment.updated"],
"is_active": true
}
secret은 생성 또는 rotate-secret 직후에만 반환됩니다. 모든 요청을 검증하는 데 필요하므로 안전하게 보관하세요. secret을 분실하면 rotate-secret으로 재발급합니다(기존 서명은 즉시 무효화됩니다).
페이로드 구조
두 이벤트는 동일한 구조를 사용하며 event 필드만 다릅니다.
{
"id": "evt_4a1f2c...",
"event": "payment.updated",
"created_at": "2026-06-19T00:00:00.000Z",
"data": {
"order": {
"id": "ORD0000000123",
"platform": "taobao",
"order_id": "123456789",
"status": "paid",
"payment_status": "paid",
"platform_payment_status": "success",
"total_amount_cny": 123.45,
"updated_at": "2026-06-19T00:00:00.000Z"
}
}
}
| 필드 | 설명 |
|---|---|
id | 이벤트 id, evt_... — 중복 처리 방지에 사용 |
event | order.updated 또는 payment.updated |
created_at | 이벤트 생성 시각(ISO 8601) |
data.order.id | 내부 주문 번호 ORD... — 시스템에서 주문을 조회하는 키 |
data.order.order_id | 플랫폼 주문 번호(플랫폼에 아직 생성되지 않았으면 null) |
data.order.status | 플랫폼 상태 — status 표 참조 |
data.order.payment_status | Elim 결제 상태 — payment_status 표 참조 |
data.order.platform_payment_status | 플랫폼 측 결제 결과 |
data.order.total_amount_cny | 주문 금액(CNY), null일 수 있음 |
data.order.updated_at | 주문의 마지막 갱신 시각(ISO 8601) |
핸들러 처리: data.order.id로 주문을 조회하고 시스템의 주문 상태를 갱신한 뒤 HTTP 2xx를 반환합니다. 페이로드는 순서가 뒤바뀌어 도착할 수 있으므로, 항상 더 새로운 updated_at을 신뢰하고 이미 보유한 상태보다 오래된 이벤트는 무시하세요.
각 전송의 헤더
| 헤더 | 값 |
|---|---|
Content-Type | application/json |
User-Agent | elim-api-webhooks/1.0 |
X-Elim-Event | 이벤트 이름 |
X-Elim-Delivery | 전송 id(재시도마다 변경) |
X-Elim-Timestamp | Unix 시간(초) |
X-Elim-Signature | sha256=<hmac> |
서명 검증
서명 문자열: "{X-Elim-Timestamp}.{원본 JSON 본문}" — 파싱 후 재직렬화하지 말고 수신한 원본 본문을 사용하세요.
알고리즘: HMAC-SHA256(secret, 서명 문자열), X-Elim-Signature의 sha256= 뒤 부분과 타이밍 안전 비교로 대조합니다.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyElimWebhook(
secret: string,
timestamp: string,
rawBody: string,
signature: string,
): boolean {
const expected = `sha256=${createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex')}`;
return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
재생 공격을 줄이기 위해 X-Elim-Timestamp가 현재와 너무 차이 나는(예: 5분 초과) 요청은 거부하세요.
재시도 정책
| 조건 | 결과 |
|---|---|
2xx 응답 | 전송 성공으로 표시 |
타임아웃 / 네트워크 오류 / 비 2xx | 재시도 예약 |
| 총 시도 횟수 | 3 |
| 시도 간격 | 60초, 그다음 300초 |
| 요청당 타임아웃 | 10초 |
전송별 결과는 GET /v1/webhooks/:id/deliveries에서 확인합니다. POST /v1/webhooks/:id/test로 수신 설정을 빠르게 검증하세요.
보안
- 운영 환경 URL은 반드시 HTTPS여야 합니다. 개발 환경은
localhost허용. - 운영 환경에서는 사설/내부/메타데이터 IP가 차단됩니다.
secret은 생성 또는rotate-secret이후에만 표시됩니다.- 페이로드에는 비밀번호, API 키, JWT, 플랫폼 액세스 토큰이 포함되지 않습니다.
Webhook을 아직 설정하지 않았다면
GET /v1/orders/:id로 언제든 상태를 직접 조회할 수 있습니다. 호출할 때마다 Elim이 플랫폼에서 최신 상태를 동기화한 뒤 응답합니다. 주문 API 참조를 보세요.