Webhook Integration

Receive real-time notifications when payments are completed. Webhooks allow your application to be notified automatically when payment events occur.

Introduction to Webhooks

Webhooks are HTTP callbacks that notify your application a payment is successful. Instead of continuously polling our API to check if a payment has been completed, webhooks push this information to your server as soon as it happens.

Key Benefits

  • Receive real-time payment notifications
  • Reduce API calls and improve response time
  • Automatically update order status in your systems
  • Trigger fulfillment processes immediately after payment

Setting Up Webhooks

Step 1: Create a Webhook Endpoint

Create an HTTP endpoint on your server that can receive POST requests. This endpoint will process the webhook data sent by Stablio.

Step 2: Generate a Webhook Secret

In your Stablio dashboard, navigate to Settings → Webhook Secret and generate a new secret key. This key will be used to verify the authenticity of webhooks.

Security Best Practice

Store your webhook secret as an environment variable...

Step 3: Configure Webhook URL

If you are configuring a Pay by Link payment then your webhook is added on the Stablio dashboard during the configuration.

If, instead, you are configuring a Web Checkout payment, include your webhook URL in the PaymentWidget call:

const widget = new PaymentWidget({
    type: 'defaultPayment',
    vendorID: 'your_vendor_id',
    amount: 49.99,
    currency: 'USD',
    userID: 'customer123',
    webhook: 'https://your-server.com/webhook'
});

Standard HTTP Webhooks

Standard webhooks are sent as HTTP POST requests to the URL you specify. They include a signature header to verify authenticity.

Webhook Payload

The webhook payload contains information about the payment:

{
  "paymentID": "f116faae-bb86-456e-a393-cd6a0628d5fa",
  "userID": "customer123",
  "amount": 49.99,
  "currency": "USD",
  "timestamp": "2025-04-24T14:30:45.123Z",
}

Webhook Headers

Each webhook request includes the following headers:

Header Description
x-signature HMAC SHA-256 signature of the request payload
Content-Type Application/json

Verifying Webhook Signatures

To ensure webhooks are genuinely from Stablio, you should verify the signature using your Stablio webhook Secret. Here's an example using Express.js:

const express = require('express');
const crypto = require('crypto');
const app = express();

// Parse JSON bodies
app.use(express.json());

app.post('/webhook', async (req, res) => {
    const receivedSignature = req.headers['x-signature'];
            
    const data = req.body;
    const payload = {
        paymentID: data.paymentID,
        userID: data.userID,
        amount: data.amount,
        currency: data.currency,
        timestamp: data.timestamp,
    };
    
    const stringPayload = JSON.stringify(payload);
    const hmac = crypto.createHmac('sha256', YOUR_STABLIO_WEBHOOK_SECRET);
    hmac.update(stringPayload);
    const calculatedSignature = hmac.digest('hex');
    
    if (calculatedSignature === receivedSignature) {
        console.log('Webhook signature is valid! ✅');
    }
    else {
        console.log('Webhook signature is invalid! ❌');
    }
});

Discord Webhooks

Stablio also supports sending webhook notifications directly to Discord channels, allowing you to monitor payments without building a custom webhook endpoint.

Setting Up Discord Webhooks

  1. In your Discord server, go to Server Settings → Integrations → Webhooks
  2. Click New Webhook, give it a name and select the channel
  3. Copy the webhook URL
  4. If you are setting up a Pay by Link then paste it on the dashboard setup. If its a Web Checkout then add it as a parameter on the PaymentWidget call
  5. In your Stablio dashboard, go to Settings → Webhook Secret and get your unique Webhook secret to verify the payments call come from Stablio

Discord Webhook Messages

Payment notifications will be sent as rich embeds in your Discord channel, containing all relevant payment details.

Verification Using a Discord Bot

If you need to process Discord webhook notifications programmatically, you can set up a Discord bot to verify and handle these notifications:

const Discord = require('discord.js');
const crypto = require('crypto');
const client = new Discord.Client();

client.login('YOUR_DISCORD_BOT_TOKEN');

client.on('message', async (msg) => { 

    if(msg.channel.id == 'YOUR_WEBHOOK_CHANNEL_ID') {

        const embed = msg.embeds[0];
        const fields = embed.fields;

        // Extract all data from the embed
        const paymentID = fields.find(f => f.name === "Payment ID")?.value;
        const amount = fields.find(f => f.name === "Amount")?.value;
        const currency = fields.find(f => f.name === "Currency")?.value;
        const userID = fields.find(f => f.name === "User ID")?.value;
        const receivedSignature = fields.find(f => f.name === "Signature")?.value;
        const timestamp = new Date(embed.timestamp).toISOString();

        const secretKey = YOUR_STABLIO_WEBHOOK_SECRET;
  
        const payload = {
          paymentID,
          userID,
          amount,
          currency,
          timestamp
        };
        
        const stringPayload = JSON.stringify(payload);
        const hmac = crypto.createHmac('sha256', secretKey);
        hmac.update(stringPayload);
        const calculatedSignature = hmac.digest('hex');
        
        if (calculatedSignature === receivedSignature) {
             console.log('Webhook signature is valid! ✅');
        }
        else {
             console.log('Webhook signature is invalid! ❌');
        }
    
    }
})

Troubleshooting

Common Issues

Not Receiving Webhooks

  • Verify your server is publicly accessible
  • Check firewall settings aren't blocking incoming requests
  • Ensure you're using the correct webhook URL format

Signature Verification Fails

  • Confirm you're using the correct webhook secret
  • Ensure you're parsing the JSON correctly before verification
  • Check the payload structure matches exactly what's expected
  • Verify you're using SHA-256 for HMAC generation