웹훅
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로 웹훅 만들기
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
추가 판매 수락 이벤트
{
"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
번들 구매 이벤트
{
"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
주문 수정 이벤트
{
"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 검증
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 검증
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항상 검증하세요
처리하기 전에 항상 웹훅 서명을 검증하세요. 공격자가 엔드포인트에 가짜 이벤트를 보내는 것을 방지해요.
재시도 정책
웹훅 전달에 실패하면 지수적으로 간격을 늘려 재시도해요.
재시도 일정
{
"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"
}
}웹훅 테스트
실제 운영 전에 웹훅 엔드포인트를 테스트하세요.
테스트 이벤트 전송
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에서 웹훅 전달 이력을 확인해요.
웹훅 로그 조회
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을 반환하세요
- 비동기로 처리해요 — 백그라운드 처리를 위해 이벤트를 큐에 넣으세요
- 중복을 처리해요 — 이벤트는 여러 번 전달될 수 있어요
- 서명을 검증해요 — 처리 전에 항상 검증하세요
- 실패를 모니터링해요 — 전달 실패 알림을 설정하세요
관련 주제
이 페이지가 도움이 되었나요?
도움이 더 필요하신가요? 고객 지원 문의