Authenticate webhooks with signature

With each webhook request, Ecwid sends a unique webhook signature used to authenticate the webhook and verify that it comes from Ecwid and is not corrupted. Webhook authentication requires you to generate a validation signature based on webhook data and compare it with the original signature received in webhook.

Get original signature

All webhooks received from Ecwid have an HTTP header named X-Ecwid-Webhook-Signature with an original signature. If webhooks come without this header, they are not from Ecwid.

Upon receiving a new webhook, take theX-Ecwid-Webhook-Signature value. You'll need it to compare with your generated signature later.

Generate validation signature

A validation signature is generated by encoding a string of concatenated webhook data with a dot . delimiter. Webhook data includes two fields from the webhook body:

  • eventCreated containing UNIX timestamp when the webhook event happened
  • eventId containing the ID of webhook entity, for example, product or customer ID

The resulting string is encoded using HMAC SHA-256 and using client_secret key from application settings. Each application has its own unique client_secret, so if you use one webhookUrl for several applications, add a custom header to identify which application received webhook.

  1. Encode the string {eventCreated}.{eventId} using HMAC SHA256 and client_secret key
  2. Pass the encoded string through Base64 encoding

Authenticate webhook

Compare the original signature received in webhook header and the validation signature generated from webhook body data to see if they match.

Code example:

if (!$signatureHeaderPresent) {
	echo 'Signature verification failed';
	exit;
}

if (!function_exists('getallheaders')) {
    function getallheaders()
    {
        foreach ($_SERVER as $name => $value) {
            if (substr($name, 0, 5) == 'HTTP_') {
                $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
            }
        }
        return $headers;
    }
}

foreach (getallheaders() as $name => $value) {
    if ($name == "X-Ecwid-Webhook-Signature") {
        $headerSignature = "$value";
      	$signatureHeaderPresent = true;
        
        $hmac_result = hash_hmac("sha256", "$eventCreated.$eventId", $client_secret, true);
        $generatedSignature = base64_encode($hmac_result);
        
        if ($generatedSignature !== $headerSignature) {
            echo 'Signature verification failed';
            exit;
        }
    }
}