웹훅

실시간 이벤트 알림을 수신하는 웹훅을 설정합니다.

웹훅

웹훅을 사용하여 예약 상태 변경, 재고 업데이트 등의 이벤트를 실시간으로 수신할 수 있습니다.

웹훅 개요#

웹훅은 특정 이벤트가 발생했을 때 ONDA가 귀사의 서버로 HTTP POST 요청을 보내는 방식입니다. 주기적으로 API를 호출하여 변경사항을 확인하는 대신, 이벤트 발생 즉시 알림을 받을 수 있습니다.

웹훅 vs 폴링#

방식장점단점
웹훅실시간, API 호출 절감, 효율적서버 엔드포인트 필요
폴링구현 간단API 호출 증가, 지연 발생

권장: 실시간성이 중요한 예약/재고 업데이트는 웹훅, 참고용 통계는 폴링

이벤트 타입#

예약 이벤트#

이벤트설명발생 시점
reservation.created예약 생성됨예약 API 호출 성공
reservation.confirmed예약 확정됨결제 완료 또는 호텔 승인
reservation.modified예약 수정됨날짜, 투숙객 정보 변경
reservation.cancelled예약 취소됨고객 또는 호텔이 취소
reservation.checked_in체크인 완료호텔에서 체크인 처리
reservation.checked_out체크아웃 완료호텔에서 체크아웃 처리
reservation.no_show노쇼 발생고객 미도착으로 판단

재고 이벤트#

이벤트설명발생 시점
inventory.updated재고 변경됨숙소의 빈방 수량 변경
inventory.closed재고 마감됨특정 날짜 판매 중단
inventory.opened재고 오픈됨마감된 날짜 재오픈

콘텐츠 이벤트#

이벤트설명발생 시점
property.created숙소 추가됨새 숙소 등록
property.updated숙소 정보 변경숙소 정보 수정
property.deleted숙소 삭제됨숙소 운영 중단
roomtype.updated객실 정보 변경객실 정보 수정
rateplan.updated패키지 정보 변경패키지 정책 수정

가격 이벤트#

이벤트설명발생 시점
rate.updated가격 변경됨요금 조정
special_offer.created특가 생성됨프로모션 시작
special_offer.expired특가 종료됨프로모션 종료

웹훅 설정 프로세스#

엔드포인트 구현

귀사 서버에 웹훅을 수신할 HTTPS 엔드포인트를 구현합니다.

웹훅 등록

ONDA API를 통해 웹훅 URL과 수신할 이벤트 타입을 등록합니다.

서명 검증

수신한 웹훅이 ONDA에서 발송한 것인지 서명(HMAC SHA256)을 검증합니다.

이벤트 처리

이벤트 타입에 따라 비즈니스 로직을 실행합니다.

서명 검증#

웹훅 요청이 실제로 ONDA에서 발송된 것인지 확인하려면 서명을 검증해야 합니다.

검증 프로세스#

  1. 요청 헤더에서 X-ONDA-Signature 추출
  2. 요청 본문(raw JSON)과 webhook secret으로 HMAC SHA256 해시 생성
  3. 생성한 해시와 헤더의 서명 비교

간단한 검증 예시 (Python)#

import hmac
import hashlib

def verify_webhook_signature(payload_bytes, signature, secret):
    """웹훅 서명 검증"""
    expected = hmac.new(
        secret.encode('utf-8'),
        payload_bytes,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(expected, signature)

# 사용 예시
signature = request.headers.get("X-ONDA-Signature")
if not verify_webhook_signature(request.data, signature, WEBHOOK_SECRET):
    return {"error": "Invalid signature"}, 401

보안 필수: 모든 웹훅 요청의 서명을 검증하세요. 검증하지 않으면 악의적인 요청에 노출될 수 있습니다.

웹훅 이벤트 구조#

모든 웹훅 이벤트는 다음 구조를 따릅니다:

{
  "id": "evt_abc123",
  "event": "reservation.created",
  "timestamp": "2026-02-08T10:30:00Z",
  "api_version": "v1",
  "data": {
    // 이벤트별 데이터
  }
}

공통 필드:

  • id: 이벤트 고유 ID (중복 처리 방지용)
  • event: 이벤트 타입
  • timestamp: 발생 시각 (ISO 8601)
  • api_version: API 버전
  • data: 이벤트별 페이로드

재시도 정책#

웹훅 전송이 실패하면 ONDA는 자동으로 재시도합니다.

재시도 스케줄#

시도대기 시간누적 시간
1차즉시0분
2차5분 후5분
3차15분 후20분
4차1시간 후1시간 20분
5차3시간 후4시간 20분
6차6시간 후10시간 20분

성공 조건#

다음 조건을 모두 만족하면 성공으로 간주합니다:

  • HTTP 상태 코드: 200-299
  • 응답 시간: 5초 이내
  • 응답 본문: 유효한 JSON (옵션)

실패 처리#

6번의 재시도 후에도 실패하면:

  1. 웹훅 상태가 failing으로 변경됨
  2. 관리자에게 이메일 알림 발송
  3. 24시간 후 자동으로 disabled 상태로 변경

실패한 이벤트는 웹훅 전송 로그 API를 통해 조회하고 수동으로 재전송할 수 있습니다.

멱등성 처리#

네트워크 문제로 동일한 이벤트가 여러 번 전송될 수 있습니다. 멱등성을 보장하세요.

중복 방지 전략#

  1. 이벤트 ID 저장: 처리한 이벤트 ID를 DB에 저장
  2. 중복 확인: 새 이벤트 수신 시 ID 존재 여부 확인
  3. 건너뛰기: 이미 처리한 이벤트는 무시

권장 구현 패턴#

웹훅 관리#

웹훅 상태#

상태의미조치
active정상 작동 중없음
failing연속 실패 중엔드포인트 점검
disabled비활성화됨재활성화 필요
paused일시 중지수동 중지 상태

일반적인 관리 작업#

  • 웹훅 목록 조회: 등록된 웹훅 확인
  • 웹훅 수정: 이벤트 타입 추가/제거
  • 웹훅 삭제: 더 이상 사용하지 않는 웹훅 제거
  • 일시 중지/재개: 유지보수 시 일시적으로 중지
  • 전송 로그 조회: 성공/실패 이력 확인
  • 수동 재전송: 실패한 이벤트 다시 보내기

상세한 관리 방법은 API 레퍼런스를 참고하세요.

디버깅 팁#

1. 로깅#

모든 웹훅 요청을 로깅하세요:

  • 요청 헤더 (서명 포함)
  • 요청 본문 (이벤트 데이터)
  • 처리 결과 (성공/실패)
  • 에러 메시지

2. 웹훅 전송 로그 조회#

ONDA에서 발송한 웹훅 로그를 API로 조회하여 디버깅할 수 있습니다:

  • 어떤 이벤트를 언제 보냈는지
  • 귀사 서버가 어떤 응답을 했는지
  • 재시도 이력

3. 테스트 이벤트#

개발 중에는 테스트 이벤트를 수동으로 발송하여 엔드포인트를 테스트할 수 있습니다.

4. 로컬 개발#

로컬 환경에서 테스트하려면 ngrok 등의 터널링 도구를 사용하세요:

# ngrok 실행
ngrok http 3000

# 생성된 URL을 웹훅 URL로 등록
# 예: https://abc123.ngrok.io/webhooks/onda

보안 권장사항#

  1. HTTPS 필수: 웹훅 URL은 HTTPS만 허용됩니다
  2. 서명 검증: 모든 요청의 서명을 검증하세요
  3. IP 화이트리스트: ONDA의 발신 IP만 허용하세요
    • 52.78.123.45
    • 13.125.67.89
  4. Secret 보호: 웹훅 secret을 안전하게 저장하세요
  5. Rate Limiting: 과도한 요청을 방지하세요
  6. 타임아웃: 5초 이내에 응답하세요 (내부 처리는 비동기로)

무거운 처리는 큐(Queue)에 넣고 비동기로 처리하세요. 웹훅 응답은 5초 이내에 반환해야 합니다.

활용 사례#

예약 알림#

  • reservation.created → 고객에게 확인 이메일 발송
  • reservation.confirmed → 예약 확인서 생성 및 발송
  • reservation.cancelled → 취소 확인 및 환불 안내

재고 동기화#

  • inventory.updated → 검색 캐시 무효화
  • inventory.closed → 해당 날짜 검색 결과에서 제외
  • inventory.opened → 검색 가능하도록 재활성화

콘텐츠 업데이트#

  • property.updated → 해당 숙소 정보 재조회 및 DB 업데이트
  • roomtype.updated → 객실 정보 갱신
  • rateplan.updated → 패키지 정책 갱신

다음 단계#