Code examples
Code example
Java
import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
public class WebhookExampleController {
@PostMapping("/webhook/example")
@ResponseBody
public String receive(HttpServletRequest request, @RequestBody String payload, HttpServletResponse response) {
String responseBody = "";
StringBuilder valueToDigest = new StringBuilder();
// Get the timestamp from header
String timestamp = request.getHeader("x-timestamp");
valueToDigest.append(timestamp);
valueToDigest.append(payload);
// Get the signature from header
String signature = request.getHeader("x-signature");
// Get your secret
String secret = getSecret();
if (HmacUtils.hmacSha256Hex(secret, valueToDigest.toString()).equals(signature)) {
// Do something with event
response.setStatus(HttpServletResponse.SC_OK);
} else {
// Invalid signature
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
responseBody = "failed to verify the signature";
}
return responseBody;
}
}
PHP
<?php
use RingCentral\Psr7\Response;
function getSecret() {
return 'whsec_CEm2XM_JZ1x5FxUUEGcZoRgIz4RZfDE';
}
function handler($request, $context): Response{
$timestamp = $request->getHeaderLine('x-timestamp');
$body = $request->getBody()->getContents();
$secret = getSecret();
$signature = $request->getHeaderLine('x-signature');
if (hash_hmac('sha256', $timestamp.$body, $secret) != $signature) {
return new Response(400, array(), 'failed to verify the signature');
}
// Do something with event
return new Response(200, array(), $body);
}
Node.js
// express.js
const crypto = require('crypto')
const secret = '<CLIENT_API_WEBHOOK_SECRET>'
async webhookController(ctx, next) {
// webhook is received
const { headers, body } = ctx.request
const { name, accountId } = body || {} // payload
const ts = headers['x-timestamp']
const policy = `${ts}${body}`
const signatureHex = crypto.createHmac('sha256', secret).update(policy).digest('hex')
if (signatureHex === headers['x-signature']) {
// do business logic after signature is verified
return next() // http response code = 200: ack the webhook
} else {
ctx.status = 500
ctx.body = 'failed to verify webhook signature'
return
}
}