Webhook / 서명 검증과 재시도
Webhook / 서명 검증과 재시도
서명 검증과 재시도
서명 검증
받은 요청의 본문 문자열 그대로를 등록할 때 받은 시크릿으로 HMAC-SHA256 계산해 X-PinderSign-Signature 의 sha256= 뒤 값과 비교하세요. 다르면 우리가 보낸 요청이 아닙니다. JSON 을 파싱했다 다시 문자열로 만들면 공백과 키 순서가 달라져 값이 안 맞습니다.
재시도
수신측이 2xx 가 아닌 응답을 주거나 8초 안에 응답하지 않으면 실패로 보고 다시 보냅니다. 최대 6번까지, 간격은 1분 → 5분 → 15분 → 1시간 → 6시간입니다. 재시도 큐는 DB 에 있어서 우리 쪽 재배포로 없어지지 않습니다.
같은 이벤트를 두 번 받을 수 있습니다. 수신측이 200 을 늦게 돌려주면 우리는 실패로 보고 다시 보내기 때문입니다. X-PinderSign-Delivery 값을 저장해 두고 이미 처리한 건이면 건너뛰세요.
전송 이력
GET
/webhooks/:id/deliveriesPOST
/webhooks/:id/deliveries/:deliveryId/retry최근 50건의 전송 기록을 시도 횟수·마지막 오류와 함께 돌려줍니다. 수신측을 고친 뒤에는 재전송으로 백오프를 기다리지 않고 바로 다시 받을 수 있습니다. 콘솔의 설정 › 개발자에서 같은 목록을 보고 버튼으로 다시 보낼 수도 있습니다.
| status | 뜻 |
|---|---|
pending | 아직 성공하지 못했고 재시도가 남음 |
delivered | 2xx 를 받음 |
failed | 6번 다 실패. 자동 재시도는 끝났고 수동 재전송만 남음 |
더 궁금한 점이 있나요?
콘솔 사용법은 사용자 가이드를 보세요. 연동 중 막히면 hello@lillo.cx 로 요청·응답을 함께 보내 주세요.
Node.js 검증
javascript
import express from "express";
import { createHmac, timingSafeEqual } from "node:crypto";
const app = express();
// 본문을 그대로 들고 있어야 한다
app.post("/webhooks/pindersign",
express.raw({ type: "application/json" }),
(req, res) => {
const got = req.header("x-pindersign-signature") ?? "";
const want = "sha256=" + createHmac("sha256", process.env.HOOK_SECRET)
.update(req.body)
.digest("hex");
const a = Buffer.from(got), b = Buffer.from(want);
if (a.length !== b.length || !timingSafeEqual(a, b)) {
return res.sendStatus(401);
}
const { event, data } = JSON.parse(req.body);
// 먼저 200 을 주고 처리는 뒤로 미룬다(8초 제한)
res.sendStatus(200);
handle(event, data);
});전송 이력
json
[
{
"id": "b9d1…",
"event": "document.completed",
"status": "failed",
"attempts": 6,
"lastError": "status 502",
"createdAt": "2026-09-19T13:02:14.001Z",
"deliveredAt": null,
"nextAttempt": null
}
]