---
title: "웹훅: CheckoutOS 문서 | Chargezen"
description: "CheckoutOS의 실시간 이벤트 알림. Chargezen CheckoutOS 문서의 API 참조 섹션에 있어요."
url: "https://chargezen.com/ko/docs/checkoutos/api/webhooks"
lang: "ko"
updated: "2025-01-16"
---

Canonical URL: https://chargezen.com/ko/docs/checkoutos/api/webhooks

# 웹훅

CheckoutOS의 실시간 이벤트 알림

마지막 업데이트: 2025-01-16

**웹훅**을 사용하면 CheckoutOS에서 이벤트가 발생할 때 실시간 알림을 받을 수 있어요. API를 반복해서 조회하는 대신 이벤트 발생 시 웹훅이 서버로 데이터를 전송해요.

## 사용 가능한 이벤트

#### 웹훅 이벤트

*   upsell.accepted — 고객이 추가 판매 제안을 수락했어요
*   upsell.declined — 고객이 추가 판매 제안을 거절했어요
*   bundle.purchased — 번들을 구매했어요
*   experiment.concluded — A/B 테스트가 유의성에 도달했어요
*   order.edited — 고객이 주문을 수정했어요
*   order.cancelled — 고객이 주문을 취소했어요
*   subscription.created — 구독 추가 판매가 전환되었어요

## 웹훅 만들기

1

#### 웹훅으로 이동

CheckoutOS → Settings → Webhooks로 이동하세요.

2

#### 엔드포인트 추가

"Add Webhook Endpoint"를 클릭하세요.

3

#### URL 입력

이벤트를 수신할 HTTPS URL을 입력하세요.

4

#### 이벤트 선택

구독할 이벤트를 선택하세요.

5

#### 저장

저장하고 서명 시크릿을 기록해 두세요.

API로 웹훅 만들기

```bash
curl -X POST "https://api.chargezen.com/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yourserver.com/webhooks/checkoutos",
    "events": ["upsell.accepted", "bundle.purchased"],
    "enabled": true
  }'

# Response
{
  "id": "wh_123",
  "url": "https://yourserver.com/webhooks/checkoutos",
  "events": ["upsell.accepted", "bundle.purchased"],
  "signing_secret": "whsec_abc123...",
  "enabled": true
}
```

## 웹훅 페이로드

### upsell.accepted

추가 판매 수락 이벤트

```json
{
  "id": "evt_123456",
  "type": "upsell.accepted",
  "created_at": "2025-01-16T14:30:00Z",
  "data": {
    "upsell_id": "upsell_abc",
    "upsell_name": "Premium Add-On",
    "order_id": "order_789",
    "shopify_order_id": "5678901234",
    "customer_id": "cust_456",
    "product": {
      "id": "prod_xyz",
      "title": "Premium Widget",
      "variant_id": "var_123",
      "price": 29.99
    },
    "discount": {
      "type": "percentage",
      "value": 15,
      "amount": 4.50
    },
    "final_price": 25.49
  }
}
```

### bundle.purchased

번들 구매 이벤트

```json
{
  "id": "evt_234567",
  "type": "bundle.purchased",
  "created_at": "2025-01-16T15:00:00Z",
  "data": {
    "bundle_id": "bundle_def",
    "bundle_name": "Skincare Starter Kit",
    "bundle_type": "fixed",
    "order_id": "order_890",
    "products": [
      { "id": "prod_a", "title": "Cleanser", "quantity": 1 },
      { "id": "prod_b", "title": "Toner", "quantity": 1 },
      { "id": "prod_c", "title": "Moisturizer", "quantity": 1 }
    ],
    "original_price": 89.97,
    "bundle_price": 71.98,
    "savings": 17.99
  }
}
```

### order.edited

주문 수정 이벤트

```json
{
  "id": "evt_345678",
  "type": "order.edited",
  "created_at": "2025-01-16T15:30:00Z",
  "data": {
    "order_id": "order_901",
    "shopify_order_id": "6789012345",
    "edit_type": "add_items",
    "changes": {
      "items_added": [
        { "product_id": "prod_new", "quantity": 1, "price": 19.99 }
      ],
      "items_removed": [],
      "quantity_changes": []
    },
    "amount_changed": 19.99,
    "new_total": 109.98
  }
}
```

## 웹훅 검증

모든 웹훅에는 검증용 서명 헤더가 포함돼요.

Node.js 검증

```javascript
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload, 'utf8')
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(`sha256=${expectedSignature}`)
  );
}

// Express middleware
app.post('/webhooks/checkoutos', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-checkoutos-signature'];

  if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body);
  // Handle event...

  res.status(200).send('OK');
});
```

Python 검증

```python
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode('utf-8'),
        payload,
        hashlib.sha256
    ).hexdigest()

    return hmac.compare_digest(
        f'sha256={expected}',
        signature
    )

# Flask example
@app.route('/webhooks/checkoutos', methods=['POST'])
def handle_webhook():
    signature = request.headers.get('X-CheckoutOS-Signature')

    if not verify_webhook(request.data, signature, WEBHOOK_SECRET):
        return 'Invalid signature', 401

    event = request.get_json()
    # Handle event...

    return 'OK', 200
```

항상 검증하세요

처리하기 전에 항상 웹훅 서명을 검증하세요. 공격자가 엔드포인트에 가짜 이벤트를 보내는 것을 방지해요.

## 재시도 정책

웹훅 전달에 실패하면 지수적으로 간격을 늘려 재시도해요.

재시도 일정

```json
{
  "retry_policy": {
    "max_attempts": 5,
    "schedule": [
      { "attempt": 1, "delay": "immediately" },
      { "attempt": 2, "delay": "5 minutes" },
      { "attempt": 3, "delay": "30 minutes" },
      { "attempt": 4, "delay": "2 hours" },
      { "attempt": 5, "delay": "24 hours" }
    ],
    "success_codes": [200, 201, 202, 204],
    "timeout": "30 seconds"
  }
}
```

## 웹훅 테스트

실제 운영 전에 웹훅 엔드포인트를 테스트하세요.

테스트 이벤트 전송

```bash
curl -X POST "https://api.chargezen.com/v1/webhooks/wh_123/test" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "upsell.accepted"
  }'
```

## 웹훅 로그

대시보드나 API에서 웹훅 전달 이력을 확인해요.

웹훅 로그 조회

```bash
curl -X GET "https://api.chargezen.com/v1/webhooks/wh_123/logs" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Response
{
  "data": [
    {
      "id": "log_123",
      "event_id": "evt_456",
      "event_type": "upsell.accepted",
      "status": "delivered",
      "response_code": 200,
      "duration_ms": 245,
      "created_at": "2025-01-16T14:30:00Z"
    }
  ]
}
```

## 권장 방법

웹훅 팁

*   **빠르게 응답해요** — 30초 이내에 200을 반환하세요
*   **비동기로 처리해요** — 백그라운드 처리를 위해 이벤트를 큐에 넣으세요
*   **중복을 처리해요** — 이벤트는 여러 번 전달될 수 있어요
*   **서명을 검증해요** — 처리 전에 항상 검증하세요
*   **실패를 모니터링해요** — 전달 실패 알림을 설정하세요

## 관련 주제

[

### 인증

API 키 관리

자세히 보기



](https://chargezen.com/ko/docs/checkoutos/api/authentication)[

### API 엔드포인트

전체 엔드포인트 참조

자세히 보기



](https://chargezen.com/ko/docs/checkoutos/api/endpoints)

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

도움이 더 필요하신가요? [고객 지원 문의](https://chargezen.com/ko/docs/checkoutos/troubleshooting/support)
