🔔Webhook

How does it work?

Webhook is a kind of feedback method for payment information.

When withdrawal request status changes, a POST request is sent to the callback url specified when creating the request.

Webhook Request format

{
    "id": "9c3288f5-3aef-464d-a3fd-57c170163eab",
    "network": "BTC",
    "currency": "BTC",
    "address": "bc1qa7pumxw8rf7srg74adtks0ramsfv6c3vjvefrm",
    "amount": 0.05,
    "status": "pending",
    "order_id": "1",
     "additional_data": {
      "user_id": 255,
      "client_category": "Big"
    },
    "created_at": 1717434398,
    "updated_at": 1717434398
}
Parameter
Description

id*

Invoice id. Can be used to check it's status

amount*

Invoice amount in fiat currency

address*

Crypto wallet address where coins should be sent to

additional_data*

Any data provided during Withdrawal creation request. It will be null if you didn't specify it during invoice creation request.

created_at*

Unix time for invoice creation date

expires_at*

Unix time for invoice expiration date

* - mandatory parameter

Webhook verification

Every Webhook Request has two headers:

  • X-Silus-Sign — this header contains the sign itself which should be validated by your backend.

  • X-Silus-Timestamp — this is the header which contains time when the event was sent. It will be used for sign generation.

How to make sure sign in request is valid?

To be sure that sign in the request is valid you have to encode the entire webhook payload to JSON, then append X-Silus-Timestamp value at the end of the result string. The entire result should be converted to sha256 using HMAC with a secret key (the one you use to authenticate requests to Silus Withdrawals API).

The result string should be equal to the one in X-Silus-Sign header to be sure you are safe to perform any operations.

Sign generation example using PHP

<?php

$secretKey = 'iaB9JSOSrBsNTSPGZAnhNRkMO1MNsq2Qep70cyOiuZfQ0GYNurpCjU5LD5jVDiky';

$payload = file_get_contents('php://input');
$payload = json_decode($payload, true);
$time = $_SERVER['HTTP_X_SILUS_TIMESTAMP'];
$requestSign = $_SERVER['HTTP_X_SILUS_SIGN'];

$signData = json_encode($payload, JSON_UNESCAPED_UNICODE) . $time;

$expectedSign = hash_hmac('sha256', $signData, $secretKey);

echo hash_equals($requestSign, $expectedSign) ? 'Yay! Request is valid!' : 'Nah :( Didn\'t work';

Sign generation example using NodeJS

const crypto = require('crypto');
const http = require('http');

const secretKey = 'iaB9JSOSrBsNTSPGZAnhNRkMO1MNsq2Qep70cyOiuZfQ0GYNurpCjU5LD5jVDiky';

const server = http.createServer((req, res) => {
    let payload = '';

    req.on('data', chunk => {
        payload += chunk;
    });

    req.on('end', () => {
        const time = req.headers['x-silus-timestamp'];
        const requestSign = req.headers['x-silus-sign'];

        const signData = payload + time;

        const expectedSign = crypto.createHmac('sha256', secretKey).update(signData).digest('hex');

        if (crypto.timingSafeEqual(Buffer.from(requestSign), Buffer.from(expectedSign))) {
            res.writeHead(200, { 'Content-Type': 'text/plain' });
            res.end('Yay! Request is valid!');
        } else {
            res.writeHead(400, { 'Content-Type': 'text/plain' });
            res.end('Nah :( Didn\'t work');
        }
    });
});

server.listen(3000, () => {
    console.log('Server is listening on port 3000');
});

Last updated