NAV

Webhooks best practices

Webhooks security

We recommend verifying each webhook request to make sure it comes from Ecwid and not altered or corrupted during transmission. You can do that by validating the webhook signature coming with each webhook.

Where can I find the signature?

A webhook signature is sent in the X-Ecwid-Webhook-Signature HTTP header with each webhook request

How is the signature generated

The signature is an encoded string generated by concatenating the following webhook data (delimiter is a dot .):

  • eventCreated (webhook event timestamp)
  • eventId (webhook event ID)

The resulting string is encoded using HMAC SHA-256 and using client_secret as the shared secret key.

How to validate the signature

To verify a webhook in your appliciation:

  1. Get the signature from the request headers
  2. Get eventCreated and eventId values from the request body
  3. Encode the string ’{eventCreated}.{eventId}’ using HMAC SHA256 (using client_secret as the shared secret key) and pass it through Base64 encoding
  4. Compare the resulting string with the received webhook signature.

See the example in the webhook processing example code.

Webhook processing example

Webhooks processing PHP example

<?php 
// Get contents of webhook request
$requestBody = file_get_contents('php://input');
$client_secret = 'abcde123456789'; // your client_secret value sent to you after the app registration

// Parse webhook data
$decodedBody = json_decode($requestBody, true);

$eventId = $decodedBody['eventId'];
$eventCreated = $decodedBody['eventCreated'];
$storeId = $decodedBody['storeId'];
$entityId = $decodedBody['entityId'];
$eventType = $decodedBody['eventType'];
$data = $decodedBody['data'];

// Reply with 200OK to Ecwid
http_response_code(200);

// Filter out the events we're not interested in
if ($eventType !== 'order.updated') {
    exit;
}

// Continue if eventType is order.updated
// Verify the webhook (check that it is sent by Ecwid)
foreach (getallheaders() as $name => $value) {
    if ($name == "X-Ecwid-Webhook-Signature") {
        $headerSignature = "$value";

        $hmac_result = hash_hmac("sha256", "$eventCreated.$eventId", $client_secret, true);
        $generatedSignature = base64_encode($hmac_result);

        if ($generatedSignature !== $headerSignature) {
            echo 'Signature verification failed';
            exit;
        }
  }
}

// Handle the event
// ...

?>

Here’s an example of implementing all of the above described guidelines and recommendations in order to process webhooks from Ecwid in the most efficient way.