Webhooks are a way for web apps to get real-time notifications of some operations in Selz. Once you register a URI to receive webhooks, Selz will send an HTTP request to that URI every time there's a change for any of your app's registered users.
Type | Description |
---|---|
blog_post_created |
Occurs whenever a blog post is created |
blog_post_updated |
Occurs whenever a blog post is updated |
blog_post_deleted |
Occurs whenever a blog post is deleted |
category_created |
Occurs whenever a category is created |
category_updated |
Occurs whenever a category is updated |
category_deleted |
Occurs whenever a category is deleted |
customer_created |
Occurs whenever a customer is created |
customer_updated |
Occurs whenever a customer is updated |
customer_deleted |
Occurs whenever a customer is deleted |
discount_created |
Occurs whenever a discount is created |
discount_updated |
Occurs whenever a discount is updated |
discount_deleted |
Occurs whenever a discount is deleted |
order_payment_succeeded |
Occurs whenever an order payment succeeded |
order_completed |
Occurs whenever an order payment is completed |
product_created |
Occurs whenever a product is created |
product_updated |
Occurs whenever a product is updated |
product_deleted |
Occurs whenever a product is deleted |
product_soldout |
Occurs whenever a product is sold out |
product_variant_soldout |
Occurs whenever a product variant is sold out |
Webhooks can be verified by calculating a digital signature.
Each Webhook request includes a HTTP_X_SELZ_SIGNATURE
header along with the data sent in the request.
To verify that the request came from Selz, compute the HMAC digest according to the following algorithm and compare it to the value in the HTTP_X_SELZ_SIGNATURE
header.
If they match, you can be sure that the Webhook was sent from Selz and the data has not been compromised.
<?php
$json = json_decode(file_get_contents('php://input'), TRUE);
$message = $json["timestamp"].$json["token"];
if(!ValidateSignature($message)){
header("HTTP/1.1 400 BAD REQUEST");
die();
}
// Do something with webhook payload
$orderId = $json["data"]["id"];
header("HTTP/1.1 200 OK");
die();
function CreateSignature($message) {
$key = 'your_webhook_verification_key';
$aMessage = iconv(iconv_get_encoding("internal_encoding"), "ASCII", $message);
$aKey = iconv(iconv_get_encoding("internal_encoding"), "ASCII", $key);
$sig = hash_hmac('sha256', $aMessage, $aKey, true);
return base64_encode($sig);
}
function ValidateSignature($message){
$signature = $_SERVER["HTTP_X_SELZ_SIGNATURE"];
$signatureToCompare = CreateSignature($message);
return ($signature == $signatureToCompare);
}
?>
const crypto = require('crypto');
app.post('/webhook', (request, response) => {
// https://github.com/visionmedia/express/wiki/Migrating-from-3.x-to-4.x
// express 3.x: app.use(express.bodyParser());
// express 4.x: app.use(bodyParser());
const json = request.body;
response.send(200);
const signature = request.headers['x-selz-signature'];
const message = `${json['timestamp']}${json['token']}`;
if (validateSignature(message, signature)) {
console.log('OK');
} else {
console.log('ERROR');
}
});
const createSignature = message => {
const key = 'your_webhook_verification_key';
return crypto
.createHmac('sha256', key)
.update(message, 'ascii')
.digest('base64');
};
const validateSignature = (message, signature) => signature === createSignature(message);
To make sure you can always respond within ten seconds, you should always do your work on a separate thread (as in the simple example above) or asynchronously using a queue.
When a user makes a number of changes in rapid succession, your app is likely to receive multiple notifications for the same user at roughly the same time. If you're not careful about how you manage concurrency, your app can end up processing the same changes for the same user more than once. For some applications, this is not a serious issue. Work that can be repeated without changing the outcome is called idempotent. If your app's actions are always idempotent, you don't need to worry much about concurrency. Unfortunately, not every app can be made idempotent easily. For example, suppose you have an app that sends email every time a certain file is changed. To avoid sending duplicate emails, you need to make sure that your app never processes the same user on multiple threads/processes at the same time.