본문으로 건너뛰기

웹훅(WebHook) 연동 가이드

📘 개발 가이드

웹훅(WebHook) 연동 가이드

쇼핑몰에서 주문, 상품, 게시판 등의 이벤트가 발생하면 등록한 URL로 이벤트 정보를 바로 전달받을 수 있습니다. 웹훅 등록 방법과 수신 조건, 메시지 형식, 제공 이벤트 목록을 안내합니다.

⚠️
웹훅 이용 전 확인해 주세요
  • 웹훅은 통합옵션 · 주문2.0 · UTF-8 쇼핑몰에서만 지원됩니다.
  • APP에 등록된 API 권한에 해당하는 이벤트만 수신할 수 있습니다.
  • 쇼핑몰 운영자가 APP 설치 시 웹훅 정보 제공에 동의해야 이벤트가 전송됩니다.
  • 서비스 이용에 필수적인 웹훅만 등록해 주세요. 수신한 정보의 관리 및 이용에 대한 책임은 파트너에게 있습니다.

웹훅 동작 방식​

웹훅을 사용하면 API를 주기적으로 호출(폴링)하지 않아도 쇼핑몰의 상태 변경을 바로 알 수 있습니다. 이벤트가 발생하면 메이크샵이 파트너가 등록한 수신 URL로 이벤트 정보를 POST 요청으로 전송합니다.

1
파트너가 웹훅 등록

파트너센터 APP 상세에서 수신할 이벤트와 수신 URL을 등록합니다.

2
쇼핑몰 운영자가 APP 설치 및 동의

샵스토어에서 APP을 설치할 때 웹훅 정보 제공 동의 안내가 함께 노출됩니다.

3
쇼핑몰에서 이벤트 발생

주문 생성, 상품 수정, 후기 등록 등 등록한 이벤트가 발생합니다.

4
수신 URL로 이벤트 전송

수신 조건을 모두 충족한 경우에만 파트너 수신 서버로 이벤트 정보가 전송됩니다.

이벤트 수신 조건​

아래 조건을 모두 충족해야 이벤트가 전송됩니다. 하나라도 충족하지 않으면 웹훅이 등록되어 있어도 전송되지 않습니다.

조건설명
API 권한 보유이벤트와 같은 분류의 API 권한이 APP에 등록되어 있어야 합니다. 예를 들어 ORDER_CREATED를 수신하려면 주문 권한이 필요합니다.
웹훅 활성 상태웹훅의 수신여부가 활성으로 설정되어 있어야 합니다.
운영자 동의쇼핑몰 운영자가 APP 설치 또는 업데이트 시 웹훅 정보 제공에 동의해야 합니다.
지원 쇼핑몰통합옵션 · 주문2.0 · UTF-8 쇼핑몰이어야 합니다.

쇼핑몰 운영자 동의 안내​

APP의 API 권한과 웹훅 이벤트가 하나 이상 일치하면, 샵스토어 상품 상세 > 설치하기 > 서비스 이용동의 팝업에 웹훅 정보 제공 동의 안내가 노출됩니다. 안내에는 API 권한과 웹훅이 모두 일치하는 이벤트만 표시되며, 운영자가 설치를 진행하면 동의한 것으로 처리됩니다.

참고 화면 — 샵스토어 서비스 이용동의 팝업
샵스토어 APP 설치 시 노출되는 웹훅 정보 제공 동의 안내

웹훅 등록하기​

웹훅은 파트너센터 App 목록 > 상세 > 개발 정보 탭의 WebHook 정보 영역에서 등록합니다.

1
API 권한 저장

수신할 이벤트에 해당하는 API 권한을 먼저 추가하고 APP을 저장합니다. APP을 한 번 이상 저장해야 웹훅을 등록할 수 있습니다.

2
등록 버튼 클릭

WebHook 정보 영역의 등록 버튼을 클릭하면 WebHook 등록 팝업이 열립니다.

3
이벤트, 수신 URL, 수신여부 입력

이벤트 분류와 수신할 이벤트를 선택하고, 수신 URL을 입력한 뒤 수신여부(활성/비활성)를 선택합니다.

4
저장

저장하면 등록한 웹훅이 목록에 추가됩니다.

⚠️
필수 웹훅만 등록해 주세요

서비스 이용에 필수적인 웹훅만 등록해 주세요. 수신한 정보의 관리 및 이용에 대한 책임은 파트너에게 있습니다.

참고 화면 — WebHook 등록 팝업
이벤트, 수신 URL, 수신여부를 입력하는 WebHook 등록 팝업

입력 항목​

항목필수설명
이벤트필수분류를 선택한 뒤 수신할 이벤트를 선택합니다. APP의 API 권한에 해당하는 이벤트만 선택할 수 있습니다.
수신 URL필수이벤트를 수신할 URL입니다. https 형식만 등록할 수 있으며, IP 주소나 포트 번호는 입력할 수 없습니다.
수신여부필수활성으로 설정한 웹훅만 이벤트가 전송됩니다.
💡
"등록하려는 이벤트에 해당하는 API 권한이 없습니다" 안내가 나타나는 경우

선택한 이벤트 분류의 API 권한이 APP에 없을 때 나타납니다. 개발 정보 탭에서 해당 분류의 API 권한을 추가하고 저장한 뒤 다시 등록해 주세요. 이벤트별 필요 권한은 제공 이벤트 목록에서 확인할 수 있으며, 파트너센터의 전체 이벤트 및 권한 안내 버튼으로도 확인할 수 있습니다.

수신 서버 준비​

발송 서버 IP 허용​

수신 서버에 방화벽이나 접근 제어를 적용하고 있다면, 아래 메이크샵 웹훅 발송 서버의 IP를 허용해 주세요. 허용되지 않으면 이벤트를 수신할 수 없습니다.

구분IPPort
WebHook 발송 서버14.129.76.217443 (HTTPS)

수신 URL 요구사항​

  • 유효한 SSL 인증서가 적용된 https URL이어야 합니다.
  • 도메인 기반 URL만 등록할 수 있습니다. 예: https://example.com/webhook
  • POST 요청과 application/json 본문을 처리할 수 있어야 합니다.

테스트 전송​

실제 이벤트가 발생하기 전에 수신 서버가 정상적으로 동작하는지 확인할 수 있습니다. 등록된 웹훅 목록에서 TEST 버튼을 클릭하고 전송을 누르면 해당 이벤트 형식의 샘플 데이터가 수신 URL로 전송됩니다.

참고 화면 — WebHook TEST 팝업
샘플 데이터를 확인하고 전송하는 WebHook TEST 팝업
  • TEST 버튼은 APP을 한 번 이상 저장한 뒤 사용할 수 있습니다.
  • 테스트로 전송되는 데이터는 실제 데이터와 다를 수 있습니다.
  • 전송 결과는 화면 알림으로 확인할 수 있고, 전송내역에 테스트 구분으로 기록됩니다.

전송내역 조회 및 재전송​

WebHook 정보 영역의 전송내역 버튼을 클릭하면 웹훅 전송 결과를 조회하고, 실패한 건을 다시 전송할 수 있습니다.

참고 화면 — WebHook 전송내역 팝업
전송일, 구분, 상태, 이벤트로 검색하는 WebHook 전송내역 팝업
검색 항목설명
전송일조회할 기간을 지정합니다. 최대 1개월까지 선택할 수 있습니다.
구분실시간(실제 이벤트), 테스트(TEST 버튼 전송), 실시간(재전송)(재전송한 건)
상태성공, 실패, 대기중, 전송중
이벤트특정 이벤트의 전송 결과만 조회합니다.
검색어쇼핑몰 ID 또는 WebHook ID로 검색합니다.

메시지 형식과 서명 검증​

요청 본문​

이벤트 정보는 JSON 형식으로 전송됩니다. 아래는 앱 삭제(APP_DELETED) 이벤트의 예시입니다.

요청 본문 예시
{
"id": "id",
"event_type": "APP_DELETED",
"shop_id": "testshop",
"occurred_at": "2026-06-10 20:00:00",
"data": {
"deleted_date": "2026-06-10 20:00:00"
}
}
필드타입설명
idString이벤트 ID (ex.evt_d509d7a1b8894c51b00cb9d8)
event_typeString이벤트 타입
shop_idString이벤트 발생한 쇼핑몰 ID
occurred_atDateTime이벤트 발생 시각
sequenceInteger이벤트 순번 (APP_* 이벤트에는 제외 / ex. 1792300501312416)
dataObjectpayload data
data.deleted_dateDateTimeAPP 삭제 시각

이벤트별 data 상세 필드는 API 문서를 참고해 주세요.

인증 정보와 서명 검증​

개발 정보 탭의 인증 정보는 메이크샵에서 보낸 것인지 확인하는 데 사용합니다. 수신 서버에서는 서명을 검증한 뒤 요청을 처리해 주세요.

요청 헤더설명
webhook-id메시지 고유 ID. 재전송 시에도 같은 값이 유지되어 중복 처리 방지에 사용할 수 있습니다.
webhook-timestamp전송 시각(Unix timestamp, 초)
webhook-signature요청 서명. v1, 접두사 뒤에 Base64 인코딩된 서명이 붙습니다.
x-client-idApp Client ID

서명은 {webhook-id}.{webhook-timestamp}.{요청 본문} 문자열을 인증 정보로 HMAC-SHA256 계산한 값입니다. 인증 정보가 whsec_로 시작하면 접두사를 제외한 나머지를 Base64 디코딩하여 키로 사용합니다. webhook-signature에는 공백으로 구분된 여러 서명이 올 수 있으며(인증 정보 재발급 직후 등), 그중 하나라도 일치하면 유효한 요청입니다. 요청 본문은 수신한 원문 그대로 사용하고, webhook-timestamp가 현재 시각과 5분 이상 차이 나면 거부하는 것을 권장합니다.

서명 검증 예시 (Node.js)
const crypto = require('crypto');
// secret: 앱 인증정보 whsec_... (앱당 1개)
// headers: 소문자 키 헤더 맵 (Node http/Express는 기본으로 소문자)
// rawBody: 수신한 원본 body (파싱 전 Buffer 또는 문자열)
function verify(rawBody, headers, secret) {
const id = headers['webhook-id'];
const timestamp = headers['webhook-timestamp'];
const signatureHeader = headers['webhook-signature']; // "v1,xxx v1,yyy"

// 필수 헤더가 하나라도 없으면 거부합니다.
if (!id || !timestamp || !signatureHeader) return false;

// 5분 이상 차이 나는 요청은 거부해 재전송 공격을 막습니다.
// 숫자가 아닌 값(NaN)도 여기서 걸러집니다.
const ts = Number(timestamp);
if (!Number.isFinite(ts) || Math.abs(Date.now() / 1000 - ts) > 300) return false;

const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
const expected = crypto
.createHmac('sha256', key)
.update(`${id}.${timestamp}.${rawBody}`)
.digest('base64');
const expectedBuf = Buffer.from(expected);

// v1 서명 중 하나라도 일치하면 통과합니다 (timing-safe 비교).
return signatureHeader
.split(' ')
.filter((part) => part.startsWith('v1,'))
.map((part) => Buffer.from(part.slice(3)))
.some((sig) => sig.length === expectedBuf.length && crypto.timingSafeEqual(sig, expectedBuf));
}

// 사용 예 (Express)
// body를 파싱하지 않은 원본 그대로 받아야 서명이 맞습니다.
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
if (!verify(req.body, req.headers, process.env.WEBHOOK_SECRET)) {
return res.status(401).end();
}
const event = JSON.parse(req.body);
// ... Webhook-Id로 중복 확인 후 처리
res.status(200).end();
});
⚠️
인증 정보 관리 주의

인증 정보가 유출되어 발생하는 데이터 노출, 시스템 부정 사용 등의 모든 책임은 파트너에게 있습니다. 인증 정보는 서버 환경 변수 등 안전한 곳에 보관해 주세요. 재발급은 키가 유출되었거나 인증에 장애가 생긴 경우에만 사용해 주세요. 재발급 후 일정 시간 동안은 기존 키와 새 키 서명이 함께 전송되므로, 그 안에 수신 서버의 키를 새 키로 교체해 주세요.

응답 및 재시도 정책​

이벤트를 정상 수신했다면 수신 서버는 HTTP 2xx 상태 코드로 응답해야 합니다. 2xx 이외의 응답을 보내거나 제한 시간 안에 응답하지 않으면 전송 실패로 처리되고, 일정 간격으로 다시 전송합니다.

시도직전 시도 이후 대기 시간
1회차즉시
2회차5초
3회차1분
4회차5분
5회차30분

모든 재시도에 실패한 건은 전송내역에서 상태를 확인하고 직접 재전송할 수 있습니다.

권장 구현 방식​

  • 먼저 응답하고 나중에 처리하세요. 요청을 받으면 바로 2xx로 응답하고, 실제 처리는 큐 등을 이용해 비동기로 진행하는 것을 권장합니다. 처리 시간이 길어지면 타임아웃으로 실패 처리되어 같은 이벤트가 다시 전송될 수 있습니다.
  • 중복 수신에 대비하세요. 재시도나 재전송으로 같은 이벤트가 두 번 이상 도착할 수 있습니다. WebHook ID를 저장해 두고 이미 처리한 이벤트는 건너뛰도록 구현해 주세요.
  • 전송 순서에 의존하지 마세요. 이벤트가 발생 순서대로 도착한다는 보장은 없습니다. 최신 상태가 필요하면 이벤트 수신 후 API로 다시 조회해 주세요.

제공 이벤트 목록​

현재 제공되는 이벤트는 총 22종입니다. 모든 이벤트는 해당 분류의 Read 권한이 있으면 수신할 수 있습니다.

분류이벤트 코드이벤트명필요 권한
앱APP_DELETED앱 삭제Read
APP_EXPIRED앱 만료Read
APP_EXPIRY_EXTENDED앱 만료 연장Read
주문ORDER_CREATED주문 생성Read
ORDER_CANCELED주문 취소Read
ORDER_PAID주문 입금 완료Read
ORDER_RETURNED주문 반품Read
ORDER_EXCHANGED주문 교환Read
ORDER_REFUNDED주문 환불Read
ORDER_TRACKING_CHANGED주문 운송장 변경Read
상품PRODUCT_CREATED상품 생성Read
PRODUCT_DELETED상품 삭제Read
PRODUCT_UPDATED상품 수정Read
PRODUCT_OPTION_UPDATED상품 옵션 수정Read
PRODUCT_STOCK_UPDATED상품 재고 수정Read
PRODUCT_CATEGORY_CREATED상품 분류 추가Read
PRODUCT_CATEGORY_UPDATED상품 분류 수정Read
PRODUCT_CATEGORY_DELETED상품 분류 삭제Read
회원CART_ITEM_ADDED장바구니 상품 담기Read
게시판REVIEW_CREATED코멘트평점 후기 등록Read
REVIEW_UPDATED코멘트평점 후기 수정Read
REVIEW_DELETED코멘트평점 후기 삭제Read
📌
추후 제공 예정 이벤트

앱 결제(APP_PAID), 앱 환불 요청(APP_REFUND_REQUESTED), 앱 환불 완료(APP_REFUND_COMPLETED) 이벤트는 샵스토어 결제 기능 오픈 시점에 제공될 예정입니다.

웹훅 수정 · 삭제​

작업안내
웹훅 수정APP 심사 상태와 관계없이 언제든 수정할 수 있으며, 수정해도 재심사는 진행되지 않습니다.
이벤트 추가새 이벤트를 추가하고 저장하면, 이미 APP을 설치한 쇼핑몰의 샵스토어 마이페이지 > 설치내역 > 연동관리 버튼이 [업데이트]로 바뀝니다. 해당 쇼핑몰이 업데이트 팝업에서 동의하기 전까지는 추가한 이벤트가 전송되지 않습니다.
웹훅 삭제목록의 삭제 버튼을 클릭하면 별도 확인 없이 바로 삭제됩니다. 삭제 시에는 쇼핑몰 재동의가 필요하지 않습니다.
API 권한 삭제같은 분류의 웹훅이 등록된 상태에서 API 권한을 삭제하면 안내가 표시됩니다. 삭제를 진행하면 웹훅 설정은 남아 있지만 해당 이벤트는 전송되지 않습니다.
⚠️
이벤트를 추가할 때는 쇼핑몰 재동의를 고려해 주세요

APP을 이미 설치한 쇼핑몰은 업데이트에 동의해야 추가 이벤트를 받을 수 있습니다. 새 이벤트를 기반으로 하는 기능은 동의하지 않은 쇼핑몰에서도 오류 없이 동작하도록 구현해 주세요.

이벤트가 수신되지 않을 때​

아래 항목을 순서대로 확인해 주세요.

  1. 전송내역 확인 — 전송내역에 기록이 있는지, 상태가 실패인지 확인합니다. 기록이 없다면 아래 수신 조건을 확인해 주세요.
  2. API 권한 — 이벤트와 같은 분류의 API 권한이 APP에 등록되어 있는지 확인합니다.
  3. 수신여부 — 웹훅이 활성 상태인지 확인합니다.
  4. 운영자 동의 — 이벤트를 추가했다면 해당 쇼핑몰 운영자가 업데이트에 동의했는지 확인합니다.
  5. 쇼핑몰 환경 — 통합옵션 · 주문2.0 · UTF-8 쇼핑몰인지 확인합니다.
  6. 방화벽 — 발송 서버 IP 14.129.76.217이 허용되어 있는지 확인합니다.
  7. 응답 코드 — 수신 서버가 제한 시간 안에 2xx로 응답하는지 확인합니다. TEST 전송으로 빠르게 점검할 수 있습니다.
📄
함께 보면 좋은 문서

API 권한별 요청/응답 형식과 파라미터 등 상세 스펙은 API 문서를 참고해 주세요.