알림톡 발송·운영

알림톡 웹훅 설정

발송 성공·실패와 검수 결과를 서버로 받아요. 주문 웹훅과 완전히 별개예요.

발송 결과를 폴링하지 않고 받으려면 웹훅을 걸어요. 수신 URL 과 구독할 이벤트를 지정하면 상태가 확정될 때 부트페이가 요청을 보내요.

주문·구독 통합 웹훅과 별개예요

알림톡 웹훅은 전용 수신 URL 을 따로 둬요. 주문 웹훅 URL 에 알림톡 이벤트를 태우면 그 수신 서버가 모르는 payload 를 받게 되어 기존 연동이 깨져요. 반드시 별도 엔드포인트를 준비해요.

발송마다 다른 주소로 받을 수도 있어요

발송 요청에 webhook_url 을 실으면 그 건의 발송 성공·실패·예약취소 웹훅은 그 주소로만 가고 이 설정은 쓰이지 않아요. 이 설정을 꺼 두었거나 그 이벤트를 구독하지 않았더라도 보내요.

상황 웹훅이 가는 곳
발송 요청에 webhook_url 있음 그 주소로만 (발송 결과·예약취소)
없음 이 설정의 수신 URL (구독·켜짐 판정 그대로)
템플릿 검수 결과·발송 제외 등록 언제나 이 설정의 수신 URL

발송마다 주소를 지정해서 쓴다면 수신 URL 을 저장하지 않아도 돼요. 이때 서명 검증용 시크릿은 시크릿 재발급으로 설정 없이도 받을 수 있고, 설정 조회는 configured: false 로 나와요.

1설정 조회

GEThttps://message.bootapi.com/alimtalk/webhookBasic Auth

코드 예제

curl -X GET "https://message.bootapi.com/alimtalk/webhook" \
  -H "Authorization: Basic {base64(client_key:secret_key)}"bash

응답

아직 설정하지 않았다면 configured: false 만 내려와요.

{
  "configured": true,
  "url": "https://example.com/hooks/alimtalk",
  "events": [301, 302, 303, 310, 311],
  "enabled": true,
  "secret": "whsec_1a2b3c********",
  "last_sent_at": "2026-08-27T10:00:05+09:00",
  "last_status": 200,
  "consecutive_failures": 0,
  "auto_disabled_at": null,
  "retry_count": 10
}json

retry_count 는 수신 서버가 2xx 를 돌려주지 않을 때 건마다 최대 몇 번까지 보낼지​​예요(첫 전송 포함, 기본 10). 아래 2. 설정 저장​​에서 바꿀 수 있어요.

시크릿은 앞 12자만 보여요. 원문은 시크릿 재발급 응답에서만 볼 수 있어요. 시각 필드 형식은 응답의 시각 형식을 봐요.

2설정 저장

PUThttps://message.bootapi.com/alimtalk/webhookBasic Auth

요청 파라미터

파라미터 타입 필수 설명
url String 선택 수신 URL. https 만 허용해요
events Array 선택 구독할 이벤트 코드. 처음 저장할 때 생략하면 기본 구독셋이 적용돼요. 빈 배열 [] 은 무시되고 기존 구독이 유지되니, 기본셋으로 되돌리려면 그 코드들을 직접 보내요
enabled Boolean 선택 활성 여부
retry_count Integer 선택 건별 재시도 횟수. 1~25 사이로 지정해요(기본 10). 생략하면 기존 값이 유지돼요

최초 저장 시 서명 시크릿이 자동 발급돼요.

retry_count 는 저장한 뒤 새로 만들어지는 전송 건​​부터 적용돼요. 이미 큐에 있는 건은 만들어질 때의 횟수를 따라요.

이벤트 코드 (events)

events 배열에 넣는 값이에요. enum 키가 아니라 숫자 그대로 주고받아요.

코드 본문의 event 이벤트 기본 구독
300 alimtalk.send.requested 발송 접수 미구독
301 alimtalk.send.succeeded 전달 성공 구독
302 alimtalk.send.failed 전달 실패 구독
303 alimtalk.send.canceled 예약 취소 구독
310 alimtalk.template.approved 검수 승인 구독
311 alimtalk.template.rejected 검수 반려 구독
320 alimtalk.optout.registered 발송 제외 목록 등록 미구독
보낼 때는 숫자, 받을 때는 문자열이에요

events 배열에는 숫자​​를 넣지만, 수신 서버가 받는 본문의 event 와 X-Bootpay-Webhook-Event 헤더에는 위 문자열​​이 담겨요. 숫자도 event_code 로 함께 와요.

접수(300)와 발송 제외 등록(320)은 건당 발화라 노이즈가 커서 명시적으로 구독해야만 발송돼요. 목록에 없는 값은 저장할 때 조용히 버려져요.

알려진 문제 — 발송 접수(300) 이벤트가 오지 않아요

지금은 300 을 구독해도 이 이벤트가 발송되지 않아요. 접수 여부는 발송 API 응답의 status: "requested" 로 판단하고, 확정 결과는 301·302 로 받아요.

코드 예제

curl -X PUT "https://message.bootapi.com/alimtalk/webhook" \
  -H "Authorization: Basic {base64(client_key:secret_key)}" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/alimtalk",
    "events": [301, 302, 303, 310, 311],
    "enabled": true,
    "retry_count": 5
  }'bash

서명 검증

요청에 아래 헤더가 붙어요.

X-Bootpay-Webhook-Event: alimtalk.send.succeeded
X-Bootpay-Delivery-Id: 68b0f2a1c3d4e5f6a7b8c9e1
X-Bootpay-Timestamp: 1756272000
X-Bootpay-Signature: sha256=HMAC_SHA256(secret, "{X-Bootpay-Timestamp}.{raw_body}")

수신 서버에서 같은 방식으로 계산해 비교하고, 타임스탬프가 5분 이상 지난 요청은 거부​​해요(replay 방지). 서명은 파싱하기 전 원본 본문(raw body) 으로 계산해요. sha256= 뒤의 값은 HMAC-SHA256 결과를 소문자 16진수(hex)로 적은 것이에요. X-Bootpay-Delivery-Id 는 전송 이력의 delivery_id 와 같아요.

payload

본문은 아래 봉투에 이벤트별 data 가 담긴 모양이에요.

필드 타입 설명
event String 이벤트 별칭 (예: alimtalk.send.succeeded)
event_code Integer 이벤트 코드 (예: 301)
occurred_at String 발생 시각 (ISO8601)
data Object 이벤트별 본문 (아래)

발송 이벤트(301·302·303)의 data 는 발송내역 목록의 항목과 같은 카드예요. 그래서 조회·목록·웹훅을 파서 하나로 처리할 수 있어요. 다만 시각 필드는 웹훅에서 ISO8601 로 와서 REST 응답과 형식이 달라요 — 응답의 시각 형식을 봐요.

검수 이벤트(310·311)의 data 예요.

필드 타입 설명
template_code String 템플릿 코드
name String 템플릿 이름
inspection_status Integer 검수 상태 숫자 (3 승인 · 4 등록 거절 · 5 승인 반려). REST 응답의 "approved" 같은 키가 아니라 숫자로 와요
vendor_status Integer 등록 상태 (0 등록전 · 1 대기 · 2 정상 · 3 중단)
comments Array 검수 반려 사유
synced_at String 마지막으로 상태를 맞춘 시각

발송 제외 등록 이벤트(320)의 data 예요.

필드 타입 설명
phone String 제외 등록된 번호 (숫자만)
scope Integer 2 프로젝트
source Integer 등록 경로 (1 랜딩 · 2 API · 3 관리자 · 4 신고)
reason String 사유
opted_out_at String 등록 시각

자동 비활성

연속 실패가 10회(기본값)에 이르면 웹훅이 자동으로 비활성화​​돼요. 죽은 URL 로 영원히 재시도하지 않기 위해서예요. 실패는 수신 서버가 2xx 가 아닌 HTTP 응답을 돌려준 경우만 세고, 재시도도 한 번씩 세요. 연결 실패·타임아웃처럼 응답 자체가 없으면 세지 않아서 자동 비활성이 걸리지 않아요.

auto_disabled_at 에 시각이 찍히고, URL 을 고쳐 다시 저장하면 실패 카운터와 auto_disabled_at 이 초기화돼요. 이때 enabled 는 false 로 남으니 다시 받으려면 enabled: true 를 함께 보내요.

발송 요청에 실은 webhook_url 의 실패는 이 카운터에 들어가지 않아요. 그 주소가 죽어 있어도 여기 저장한 수신 URL 은 그대로 살아 있어요(주소가 서로 같을 때만 함께 세요). 대신 건별 주소에는 자동 비활성이 없으니, 주소를 바꿀 때는 발송 요청 쪽을 고쳐요.

에러 코드

코드 error_code 메시지 대처 방법
3028 WEBHOOK_URL_INVALID 웹훅 URL 형식 오류 https:// 로 시작하는 URL 인지 확인해요
11304 WEBHOOK_RETRY_COUNT_INVALID 웹훅 재시도는 최소 1회부터 최대 25회까지 설정이 가능합니다 retry_count 를 1~25 사이 정수로 보내요

다음 단계

설정을 마쳤다면 테스트 발송으로 수신 서버가 제대로 받는지 확인해요.