웹훅 엔드포인트에서 Tokenz 이벤트 수신
웹훅 엔드포인트에서 Tokenz 계정의 이벤트를 수신하여 연동 시스템이 자동으로 후속 작업을 실행하도록 하세요.
금액 형식: 웹훅 페이로드의 금액 값(amount 필드 등)은 각 통화의 최소 단위로 표시됩니다. 통화별 정확한 형식은 지원 통화를 참고하세요.
웹훅을 사용하는 이유
Tokenz Checkout을 연동할 때 계정에서 이벤트가 발생하면 애플리케이션이 이를 수신하여 백엔드에서 필요한 작업을 실행해야 합니다.
웹훅 이벤트를 사용하려면 웹훅 엔드포인트를 등록해야 합니다. 등록 후 Tokenz 계정에서 이벤트가 발생하면 애플리케이션의 웹훅 엔드포인트로 실시간 이벤트 데이터를 전송합니다. Tokenz는 HTTPS를 통해 Event 객체를 담은 JSON 페이로드를 전송합니다.
결제 결과 알림을 빠짐없이 받을 수 있도록 Checkout 리디렉션 처리와 함께 웹훅을 구현하는 것을 강력히 권장합니다.
이벤트 객체
이벤트가 발생하면 Tokenz는 새 Event 객체를 생성합니다. 하나의 API 요청으로 여러 이벤트가 발생할 수 있습니다.
Tokenz 계정에 웹훅 엔드포인트를 등록하면 Tokenz가 애플리케이션에서 호스팅하는 엔드포인트로 POST 요청에 Event 객체를 담아 자동 전송합니다. 이벤트를 수신한 후 백엔드 작업을 실행할 수 있습니다. 예를 들어 order.succeeded 이벤트를 받으면 구매한 상품의 다운로드 링크를 보내거나 고객 잔액을 충전할 수 있습니다.
웹훅으로 전송되는 Event 객체는 변경된 객체의 스냅샷입니다. 웹훅에는 항상 이벤트가 발생한 전체 객체와 이벤트 메타데이터가 포함됩니다.
이벤트 페이로드 예제
다음은 주문 성공 시 전송되는 이벤트의 예제입니다.
{
"id": "a1b2c3d4-e5f6-7g8h-9i0j-k1l2m3n4o5p6",
"object": "order.succeeded",
"createdAt": "2026-01-15T09:30:00Z",
"test": true,
"eventData": {
"type": "order",
"version": "v1",
"data": {
"order": {
"id": "order_1D5xA9BnKfv_t",
"object": "order",
"status": "succeeded",
"amount": {
"amount": 3700,
"currency": "JPY"
},
"items": [
{
"id": "item_1D6F8mR5TnK_t",
"detail": {
"product": {
"price": {
"amount": 1200,
"currency": "JPY"
},
"quantity": 3,
"label": "ひとにぎりのエメラルド",
"description": "80+8",
"images": [
"https://images.ctfassets.net/z82qbo7cv7ia/1dWPbk5Qx2M1Qikj6Knyuc/e37b2c26829c0d30793a348ae3adb3b0/fake-pass.webp"
]
}
}
},
{
"id": "item_1xejV7puGeK_t",
"detail": {
"product": {
"price": {
"amount": 100,
"currency": "JPY"
},
"quantity": 1,
"label": "Diamond",
"description": "",
"images": [],
"sku": "sku_103843dfjhdfgiu",
"taxCategory": "VIRTUAL_CURRENCY"
}
}
}
],
"description": "Game items purchase",
"reference": "ORDER_2024_001",
"test": true,
"expiresAt": "2024-12-31T23:59:59Z",
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-15T10:05:30Z"
}
}
}
}
라이브 및 테스트 모드
하나의 엔드포인트에서 라이브 및 테스트 모드를 모두 처리하면 두 모드의 이벤트를 모두 수신할 수 있습니다. test 플래그로 객체가 어느 모드에 속하는지 확인하고 적절하게 처리하세요.
버전
version은 이벤트의 API 버전을 나타내며, 포함된 data.object의 구조를 결정합니다.
이벤트 유형
| 유형 | 설명 |
|---|---|
order.created | Checkout Session 생성 엔드포인트를 통해 새 주문이 생성되었습니다. |
order.succeeded | 고객이 주문 결제를 완료했습니다. 고객에게 아이템을 지급할 수 있습니다. |
order.expired | 주문이 만료되었습니다. |
order.canceled | 주문이 취소되었습니다. |
order.failed | 주문 결제에 실패했습니다. |
refund.created | 환불이 생성되었습니다. |
refund.failed | 환불에 실패했습니다. |
dispute.created | 분쟁이 생성되었습니다. |
dispute.closed | 분쟁이 종료되었습니다. |
redemption.completed | 기프트 코드를 사용했거나 무료 아이템을 수령했습니다. kind로 흐름을 구분합니다(source는 더 이상 권장되지 않음). 무료 아이템 수령에서는 code가 생략됩니다. |
재시도와 멱등성
엔드포인트는 2xx 응답으로 웹훅 수신을 확인해야 합니다. 다른 상태 코드를 반환하거나 응답 시간이 초과되거나 접근할 수 없으면 Tokenz가 최대 3일 동안 자동으로 재전송합니다. 초기 재시도는 전송 실패 후 약 5초, 15초, 30초에 이루어집니다. 이후에는 간격이 점점 길어집니다. 재시도 시점은 약간 달라질 수 있으므로 이후 재시도의 정확한 일정에 의존하지 마세요. 테스트 모드에는 다른 재시도 정책이 적용될 수 있으므로 이를 사용하여 라이브 모드의 재시도 시점을 측정하거나 검증하지 마세요. 2xx 응답을 반환하면 해당 이벤트의 재시도가 중단됩니다. 같은 이벤트를 여러 번 받거나 이벤트 순서가 바뀔 수 있습니다.
이벤트를 안전하게 수신하면 바로 2xx로 응답하고, 오래 걸리는 작업은 비동기로 처리하세요. 이벤트의 최상위 id를 멱등성 키로 사용하세요.
문제 해결: 이벤트가 수신되지 않는 경우
대부분의 경우 “웹훅이 도착하지 않았다”는 것은 Tokenz가 전송했지만 엔드포인트가 거부했다는 뜻입니다. Tokenz는 2xx 이외의 응답, 시간 초과, 접근 불가를 전송 실패로 간주하고 최대 3일 동안 자동 재시도합니다. 따라서 판매자 측에서는 아무것도 도착하지 않은 것처럼 보이지만 Tokenz에서는 같은 전송이 반복해서 실패할 수 있습니다(예: 계속되는 HTTP 400).
Tokenz는 엔드포인트별 전송 로그를 제공하지 않으므로 자체 엔드포인트에서 진단하세요.
1. 엔드포인트가 반환한 HTTP 상태를 확인하세요. Tokenz가 받는 응답과 같습니다. 서버의 액세스 로그와 오류 로그에서 수신 POST 요청을 확인하세요.
2xx— 이벤트가 전송되고 수신 확인되었습니다. 시스템에서 후속 작업이 실행되지 않았다면 전송 문제가 아니라 응답 이후 핸들러 처리의 문제입니다.400,401,403— 이벤트는 수신했지만 엔드포인트가 거부했습니다(아래 참고).5xx또는 시간 초과 — 핸들러에서 오류가 발생했거나 응답이 너무 느립니다.
2. 400을 반환한다면 먼저 서명 검증을 확인하세요. 가장 흔한 원인입니다.
- 원본 요청 본문으로 검증하세요. 대부분의 프레임워크는 JSON을 파싱하고 다시 직렬화하여 바이트가 달라지므로 HMAC 검증에 실패합니다. 예를 들어
express.raw()로 원본 바이트를 읽고, 검증한 후 파싱하세요. 웹훅 엔드포인트 보안 설정을 참고하세요. - 올바른 서명 비밀키를 사용하세요. 엔드포인트 등록 시 한 번만 표시되며 해당 엔드포인트 전용입니다. 교체 전 비밀키나 오타가 있는 비밀키를 사용하면 모든 이벤트 검증에 실패합니다.
- 테스트 및 라이브 모드를 맞추세요. 테스트 이벤트에 라이브 서명 비밀키를 사용하거나 그 반대로 사용하면 일치하지 않습니다. 두 모드를 하나의 엔드포인트에서 처리한다면 이벤트의
test플래그로 비밀키를 선택하세요. - 서버 시간 차이를 확인하세요. 타임스탬프 허용 오차를 5분으로 적용할 때 서버 시간이 크게 어긋나 있으면 유효한 이벤트도 거부할 수 있습니다.
3. 2xx 이외의 응답을 반환하는 다른 원인:
- 엔드포인트 앞의 방화벽, WAF 또는 IP 허용 목록이 Tokenz 요청을 차단합니다.
- 엔드포인트가 외부에서 HTTPS로 접근되지 않거나, 대시보드에 등록한 URL이 잘못되었거나 다른 환경을 가리킵니다.
- 요청에 응답하기 전에 오래 걸리는 작업을 수행하면 응답 시간이 초과될 수 있습니다. 먼저
2xx로 수신을 확인한 후 해당 작업을 비동기로 처리하세요.
4. 전송을 별도로 확인하세요. 엔드포인트(또는 그 사본)가 Webhook.site를 가리키도록 설정하여 Tokenz 전송 여부와 정확한 페이로드·헤더를 확인하고, 테스트 모드 결제로 이벤트를 발생시키세요.
엔드포인트가 2xx를 반환하면 재시도가 중단됩니다. 이미 처리한 이벤트가 재전송될 수 있으므로 핸들러의 멱등성을 유지하세요. 최상위 id를 멱등성 키로 사용하면 재전송으로 주문이 중복 이행되는 것을 방지할 수 있습니다.