import { createHmac, timingSafeEqual } from 'node:crypto'; /** hmac-sha256(secret, body) as lowercase hex — the X-PayServer-Signature value. */ export function signWebhookBody(secret: string, body: string): string { return createHmac('sha256', secret).update(body, 'utf8').digest('hex'); } /** Constant-time signature verification. */ export function verifyWebhookSignature(secret: string, body: string, signature: string): boolean { const expected = signWebhookBody(secret, body); const a = Buffer.from(expected, 'utf8'); const b = Buffer.from(signature, 'utf8'); return a.length === b.length && timingSafeEqual(a, b); } /** Retry schedule after the initial attempt: 1m, 5m, 30m, 2h, 12h, then dead-letter. */ export const WEBHOOK_RETRY_DELAYS_MS = [60_000, 300_000, 1_800_000, 7_200_000, 43_200_000] as const;