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


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

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

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

    return deciphered_message.toString();

Last updated