> For the complete documentation index, see [llms.txt](https://roqqu-api-services.gitbook.io/ras/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://roqqu-api-services.gitbook.io/ras/webhooks/decrypt-webhook-body.md).

# Decrypt Webhook Body

To decrypt the webhook body, use the helper function below:

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
async function decrypt(hash, key, iv) {

    try {

        const content = hash;
        const decipher = await crypto.createDecipheriv(algorithm, key.substring(0, 32), Buffer.from(iv, 'hex'));
        const decrypted = Buffer.concat([decipher.update(Buffer.from(content, 'hex')), decipher.final()]);
        try {
            return JSON.parse(decrypted.toString());
        } catch (e) {
            return decrypted.toString()
        }
    } catch (err) {

        return false;
    }
}
﻿

// Usage
const decrypted = await decrypt(
  webhookBody.hash,
  yourApiKey,
  webhookHeaders['x-api-key'],
);
```

{% endtab %}

{% tab title="Python" %}

```python
from Crypto.Cipher import AES
import json

def decrypt_webhook(hash_hex, key, iv_hex):
    try:
        # Convert hex to bytes
        ciphertext = bytes.fromhex(hash_hex)
        iv_bytes = bytes.fromhex(iv_hex)
        key_bytes = key[:32].encode('utf-8')

        # AES-CTR doesn't need a "Counter" object if you provide the full 16-byte IV 
        # as the initial value (nonce) in some versions, but standard way is:
        cipher = AES.new(key_bytes, AES.MODE_CTR, nonce=b'', initial_value=iv_bytes)
        
        decrypted_bytes = cipher.decrypt(ciphertext)
        decrypted_str = decrypted_bytes.decode('utf-8')

        try:
            return json.loads(decrypted_str)
        except:
            return decrypted_str
    except Exception as e:
        print(f"Error: {e}")
        return False

# Usage
decrypted = decrypt_webhook(webhook_body['hash'], your_api_key, webhook_headers['x-api-key'])
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Text;
using System.Security.Cryptography;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        // Example Usage
        string hash = "6d32159e"; // Replace with your hex hash
        string key = "my-secret-key-12345678901234567";
        string iv = "0123456789abcdef0123456789abcdef";

        object result = DecryptWebhook(hash, key, iv);
        Console.WriteLine("Result: " + result);
    }

    public static object DecryptWebhook(string hashHex, string keyString, string ivHex)
    {
        try
        {
            // 1. Prepare Key (Substring 0, 32)
            string shortKey = keyString.Length > 32 ? keyString.Substring(0, 32) : keyString;
            byte[] keyBytes = Encoding.UTF8.GetBytes(shortKey);

            // 2. Convert Hex to Bytes (Manual helper for older environments)
            byte[] ciphertext = StringToByteArray(hashHex);
            byte[] ivBytes = StringToByteArray(ivHex);

            // 3. AES-CTR Manual Implementation using ECB
            // (CTR mode is just ECB-encrypting the IV/Counter and XORing it with the data)
            byte[] decrypted = new byte[ciphertext.Length];
            
            using (var aes = Aes.Create())
            {
                aes.Mode = CipherMode.ECB;
                aes.Padding = PaddingMode.None;
                
                using (var encryptor = aes.CreateEncryptor(keyBytes, null))
                {
                    byte[] counter = (byte[])ivBytes.Clone();
                    byte[] keystream = new byte[16];

                    for (int i = 0; i < ciphertext.Length; i++)
                    {
                        if (i % 16 == 0)
                        {
                            encryptor.TransformBlock(counter, 0, 16, keystream, 0);
                            IncrementCounter(counter);
                        }
                        decrypted[i] = (byte)(ciphertext[i] ^ keystream[i % 16]);
                    }
                }
            }

            string decryptedStr = Encoding.UTF8.GetString(decrypted);

            // 4. Simple JSON Check (Manual check since System.Text.Json is missing)
            if ((decryptedStr.Trim().StartsWith("{") && decryptedStr.Trim().EndsWith("}")) || 
                (decryptedStr.Trim().StartsWith("[") && decryptedStr.Trim().EndsWith("]")))
            {
                return decryptedStr;
            }
            
            return decryptedStr;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            return false;
        }
    }

    // Helper: Converts Hex String to Byte Array
    private static byte[] StringToByteArray(string hex)
    {
        int NumberChars = hex.Length;
        byte[] bytes = new byte[NumberChars / 2];
        for (int i = 0; i < NumberChars; i += 2)
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
        return bytes;
    }

    // Helper: Increments the CTR counter
    private static void IncrementCounter(byte[] counter)
    {
        for (int i = counter.Length - 1; i >= 0; i--)
        {
            if (++counter[i] != 0) break;
        }
    }
}
```

{% endtab %}
{% endtabs %}

### Required Parameters <a href="#required-parameters" id="required-parameters"></a>

1. **hash** - This is returned from the webhook endpoint
2. **key** - Your Live API key is available on your dashboard
3. **iv** - This is passed in the webhook header as x-api-key
4. **algorithm** - The algorithm used is `aes-256-ctr`
