Webhook Authentication
Every webhook payload We-Link sends includes a cryptographic hash field. This ensures the data hitting your server is authentic and has not been tampered with.
How It Works
Step-by-Step
- Configuration — When creating a webhook in the dashboard, you define a Secret Code
- Hashing — When we send a webhook, we generate a cryptographic hash of the entire message body using your Secret Code
- Verification — The hash is included in the payload under the
hashfield - Validation — On your side, regenerate the hash and compare
Implementation
Node.js Example
const crypto = require("crypto");
app.post("/webhook/welink", (req, res) => {
const payload = req.body;
const receivedHash = payload.hash;
// Remove hash from body before computing
const { hash, ...data } = payload;
// Compute hash using your stored secret
const computedHash = crypto
.createHmac("sha256", process.env.WELINK_WEBHOOK_SECRET)
.update(JSON.stringify(data))
.digest("hex");
if (computedHash === receivedHash) {
// ✅ Authentic — process the webhook
console.log("Verified webhook:", data);
res.status(200).send("OK");
} else {
// ❌ Tampered — reject
console.warn("Invalid webhook signature");
res.status(401).send("Unauthorized");
}
});
Python Example
import hmac
import hashlib
import json
def verify_webhook(payload: dict, secret: str) -> bool:
received_hash = payload.pop('hash', None)
computed_hash = hmac.new(
secret.encode(),
json.dumps(payload).encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(computed_hash, received_hash)
Payload Examples
Authenticated Success Response
{
"status": "SUCCESS",
"request_id": "req-11111-22222-33333",
"result": {
"first_name": "Jane",
"last_name": "Doe",
"profile_id": "jane-doe-123",
"premium": true
},
"hash": "a1b2c3d4e5f67890123456789abcdef123456789"
}
Authenticated Failed Response
{
"status": "FAILED",
"request_id": "req-99999-88888-77777",
"error": "Password Incorrect",
"hash": "f6e5d4c3b2a109876543210987654321fedcba98"
}
Security Best Practice
- Store your Secret Code in environment variables, never in source code
- Always validate the hash before processing any webhook data
- Reject and log any requests with invalid signatures