// Receiver di test per i webhook Medusa -> Fastify, finché apps/api non implementa /webhooks/medusa. // Uso (in medusa/apps/backend): node http/webhook-receiver.mjs [porta] // Legge WEBHOOK_SECRET da .env, verifica la firma x-signature e stampa ogni richiesta. // Con FAIL=3 risponde 503 alle prime 3 richieste (per vedere i retry). import { createHmac, timingSafeEqual } from "node:crypto" import { readFileSync } from "node:fs" import { createServer } from "node:http" const port = Number(process.argv[2] ?? 3999) const secret = process.env.WEBHOOK_SECRET ?? readFileSync(".env", "utf8").match(/^WEBHOOK_SECRET=(.*)$/m)?.[1]?.trim() let failuresLeft = Number(process.env.FAIL ?? 0) if (!secret) { console.error("WEBHOOK_SECRET non trovato (env o .env)") process.exit(1) } createServer((req, res) => { let body = "" req.on("data", (chunk) => (body += chunk)) req.on("end", () => { const expected = createHmac("sha256", secret).update(body).digest("hex") const got = String(req.headers["x-signature"] ?? "") const valid = got.length === expected.length && timingSafeEqual(Buffer.from(got), Buffer.from(expected)) const status = failuresLeft > 0 ? 503 : valid ? 200 : 401 if (failuresLeft > 0) failuresLeft-- let payload = body try { const p = JSON.parse(body) payload = `${p.event} id=${p.id} occurred_at=${p.occurred_at} data=${JSON.stringify(p.data)}` } catch {} console.log( `${new Date().toISOString()} ${req.method} ${req.url} firma=${valid ? "OK" : "NON VALIDA"} -> ${status}\n ${payload}` ) res.writeHead(status, { "content-type": "application/json" }).end('{"ok":true}') }) }).listen(port, () => console.log(`webhook receiver su http://localhost:${port}/webhooks/medusa`))