Kanorio는 사이트에서 주문 결제, 배송 업데이트, 양식 제출, 도메인 문제, 할당량 경고 또는 트래픽 마일스톤과 같은 특정 이벤트가 발생할 때 시스템에 실시간으로 알림을 보낼 수 있습니다. Zapier, Make, n8n 또는 자체 사용자 지정 코드에 연결하여 스프레드시트에 데이터를 자동으로 기록하거나, 팀 채팅 그룹으로 알림을 전달하거나, 지원 티켓을 생성하거나, ERP 또는 CRM과 동기화할 수 있습니다.
이 설정은 사이트 콘솔의 기술 설정 섹션 내 '통합' 탭에서 구성할 수 있습니다. Webhook은 비즈니스 플랜 기능이며, 사이트 소유자와 관리자만 추가하거나 관리할 수 있습니다. 다른 멤버는 URL, 보안 키 또는 전달 로그를 볼 수 없습니다.
사이트당 최대 5개의 Webhook을 추가할 수 있습니다.
각 엔드포인트를 확장한 후 '구독 이벤트'를 구성할 수 있습니다.
현재 지원되는 이벤트(필드 세부 정보는 끝부분의 '이벤트 참조' 참조):
| 이벤트 | 트리거 | 이벤트 코드 |
|---|---|---|
| 주문 결제 완료 | 구매자가 결제를 완료했을 때 | ec.order.paid |
| 배송 업데이트 | 상품이 발송, 매장 도착, 배송 완료되거나 예외가 발생했을 때 | ec.shipment.statusChanged |
| 양식 제출 | 방문자가 양식을 제출했을 때(질문 및 답변 포함) | customers.form.submitted |
| 발송 도메인 저하 | 발송 도메인 인증에 실패했을 때 | customers.sendingDomain.degraded |
| 메시징 할당량 경고 | 할당량 소진, 자동 충전, 한도 도달 또는 결제 실패 시 | customers.messagingQuota.alert |
Webhook 전달은 전적으로 이러한 구독 설정에 따라 달라집니다. 의 개별 시나리오 패널에 'N개 엔드포인트 구독 중' 또는 '연결되지 않음'으로 표시될 수 있지만, 실제 제어는 자동화가 아닌 여기서 이루어집니다.
Webhook은 알림 이메일을 대체하지 않습니다. Webhook을 추가한 후에도 소유자에게 전송되는 알림 이메일(예: 새 주문 및 양식 제출)은 계속 전송됩니다. 배송 업데이트에 대한 팀 이메일은 기본적으로 비활성화되어 있습니다. 팀 이메일을 전환하려면 '자동화'에서 구성하십시오.
엔드포인트를 확장하여 '최근 전달'을 확인하십시오: 이벤트, 결과, HTTP 상태 및 시간. 각 항목을 확장하여 시도 횟수, 지연 시간, 다음 재시도 시간 및 오류 이유를 볼 수 있습니다. 최근 7일 이내의 알림은 '보기'를 통해 페이로드를 확인하거나 '재전송'하여 다시 시도할 수 있습니다. 재전송은 동일한 전달 ID를 사용하므로 수신 측에서 중복 제거에 사용할 수 있습니다.
'테스트 보내기'는 실패 제한 횟수에 포함되지 않으므로 문제 해결을 위해 자유롭게 사용하십시오.
Kanorio는 고정 IP에서 Webhook을 전송합니다. 수신 측에서 화이트리스트 소스만 허용하는 경우, 다음 세 가지 IPv4 주소를 모두 추가하십시오(초기 전달, 테스트 및 수동 재전송은 처음 두 개에서, 자동 재시도는 세 번째에서 발생합니다).
| 목적 | IP |
|---|---|
| 초기 전달, 테스트, 수동 재전송 | <MAIN_EGRESS_IP_1> |
| 초기 전달, 테스트, 수동 재전송 | <MAIN_EGRESS_IP_2> |
| 자동 재시도 | 168.144.105.51 |
화이트리스트는 추가적인 보호 계층이며 서명 확인을 대체할 수 없습니다. 항상 X-Kanorio-Signature를 확인하십시오(아래 '엔지니어용' 참조). IP가 변경되어야 하는 경우, 여기서 공지하고 이전 IP와 새 IP를 일정 기간 동안 모두 실행한 후 이전 IP를 제거합니다.
아니요. Webhook은 Kanorio를 통해 이메일을 전송하지 않으며 이메일 할당량에 포함되지 않습니다.
엔드포인트로의 전달이 일시 중지됩니다. 설정과 키는 보존되며 목록은 '플랜 초과'로 표시됩니다. 비즈니스 플랜으로 다시 업그레이드하면 즉시 재개됩니다.
수신 측의 응답이 너무 느리거나 오류가 발생할 때 Kanorio가 재시도하기 때문입니다. 수동으로 재전송했을 수도 있습니다. X-Kanorio-Delivery(또는 JSON의 id)를 사용하여 이미 처리되었는지 확인하십시오.
현재는 Zapier나 Make를 통해 알림을 전달할 수 있습니다. Webhook을 사용하여 Kanorio 알림을 받은 다음 Slack 채널이나 LINE으로 보내십시오.
Webhook은 주문 및 양식 데이터를 Kanorio 외부 시스템으로 보내므로 URL과 서명 시크릿은 소유자와 관리자만 볼 수 있습니다. 다른 멤버는 엔드포인트 이름과 상태만 볼 수 있습니다.
별도의 샌드박스는 없습니다. '테스트 보내기'를 사용하여 연결을 확인하고 '콘텐츠 보기'를 통해 실제 이벤트 페이로드를 확인하십시오. 개발 중에는 엔드포인트를 webhook.site와 같은 서비스로 지정하여 형식을 관찰할 수 있습니다.
각 알림은 Content-Type: application/json 및 다음 헤더를 포함하는 POST 요청입니다.
| 헤더 | 내용 |
|---|---|
X-Kanorio-Event |
| 트래픽 마일스톤 | 누적 사이트 조회수가 100 또는 500을 넘었을 때 | site.analytics.milestone |
| 통합 일시 중지 | 연속 실패로 인해 Webhook이 일시 중지되었을 때(해당 엔드포인트로 전송되지 않음) | customers.teamDestination.disabled |
| 테스트 이벤트 | '테스트 보내기'를 클릭했을 때 | team.test |
이벤트 코드(JSON의 event와 동일) |
X-Kanorio-Delivery | 전달 ID(JSON의 id와 동일; 재시도 및 재전송 시 변경되지 않음) |
X-Kanorio-Signature | 서명(형식 t=timestamp,v1=signature; 키 교체 중에는 두 개의 v1 값이 존재할 수 있음) |
User-Agent | Kanorio-Notifications/1.0 |
수신 측의 2xx 응답은 성공으로 간주되며 응답 본문은 무시됩니다. 8초 이내에 응답하십시오. 더 긴 처리가 필요한 경우 먼저 200을 반환하고 비동기적으로 처리하십시오. Kanorio는 리디렉션을 따르지 않으며 3xx 응답은 실패로 처리됩니다.
모든 이벤트 JSON은 동일한 셸을 공유하므로 수신 측은 한 번만 구성하면 됩니다.
{ "version": "1", "id": "3f9c2a…", "event": "ec.order.paid", "occurredAt": "2026-09-29T12:00:00.000Z", "websiteId": "cmk…", "title": "New order #1024, NT$1,280", "summary": "'My Store' received a paid order.", "fields": [{ "label": "Order ID", "value": "#1024" }], "data": { "…": "Varies by event, see reference below" }, "actionUrl": "https://app.kanorio.com/store/transactions?tx=…" }
| 필드 | 유형 | 설명 |
|---|---|---|
version | string | 현재는 "1"입니다. 필드를 추가해도 버전은 변경되지 않으며, 필드 삭제나 이름 변경 시 버전이 올라가며 여기서 공지됩니다 |
id | string | 전달 ID(32자), X-Kanorio-Delivery와 동일합니다. 재시도/재전송 시 변경되지 않으며 중복 제거에 사용하십시오 |
event | string | 이벤트 코드, 위 표 참조 |
occurredAt | string | 이벤트 시간, ISO 8601(UTC) |
websiteId | string | 사이트 ID. 엔드포인트는 해당 사이트에서 생성된 이벤트만 수신합니다 |
title, summary | string | 채팅 전달을 위해 사이트 언어로 현지화된 한 줄의 제목 및 요약 |
fields | array | 사람이 읽을 수 있는 세부 정보(주문 ID, 금액, 양식 답변)의 { label, value } 배열. 라벨은 사이트 언어에 따라 변경되므로 프로그래밍 로직에는 data를 사용하십시오 |
data | object | 언어 독립적인 원시 이벤트 데이터. 이벤트별 필드는 아래 참조 |
actionUrl | string | null | 이 데이터를 보기 위한 Kanorio 대시보드 링크 |
다음은 각 이벤트의 data 필드입니다. 'Nullable'은 필드가 null일 수 있음을 의미합니다.
ec.order.paid 주문 결제 완료구매자가 결제를 완료했을 때 전송됩니다(주문당 1회).
| 필드 | 유형 | Nullable | 설명 |
|---|---|---|---|
orderId | string | 주문 ID(대시보드 URL의 ?tx=와 동일) | |
orderNumber | number | ✓ | 사람이 읽을 수 있는 주문 번호(예: 1024); 매우 오래된 주문에는 없을 수 있음 |
amount | number | 총 결제 금액(상품+배송비), 통화의 소수점 단위(ISO 4217): NT$1,280은 128000, US$12.80은 1280, JPY ¥1,280은 1280. 표시 금액으로 변환하려면 통화의 소수점 자릿수만큼 10의 거듭제곱으로 나누십시오 | |
currency | string | ISO 4217 대문자, 예: TWD, USD | |
itemCount | number | 상품 수 | |
customerName | string | ✓ | 구매자 이름 |
customerEmail | string | ✓ | 구매자 이메일 |
ec.shipment.statusChanged 배송 업데이트배송이 발송, 도착, 배송 완료 또는 예외 상태가 될 때 전송됩니다(배송당 상태 변경 시 1회).
| 필드 | 유형 | Nullable | 설명 |
|---|---|---|---|
orderId | string | 주문 ID | |
orderNumber | number | ✓ | 주문 번호 |
shipmentId | string | 배송 ID; 하나의 주문에 여러 배송이 있을 수 있음 | |
status | string | IN_TRANSIT(발송), AT_STORE(도착), DELIVERED(배송 완료), EXCEPTION(예외) | |
carrier | string | 물류 서비스 코드, 예: PAYUNI_LOGISTICS, MANUAL | |
trackingNumber | string | ✓ | 운송장 번호 |
storeName | string | ✓ | 편의점 이름; 택배는 null |
customers.form.submitted 양식 제출방문자가 양식을 제출하고 스팸 검사를 통과했을 때 전송됩니다(제출당 1회).
| 필드 | 유형 | Nullable | 설명 |
|---|---|---|---|
formId | string | 양식 ID | |
formName | string | 양식 이름 | |
submissionId | string | 제출 ID | |
submitter | object | { name, email, phone }, 각각 Nullable; 양식 필드에서 자동 식별됨 | |
answers | array | 질문당 객체 배열(아래 표 참조) |
answers[] 항목:
| 필드 | 유형 | 설명 |
|---|---|---|
fieldId | string | 질문 ID, 양식별 고정; label 대신 사용하십시오 |
type | string | 유형: short_text, long_text, email, phone, name, choice, date, time, rating, file |
label | string | 질문 텍스트 |
value | string | string[] | number | null | 원시 답변. 단일 선택은 문자열, 다중 선택은 문자열 배열, 평점은 숫자, 날짜/시간은 문자열(YYYY-MM-DD, HH:mm), 파일은 파일 ID; 비어 있으면 null |
display | string | 사람이 읽을 수 있는 문자열, fields와 동일; 파일 질문의 경우 파일 이름 |
customers.sendingDomain.degraded 발송 도메인 저하인증된 사용자 지정 발송 도메인의 인증이 실패했을 때 전송됩니다(도메인당 하루 1회).
| 필드 | 유형 | 설명 |
|---|---|---|
domain | string | 저하된 도메인 |
customers.messagingQuota.alert 메시징 할당량 경고할당량 상태가 변경될 때 전송됩니다.
| 필드 | 유형 | 설명 |
|---|---|---|
reason | string | exhausted, auto_upgraded, auto_upgrade_limit, payment_failed |
quota | number | 현재 기간 할당량 |
levels | number | 현재 자동 업그레이드 레벨 |
periodStart | string | 기간 시작 시간, ISO 8601 |
site.analytics.milestone 트래픽 마일스톤누적 사이트 조회수가 마일스톤을 넘을 때 전송됩니다(마일스톤당 1회).
| 필드 | 유형 | 설명 |
|---|---|---|
milestone | number | 100 또는 500 |
customers.teamDestination.disabled 통합 일시 중지Webhook 엔드포인트가 자동으로 일시 중지될 때 전송됩니다(연속 실패 또는 410 응답). 다른 정상적인 엔드포인트에만 전송됩니다.
| 필드 | 유형 | 설명 |
|---|---|---|
destinationId | string | 일시 중지된 엔드포인트 ID |
failures | number | 연속 실패 횟수 |
lastError | string | 마지막 오류, 예: HTTP 503, 타임아웃 |
team.test 테스트 이벤트'테스트 보내기'가 클릭될 때 전송됩니다(1회, 재시도 없음, 전달 기록에 기록되지 않음).
확인 단계:
X-Kanorio-Signature에서 t와 모든 v1을 추출합니다.t, 마침표, 원시 요청 본문(파싱되지 않고 재직렬화된 상태)을 연결합니다(예: 1790000000.{"version":"1",…}).v1과 비교합니다. 일치하는 경우에만 수락하십시오.Node.js 예시:
import { createHmac, timingSafeEqual } from "node:crypto"; function verify(rawBody, header, secret) { const parts = header.split(",").map((part) => part.split("=")); const t = parts.find(([key]) => key === "t")?.[1]; const signatures = parts.filter(([key]) => key === "v1").map(([, value]) => value); if (!t || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"); return signatures.some( (v1) => v1.length === expected.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1)) ); }
Zapier, Make, n8n과 같은 서비스는 일반적으로 사용자 지정 확인 로직을 지원하지 않으며, 수신 URL에 임의의 경로가 포함되어 있으므로 확인은 일반적으로 필요하지 않습니다.
시크릿은 통합 목록에서 엔드포인트를 확장하고 '보기'를 클릭하여 확인할 수 있습니다. 유출이 의심되면 '새 시크릿 생성'을 클릭하십시오:
v1), 하나라도 일치하면 충분합니다.