--- title: "웹훅 연동하기" description: "다음 절차에 따라 웹훅 엔드포인트를 만들고 등록하면 앱에서 웹훅 이벤트를 수신할 수 있습니다." source: "https://docs.tokenz.one/ko-KR/v1/checkout/webhooks-get-started" api_version: "v1" locale: "ko-KR" version_status: "legacy" docs_stage: "prod" --- # 웹훅 연동하기 다음 절차에 따라 웹훅 엔드포인트를 만들고 등록하면 앱에서 웹훅 이벤트를 수신할 수 있습니다. 1. 이벤트 데이터 POST 요청을 수신할 **웹훅 엔드포인트 핸들러를 만드세요.** 2. Tokenz 대시보드에서 **엔드포인트를 등록하세요.** 3. **웹훅 엔드포인트의 보안을 설정하세요.** 4. [테스트 결제](https://docs.tokenz.one/ko-KR/v1/checkout/testing)로 **웹훅 엔드포인트를 테스트하세요.** ## 1. 핸들러 생성 웹훅 POST 요청을 받을 HTTPS 엔드포인트를 구현하세요. [Webhook.site](https://webhook.site/)로 페이로드를 확인하고 전송을 테스트할 수 있습니다. 이 엔드포인트는 다음 조건을 충족해야 합니다. - [이벤트 객체](https://docs.tokenz.one/ko-KR/v1/checkout/webhooks#event-object)로 구성된 JSON 페이로드의 POST 요청을 처리합니다. - 시간 초과를 유발할 수 있는 복잡한 로직을 실행하기 전에 성공 상태 코드(2xx)를 신속하게 반환합니다. ## 2. 엔드포인트 등록 [대시보드](https://dashboard.tokenz.one/ko-KR/home/developers)에서 웹훅 엔드포인트를 등록하세요. 1. **개발자**(Developers) 페이지에서 **웹훅**(Webhooks) 탭을 여세요. 2. **새 웹훅 생성**(Create new webhook)을 클릭하세요. 3. URL과 선택 사항인 설명을 입력하고, 수신할 이벤트를 선택하세요. 고객의 주문 성공을 놓치지 않도록 최소한 `order.succeeded`를 선택하는 것을 권장합니다. 4. **웹훅 생성**(Create webhook)을 클릭하세요. 5. 반환된 서명 비밀키를 복사하여 보관하세요. 수신 웹훅 검증에 필요합니다. 보안상 한 번만 표시됩니다. ![](https://docs.tokenz.one/docs/dashboard_create_webhook_en.png) ## 3. 웹훅 엔드포인트 보안 설정 Tokenz는 전송하는 모든 웹훅에 서명을 포함합니다. Tokenz가 전송했고 변조되지 않았는지 확인하려면 반드시 서명을 검증해야 합니다. 또는 웹훅 알림을 계기로 API에서 주문 상태 변경을 확인할 수 있습니다. 불필요한 API 호출을 피하려면 웹훅 서명 검증을 권장합니다. 서명된 이벤트의 `Tokenz-Signature` 헤더에는 타임스탬프(`t:`)와 검증해야 할 버전별 서명(`v1:`)이 하나 이상 포함됩니다. 현재 유효한 라이브 서명 방식은 `v1`입니다. **예제:** ```plaintext t:1725864981111,v1:zjdrra3...Mh+e6s= ``` ### 서명 검증 #### 1. 타임스탬프와 서명 추출 헤더를 쉼표(`,`)로 나누어 요소 목록을 만드세요. 각 요소를 콜론(`:`)으로 나누어 접두사와 값의 쌍을 얻습니다. `t`는 타임스탬프, `v1`은 서명입니다. 나머지 요소는 무시하세요. #### 2. 서명할 페이로드 준비 다음 값을 순서대로 이어 붙여 페이로드 문자열을 만드세요. - 문자열 형태의 타임스탬프 - 수정하지 않은 원본 요청 본문(JSON 페이로드) #### 3. 서명 계산 SHA256 해시 함수를 사용하여 HMAC을 계산하세요. 엔드포인트의 서명 비밀키를 키로, 페이로드 문자열을 메시지로 사용합니다. #### 4. 서명 비교 헤더의 서명과 계산한 서명이 일치하는지 확인하세요. 재전송 공격을 방지하려면 현재 시각과 수신 타임스탬프의 차이도 확인하세요. 서명이 유효해도 타임스탬프가 오래되었다면 거부할 수 있습니다. 권장 허용 오차는 300초(5분)입니다. 재전송 공격은 공격자가 정상 페이로드와 서명을 가로채 다시 보내는 공격입니다. Tokenz는 `Tokenz-Signature` 헤더에 타임스탬프를 포함하여 이 위험을 줄입니다. #### NodeJS ```javascript const crypto = require('crypto'); const express = require('express'); const app = express(); const port = 3000; // Use express.raw() so the signature is computed over the exact bytes // Tokenz sent; re-serializing a parsed body can fail verification. // If your app registers express.json() or another body parser globally, // mount this webhook route BEFORE it so the raw body is preserved. app.post("/webhook", express.raw({ type: 'application/json' }), (req, res) => { // The signing secret shown once on webhook creation is Base64-encoded. const secret = 'webhook-endpoint-secret'; const sig = req.headers['tokenz-signature']; let timestamp, signature; for (let sigPart of sig.split(',')) { let [key, value] = sigPart.split(':'); if (key === 't') { timestamp = value; } else if (key === 'v1') { signature = value; } } const checkSignature = crypto.createHmac('sha256', Buffer.from(secret, 'base64')) .update(`${timestamp}${req.body.toString('utf8')}`) .digest('base64'); // The `t` value in Tokenz-Signature is a Unix timestamp in milliseconds. const tolerance = 5 * 60 * 1000; // 5 minutes if (signature === checkSignature && Math.abs(Date.now() - Number(timestamp)) <= tolerance) { return res.status(200).end(); } else { return res.status(400).end(); } }); ``` ## 4. 웹훅 엔드포인트 테스트 웹훅 처리가 올바르게 동작하는지 확인하려면 [테스트 가이드](https://docs.tokenz.one/ko-KR/v1/checkout/testing)에 따라 테스트 결제를 생성하고 완료하세요.