DOCS

Webhook으로 event 수신

Zonos 통합에 대한 real-time event notification을 받습니다.

Webhook은 특정 event 발생 시 Zonos가 external system에 proactive하게 알리는 방법입니다. subscribe한 event가 발생하면 Zonos가 지정한 webhook URL로 HTTP POST request를 보냅니다. request body에 event 상세가 포함되어 system이 programmatically 처리할 수 있습니다.

Webhook은 Zonos를 다른 platform과 통합하고, automated workflow를 trigger하며, system 간 data를 real-time으로 sync하는 데 유용합니다. 예:

  • Zonos에서 order가 생성되면 order management system을 업데이트
  • shipment이 canceled되면 fulfillment provider에 알림
  • auditing을 위해 international order status change를 log

Webhook type 

사용 가능한 모든 webhook type은 WebhookType enum에 포함됩니다. 각 example payload는 Event Types guide에서 확인할 수 있습니다.

Webhook 생성 

API로 webhook을 생성하려면:

1mutation WebhookCreate($input: WebhookCreateInput!) {
2 webhookCreate(input: $input) {
3 id
4 url
5 type
6 status
7 secret
8 headers {
9 key
10 }
11 }
12}

중요: webhook을 생성할 때 secret 값을 저장해두세요 — 이 값은 이때만 반환되며, webhook signature를 검증할 때 필요합니다. 자세한 내용은 아래 Webhook signature 검증을 참고하세요.

Webhook 상세 편집 

API로 기존 webhook을 편집하려면:

1mutation WebhookUpdate($input: WebhookUpdateInput!) {
2 webhookUpdate(input: $input) {
3 id
4 url
5 type
6 status
7 }
8}

Webhook signature 검증 

Zonos가 보내는 모든 webhook request에는 zonos-signature header가 포함되어 있어, 해당 request가 실제로 Zonos에서 온 것인지, 그리고 전송 중에 payload가 변조되지 않았는지 확인할 수 있습니다.

header 값의 형식은 다음과 같습니다:

timestamp=<unix-timestamp-ms>,hmac=<base64-encoded-signature>
  • timestamp — request가 서명된 시각으로, Unix epoch milliseconds 단위입니다.
  • hmac — raw JSON request body에 대한 HMAC-SHA256 서명으로, webhook의 secret을 key로 사용해 계산한 후 Base64로 encoding한 값입니다.

request를 검증하려면:

  1. zonos-signature header에서 timestamp와 hmac 값을 parse합니다.
  2. webhook을 생성할 때 받은 secret을 사용해, raw하고 parsing되지 않은 request body에 대해 직접 HMAC-SHA256 서명을 계산합니다.
  3. 계산한 서명을 hmac 값과 constant-time comparison으로 비교하고, 일치하지 않으면 request를 거부합니다.
  4. 필요하다면 timestamp가 몇 분 이상 지난 request는 거부하여, 캡처된 request의 재전송(replay)을 방지할 수 있습니다. Zonos는 자체적으로 delivery window를 강제하지 않으므로, 이 확인은 사용자가 직접 구현해야 합니다.
1const crypto = require('crypto');
2 
3function verifyZonosWebhook(rawBody, signatureHeader, secret) {
4 const [timestampPart, hmacPart] = signatureHeader.split(',');
5 const receivedHmac = hmacPart.split('=')[1];
6 
7 const expectedHmac = crypto
8 .createHmac('sha256', secret)
9 .update(rawBody)
10 .digest('base64');
11 
12 const receivedBuffer = Buffer.from(receivedHmac);
13 const expectedBuffer = Buffer.from(expectedHmac);
14 
15 if (receivedBuffer.length !== expectedBuffer.length) {
16 return false;
17 }
18 
19 return crypto.timingSafeEqual(receivedBuffer, expectedBuffer);
20}

참고: webhook에 custom header를 설정한 경우, 해당 header도 zonos-signature와 함께 모든 request에 그대로 포함됩니다.

Webhook log 조회 

API로 webhook log를 조회하려면:

1query WebhookLogs(
2$first: Int
3$after: String
4$filter: WebhookLogsFilterInput
5) {
6 webhookLogs(first: $first, after: $after, filter: $filter) {
7 edges {
8 node {
9 id
10 type
11 url
12 createdAt
13 responseStatus
14 }
15 }
16 }
17}
GraphQL API ReferenceTypes, inputs, and operations used in this guide

이 페이지가 도움이 되었나요?