Notification
Webhook

Webhook Integration

This guide explains how to set up and handle webhooks for Xellar's notification service.

Setting Up Your Webhook

Configure Webhook URL

Webhook Configuration

  1. Navigate to the "Developer" section in your Xellar dashboard
  2. Select "Webhook" from the menu
  3. Enter your webhook URL in the "Notification Webhook URL" field
  4. Click "Save" to store your configuration

Security

Signature Verification

All webhook requests include a signature in the x-xellar-signature header. You should always verify this signature to ensure the request came from Xellar.

Here's how to verify the signature:

const crypto = require('crypto');
 
const verifyWebhookSignature = (signature, body) => {
  const publicKey = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0NCk1Db3dCUVlESzJWd0F5RUFsRHUzVWMzenFvTGhhd1dHQnBuMU5XK0E4WFUwY2swSGpqdUFmSDZDekZjPQ0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tDQo="
  // Use this public key to verify webhooks from Xellar
 
  const verify = crypto.verify(
    null,
    Buffer.from(JSON.stringify(body)),
    Buffer.from(publicKey, 'base64'),
    Buffer.from(signature, 'base64')
  );
  return verify;
};
 
// Example usage in Express.js
app.post('/webhook', express.json(), (req, res) => {
  const signature = req.headers['x-xellar-signature'];
  
  if (!verifyWebhookSignature(signature, req.body)) {
    return res.status(401).send('Invalid signature');
  }
 
  // Process the webhook data
  console.log('Verified webhook data:', req.body);
  res.status(200).send('OK');
});

Webhook Data Format

EVM Networks

Webhook payload for EVM-compatible networks:

interface EVMWebhookData {
  id: string;
  createdAt: string;
  message: string;
  data: {
    rawData: {
      blockchain_type: string,
      value: string,
      chainId: number,
      status: boolean,
      transactionHash: string,
      transactionIndex: number,
      blockHash: string,
      blockNumber: number,
      from: string,
      to: string,
      contractAddress?: string,
      cumulativeGasUsed: number,
      gasUsed: number,
      logs: {
        address: string,
        data: string,
        topics: string[],
        logIndex: number,
        transactionIndex: number,
        transactionHash: string,
        blockHash: string,
        blockNumber: number,
      }[],
      logsBloom: string,
      events?: {
        [eventName: string]: {
          event: string,
          address: string,
          returnValues: any,
          logIndex: number,
          transactionIndex: number,
          transactionHash: string,
          blockHash: string,
          blockNumber: number,
          raw?: {
            data: string,
            topics: any[]
          },
        },
      },
    },
    filteredData: {
      from: string,
      to: string,
      value: string,
      txHash: string,
      chainId: number,
      blockchain_type: string,
      tokenAddress: string,
    },
  };
}

TRON Network

Webhook payload for TRON network:

interface TronWebhookData {
  id: string;
  createdAt: string;
  message: string;
  data: {
    rawData: {
      status: boolean,
      transactionHash: string,
      transactionIndex: number,
      blockHash: string,
      blockNumber: number,
      from: string,
      to: string,
      type: string,
      contractAddress?: string,
      cumulativeGasUsed: string,
      effectiveGasPrice: string,
      gasUsed: string,
      logs: {
        address: string,
        data: string,
        topics: string[],
        logIndex: number,
        removed: boolean,
        transactionIndex: number,
        transactionHash: string,
        blockHash: string,
        blockNumber: number,
      }[],
      logsBloom: string,
    },
    filteredData: {
      from: string,
      to: string,
      value: string,
      txHash: string,
      chainId: number,
      blockchain_type: string,
      tokenAddress: string,
      tokenSymbol: string,
    },
  };
}

Example Webhook Responses

Token Transfer (EVM)

{
  "id": "webhook_1234567890",
  "createdAt": "2024-03-20T10:30:00Z",
  "message": "ERC20 token transfer detected",
  "data": {
    "rawData": {
      "blockchain_type": "evm",
      "value": "0",
      "chainId": 1,
      "status": true,
      "transactionHash": "0x123...",
      "from": "0xabc...",
      "to": "0xdef...",
      "contractAddress": "0x789...",
      "logs": [
        {
          "address": "0x789...",
          "data": "0x000000000000000000000000000000000000000000000000000000174876e800",
          "topics": [
            "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
            "0x000000000000000000000000abc...",
            "0x000000000000000000000000def..."
          ],
          "logIndex": 0,
          "transactionIndex": 5,
          "transactionHash": "0x123...",
          "blockHash": "0x456...",
          "blockNumber": 12345678
        }
      ],
      "events": {
        "Transfer": {
          "event": "Transfer",
          "address": "0x789...",
          "returnValues": {
            "from": "0xabc...",
            "to": "0xdef...",
            "value": "100000000000"
          },
          "logIndex": 0,
          "transactionIndex": 5,
          "transactionHash": "0x123...",
          "blockHash": "0x456...",
          "blockNumber": 12345678
        }
      }
    },
    "filteredData": {
      "from": "0xabc...",
      "to": "0xdef...",
      "value": "100",
      "txHash": "0x123...",
      "chainId": 1,
      "blockchain_type": "ethereum",
      "tokenAddress": "0x789..."
    }
  }
}

Native Transfer (TRON)

{
  "id": "webhook_0987654321",
  "createdAt": "2024-03-20T10:35:00Z",
  "message": "Native TRX transfer detected",
  "data": {
    "rawData": {
      "status": true,
      "transactionHash": "123abc...",
      "from": "T123...",
      "to": "T456...",
      "type": "Transfer",
      "value": "1000000",
      "blockNumber": 987654,
      "blockHash": "block123...",
      "transactionIndex": 3,
      "cumulativeGasUsed": "20000",
      "effectiveGasPrice": "420",
      "gasUsed": "20000",
      "logs": [],
      "logsBloom": "0x00..."
    },
    "filteredData": {
      "from": "T123...",
      "to": "T456...",
      "value": "1.0",
      "txHash": "123abc...",
      "chainId": 0,
      "blockchain_type": "tron",
      "tokenAddress": null,
      "tokenSymbol": "TRX"
    }
  }
}

Best Practices

  1. Signature Verification

    • Always verify the webhook signature
    • Store the public key securely
    • Reject requests with invalid signatures

  2. Error Handling

    • Implement proper error handling
    • Log invalid requests for debugging
    • Set up monitoring for webhook failures

  3. Processing

    • Process webhooks asynchronously
    • Implement idempotency checks
    • Store raw webhook data before processing

  4. Response

    • Respond quickly (within 5 seconds)
    • Return 2xx status code for successful receipt
    • Handle retries appropriately

Troubleshooting

Common Issues

  1. Invalid Signature

    • Verify you're using the correct public key
    • Check signature header name is correct
    • Ensure body is not modified before verification

  2. Missing Events

    • Verify notification service is enabled
    • Check wallet notification status
    • Confirm supported network

Need help? Contact our support team or check our documentation for more information.