Webhooks allow your application to receive real-time notifications when important events happen in your Quickbutik store. Instead of constantly polling the API, webhooks push data to your application immediately when events occur.

Common use cases:

  • Sync new orders to your fulfillment system instantly
  • Update inventory levels across multiple platforms
  • Send custom order confirmations or notifications
  • Trigger automated workflows and integrations

How Webhooks Work

When an event occurs in your store (like a new order), Quickbutik sends an HTTP GET request to your configured webhook URL with event details as query parameters.

Quick Setup

1

Create webhook endpoint

Set up an endpoint in your application to receive webhook notifications

app.get('/webhooks/quickbutik', (req, res) => {
  const { event_type, order_id, product_id } = req.query;
  
  // Always respond quickly
  res.status(200).send('OK');
  
  // Process webhook asynchronously
  processWebhook(event_type, { order_id, product_id });
});
2

Configure in Quickbutik

Enable webhooks in your Quickbutik Control Panel under Settings → Webhooks and add your endpoint URL

3

Handle events

Process the webhook events in your application based on the event type

Event Structure

All webhook requests are sent as GET requests with the following query parameters:

ParameterDescriptionExample
event_typeThe type of event that occurredorder.new, product.update
order_idOrder ID (for order events)12345
product_idProduct ID (for product events)67890

Example Webhook Request

GET /your-webhook-endpoint?event_type=order.new&order_id=12345
Host: your-domain.com
User-Agent: Quickbutik-Webhooks/1.0

Complete Example

Here’s a complete webhook handler that processes different event types:

const express = require('express');
const QuickbutikAPI = require('./quickbutik-api');

const app = express();
const api = new QuickbutikAPI(process.env.QUICKBUTIK_API_KEY);

app.get('/webhooks/quickbutik', async (req, res) => {
  const { event_type, order_id, product_id } = req.query;
  
  console.log(`Received webhook: ${event_type}`, { order_id, product_id });
  
  // Acknowledge webhook immediately (important!)
  res.status(200).send('OK');
  
  try {
    // Process webhook asynchronously
    switch (event_type) {
      case 'order.new':
        await handleNewOrder(order_id);
        break;
      case 'order.done':
        await handleOrderShipped(order_id);
        break;
      case 'order.cancelled':
        await handleOrderCancelled(order_id);
        break;
      case 'product.add':
        await handleProductAdded(product_id);
        break;
      case 'product.update':
        await handleProductUpdated(product_id);
        break;
      case 'product.delete':
        await handleProductDeleted(product_id);
        break;
      default:
        console.log(`Unhandled event type: ${event_type}`);
    }
  } catch (error) {
    console.error(`Error processing webhook ${event_type}:`, error);
    
    // In production, add to retry queue or send alert
    await handleWebhookError(event_type, { order_id, product_id }, error);
  }
});

async function handleNewOrder(orderId) {
  console.log(`Processing new order: ${orderId}`);
  
  // Fetch complete order details
  const orders = await api.getOrders({ 
    order_id: orderId,
    include_details: true 
  });
  
  if (orders && orders.length > 0) {
    const order = orders[0];
    
    // Your business logic here
    await processNewOrder(order);
    console.log(`Successfully processed order ${orderId}`);
  }
}

async function handleProductUpdated(productId) {
  console.log(`Processing product update: ${productId}`);
  
  // Fetch updated product details
  const products = await api.getProducts({ 
    product_id: productId,
    include_details: true 
  });
  
  if (products && products.length > 0) {
    const product = products[0];
    
    // Your business logic here
    await syncProductToExternalSystem(product);
    console.log(`Successfully synced product ${productId}`);
  }
}

app.listen(3000, () => {
  console.log('Webhook server running on port 3000');
});

Best Practices

Respond Quickly

Always respond with 200 OK within 10 seconds to acknowledge receipt. Process the actual work asynchronously.

Handle Retries

Webhooks may be sent multiple times if your endpoint doesn’t respond. Make your processing idempotent.

Validate Events

Verify webhook authenticity in production environments using request validation.

Error Handling

Implement proper error handling and retry mechanisms for failed webhook processing.

Important Considerations:

  • Webhooks are sent as GET requests (not POST)
  • Always acknowledge webhooks quickly to avoid retries
  • Events may be delivered more than once - ensure idempotent processing
  • Use the API to fetch complete data when processing webhooks

Testing Webhooks

Use tools like ngrok to test webhooks locally:

# Install ngrok
npm install -g ngrok

# Start your webhook server
node webhook-server.js

# In another terminal, expose your local server
ngrok http 3000

# Use the ngrok URL in your Quickbutik webhook settings
# Example: https://abc123.ngrok.io/webhooks/quickbutik

Next Steps