For the complete documentation index, see llms.txt. This page is also available as Markdown.

Webhooks

This section shows you how our webhook service works, what it delivers and explains its messages.

Pre-requisites

To properly receive incoming webhooks, your server should provide an endpoint supporting:

  • POST requests are either raw in text/plain if message was encrypted by your configured secret or application/json if no secret was set

You can use a service like e.g. https://webhook.site/ to test receiving webhooks from your developer dashboard.

Security / Encryption

Webhooks are a crucial node to ensure the functionality of your integration, as such, they can be the target of a malicious user aiming to disrupt the service. In order to protect your application from these threats, you must include a 32 bytes-long secret in your webhook configuration, which will be used to encrypt the request body.

When you enable Encryption, the Webhook message is sent as text/plain. Below you'll find an example of how to decipher an incoming webhook request. The cipher initialization vector will be sent over as a 16 bytes metadata (header) of the response.

import * as crypto from 'crypto';

export class Decipher {
  decipherAES_256_CBC(request: any) {
    const CIPHER_KEY = 'YOUR-PLAIN-KEY';
    const BASE64_PLAIN_IV = request.headers['x-pvt-cipher-iv'];
    const BASE64_CIPHERED_MESSAGE = request.body;

    const BUFFER_KEY = Buffer.from(CIPHER_KEY);
    const BUFFER_IV = Buffer.from(BASE64_PLAIN_IV, 'base64');
    const BUFFER_CIPHERED_MESSAGE = Buffer.from(BASE64_CIPHERED_MESSAGE, 'base64');

    const DECIPHER = crypto.createDecipheriv('aes-256-cbc', BUFFER_KEY, BUFFER_IV);
    DECIPHER.setAutoPadding(true);

    let deciphered_message = DECIPHER.update(BUFFER_CIPHERED_MESSAGE, 'hex', 'utf8');

    deciphered_message += DECIPHER.final('utf-8');

    return deciphered_message.toString();
  }
}

Last updated