u/Taskra_agency

▲ 3 r/n8n

Sketch: payment webhook in n8n with signature check + dedupe. What am I missing?

I'm sketching a handler for payment-provider webhooks in n8n (for a subscription flow) and want a sanity check before building the rest.

The two things I want to get right:

  1. Verify the signature on the raw body, not the parsed JSON.

  2. Don't process the same event twice, since providers retry.

Webhook node with "Raw Body" enabled, then a Code node:

const crypto = require('crypto');

const raw = (await this.helpers.getBinaryDataBuffer(0, 'data')).toString('utf8');

const sig = $input.first().json.headers['x-signature'];

const expected = crypto.createHmac('sha256', $env.WEBHOOK_SECRET).update(raw).digest('hex');

const ok = sig && sig.length === expected.length &&

crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));

if (!ok) throw new Error('bad signature');

const event = JSON.parse(raw);

const store = $getWorkflowStaticData('global');

store.seen = store.seen || {};

if (store.seen[event.id]) return []; // already handled

store.seen[event.id] = Date.now();

return [{ json: event }];

Caveats I already know about:

- Header name and signature format differ per provider (some sign a timestamp too).

- Static data only persists for active (production) runs, not manual tests.

- It grows forever, so I'd prune old IDs or use a Data Table instead.

- I haven't run this exact code on n8n Cloud, so crypto/$env may be restricted there.

Questions: is static data or a Data Table the better place for the dedupe list? Anything about retries or out-of-order events I should handle before the "grant access" step?

reddit.com
u/Taskra_agency — 10 days ago