Webhook handling

When you get a webhook from Ecwid API, you need to let Ecwid know that your server received it, verify its identity, and parse the data inside for further automation. We refer to this process as webhook handling.

Respond with status 200

If Ecwid can't confirm that your application received a webhook, it will try to resend a webhook for the next 24h. We refer to this process as resend policy. To let Ecwid know about the successful webhook delivery, your app must return a 200 OK HTTP status code in response to a webhook. Otherwise, Ecwid will continue sending the same webhook to your server:

Response HTTP codeResult
200Webhook counts as delivered.
201, 202, any other 2xx or 3xxWebhook counts as not delivered.

Ecwid tries to connect with your webhookUrl and to receive a response for a limited time for each delivery. If your app fails to respond in time, Ecwid calls a timeout and counts this webhook as not delivered:

Timeout in
webhookUrl connection time3 sec
Time to receive a response from webhookUrl10 sec

If the webhook is not delivered, Ecwid continues with the resend policy. We'll make several attempts to deliver a webhook to your server for the next day following the schedule described above:

Attempt №Schedule
115 min
230 min
345 min
41h
52h
63h
74h
85h
96h
......
2724h

Parse webhook data and verify its identity

After responding with 200 OK HTTP code, your application must decode and parse the webhook body, and verify that it comes from Ecwid.

Code example for webhook body decoding and parsing:

$decodedBody = json_decode($requestBody, true);

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

Code example for webhook verification:

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;
        }
    }
}

After completing these steps, you can safely process the data received in the webhook.

Template for webhook handling

Now let's combine the previous steps in one example. Use this code as a starting point for developing webhook handling for your app:

<?php 

$requestBody = file_get_contents('php://input'); // Get contents of webhook request
$client_secret = 'abcde123456789'; // your client_secret value on https://my.ecwid.com/#develop-apps page; NOT your 'secret_*' access token.

// Parse webhook data and reply with 200OK to Ecwid
$decodedBody = json_decode($requestBody, true);

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

http_response_code(200);

// (Optional) Filter out events you're not interested in.
// If you receive webhooks for events you don't need, email us to disable these events
// Our email: [email protected]
if ($eventType !== 'order.updated') {
    exit;
}

// (Optional) Authenticate webhook signature to verify it came from Ecwid
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;
        }
    }
}

// If webhook was authenticated, get data from $decodedBody and handle the event
//
// If it's not, email us and provide us with logs and details about failed event 

?>