웹훅 (Webhook)
Gency 웹훅을 등록해 상품 생성·삭제·검수 상태 변경 이벤트를 실시간으로 수신하는 방법을 안내합니다. 지원 이벤트 타입과 페이로드 형식, 재시도 규칙을 함께 정리했습니다.
Webhook 사용법
앱이 Gency 내에서 발생하는 이벤트를 실시간으로 수신할 수 있도록 웹훅을 등록할 수 있습니다.
웹훅 등록
API 센터에서 새 웹훅 만들기를 클릭하고 다음 항목을 입력합니다.
- 이름 (필수, 최대 100자): 웹훅을 식별할 수 있는 이름
- URL (필수, HTTPS만 허용, 최대 500자): 이벤트 발생 시 POST 요청을 보낼 엔드포인트
- 구독 이벤트 : 수신할 이벤트 타입을 체크박스로 선택
지원 이벤트 타입
| 이벤트 | 설명 |
|---|---|
product.created | 상품이 생성됨 |
product.deleted | 상품이 삭제됨 |
product.pending_review | 검수 대기 상태로 변경됨 |
product.in_review | 검수 진행 중으로 변경됨 |
product.review_completed | 검수가 완료됨 |
product.creation_failed | 상품 생성에 실패함 |
이벤트 페이로드
이벤트 발생 시 등록된 URL로 다음 형식의 POST 요청이 전송됩니다. event 필드는 공통이며, data 내부 구조는 이벤트 타입에 따라 다릅니다.
product.pending_review / product.in_review / product.review_completed
상품의 검수 상태가 변경되었을 때 발송됩니다.
{
"event": "product.review_completed",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "REVIEW_COMPLETE",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}
| 필드 | 타입 | 설명 |
|---|---|---|
products | Array | 상태가 변경된 상품 목록 |
products[].workspaceId | String | 워크스페이스 ID |
products[].productId | String | 상품 ID |
products[].projectId | String | 관리명 |
products[].productName | String | 상품명 |
products[].status | String | 변경된 상태 (BEFORE_REVIEW: 검수전, IN_REVIEW: 검수중, REVIEW_COMPLETE: 검수완료, CREATION_FAILED: 생성실패) |
products[].category | String | 카테고리 |
products[].productType | String | 상품 타입 (FASHION, JEWELRY) |
products[].createdId | String | 생성자 ID |
products[].createdAt | String | 생성일시 (ISO 8601) |
product.created
상품이 생성되었을 때 발송됩니다.
{
"event": "product.created",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "BEFORE_REVIEW",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}
product.creation_failed
상품 생성에 실패했을 때 발송됩니다.
{
"event": "product.creation_failed",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"projectId": "my-project-01",
"productName": "겨울 패딩 자켓",
"status": "CREATION_FAILED",
"category": "OUTER",
"productType": "FASHION",
"createdId": "01HUSR...",
"createdAt": "2025-01-01T00:00:00+09:00"
}
]
}
}
페이로드 구조는 상태 변경 이벤트와 동일합니다. status가 PRODUCT_STATUS_05 (생성 실패)로 설정됩니다.
product.deleted
상품이 삭제되었을 때 발송됩니다.
{
"event": "product.deleted",
"data": {
"products": [
{
"workspaceId": "01HABC...",
"productId": "01HXYZ...",
"productName": "겨울 패딩 자켓"
}
]
}
}
| 필드 | 타입 | 설명 |
|---|---|---|
products | Array | 삭제된 상품 목록 |
products[].workspaceId | String | 워크스페이스 ID |
products[].productId | String | 상품 ID |
products[].productName | String | 상품명 |
재시도정책
웹훅 발송이 실패하면 시스템이 자동으로 재시도합니다. 최초 발송을 포함하여 최대 5회 (최초 1회 + 재시도 4회) 시도하며, 지수 백오프 방식으로 간격이 늘어납니다.
- 성공 기준: HTTP 응답 코드
200 ~ 299 - 실패 처리: 위 범위 외의 응답 코드, 타임아웃(30초), 네트워크 오류 등은 모두 실패로 간주됩니다.
- 5회 재시도까지 모두 실패하면 해당 배송은 최종 실패 처리됩니다.
- 모든 시도에 대한 배송 기록(HTTP 상태 코드, 응답 시간, 에러 메시지)은 30일간 보관됩니다.
웹훅 등록 제한
마스터당 최대 10개의 웹훅을 등록할 수 있습니다. 삭제된 웹훅은 개수에 포함되지 않으므로, 한도에 도달한 경우 사용하지 않는 웹훅을 삭제하면 새로 등록할 수 있습니다.
서명 검증 (선택사항)
웹훅 생성 시 Signing Secret이 자동 발급됩니다 (whsec_{32자 랜덤문자열} 형식). 서명 검증은 필수가 아니지만, 위조된 요청을 방지하기 위해 프로덕션 환경에서는 검증을 권장합니다.
각 웹훅 요청에는 다음 헤더가 포함됩니다.
| 헤더 | 설명 |
|---|---|
X-Webhook-Signature | sha256={HMAC-SHA256 서명값} |
X-Webhook-Timestamp | 요청 발송 시각 (Unix timestamp) |
| Content-Type | application/json |
검증 방법:
X-Webhook-Timestamp헤더에서 타임스탬프를 추출합니다.{타임스탬프}.{요청 body}형식으로 서명 대상 메시지를 만듭니다.- Signing Secret을 키로 사용하여 HMAC-SHA256 서명을 계산합니다.
- 계산된 서명과
X-Webhook-Signature헤더의 값을 비교합니다.
// 검증 예시 (Java)
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
public boolean verifyWebhook(String payload, String timestamp, String signature, String secret) {
String message = timestamp + "." + payload;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
byte[] hash = mac.doFinal(message.getBytes());
StringBuilder hex = new StringBuilder();
for (byte b : hash) {
hex.append(String.format("%02x", b));
}
String expected = "sha256=" + hex.toString();
return MessageDigest.isEqual(expected.getBytes(), signature.getBytes());
}
Secret 재발급
Secret 재발급 버튼을 클릭하면 새로운 Signing Secret이 발급됩니다. 기존 시크릿은 즉시 무효화되므로, 새 시크릿을 서버에 반영한 후 사용해야 합니다.
상태 관리
웹훅은 다음 상태를 가질 수 있습니다.
| 상태 | 설명 |
|---|---|
ACTIVE | 이벤트 발생 시 정상적으로 발송됩니다 |
INACTIVE | 이벤트 발송이 일시 중지됩니다 |
일시적으로 웹훅 수신을 중단하고 싶다면 비활성화할 수 있으며, 삭제하면 완전히 제거됩니다.