November 1

Verifying a webhook signature (with code)

0  comments

If you set a Signing secret under Webhook in WP Lead Player › Integrations, every request carries a signature your receiving code can check. That proves it came from your site and wasn’t changed on the way.

How the signature works

  • It’s an HMAC-SHA256 of the raw request body, using your signing secret as the key.
  • It’s sent in the X-WPLP-Signature header, as sha256= followed by the hex digest.
  • An X-WPLP-Event header names the event, for example lead.created.

Use the raw body exactly as received, before any JSON parsing. If you parse and re-encode it first, the digest will never match.

PHP

$raw    = file_get_contents('php://input');
$given  = $_SERVER['HTTP_X_WPLP_SIGNATURE'] ?? '';
$valid  = hash_equals('sha256=' . hash_hmac('sha256', $raw, $secret), $given);

Node

const crypto = require('crypto');
const expected = Buffer.from('sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex'));
const given = Buffer.from(req.headers['x-wplp-signature'] || '');
const valid = given.length === expected.length && crypto.timingSafeEqual(given, expected);

Both use a timing-safe comparison, which is the right way to compare signatures.

If it never matches

  • Check both ends use exactly the same secret.
  • Make sure you’re hashing the raw body, not a parsed copy. In Express, for example, capture the raw body before the JSON parser runs.
  • Send a test from Send a test lead to this webhook and compare.

For the full list of what’s in each request, see How integrations work and what gets sent.

Was this article helpful?

  • developers
  • HMAC
  • signature
  • webhook
  • WP Lead Player

← WP Lead Player


Tags


You may also like

Hello world!

Hello world!
{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Get in touch

Name*
Email*
Message
0 of 350