Skip to main content
Coming Soon - Webhook functionality is currently in development. This page documents the planned implementation.
Webhooks allow your application to receive real-time notifications when events occur in your Givebutter account, such as new donations, campaign updates, or ticket purchases. Instead of repeatedly polling the API for changes, webhooks push data to your application the moment an event happens.

How Webhooks Work

1

Configure Endpoint

Set up a webhook endpoint URL in your Givebutter Dashboard that can receive POST requests
2

Event Occurs

An event happens in your account (e.g., a donation is made)
3

Givebutter Sends Request

Givebutter sends an HTTPS POST request to your endpoint with event data
4

Your App Processes

Your application receives and processes the webhook payload
5

Respond with 200

Your endpoint responds with a 200 status code to acknowledge receipt

Setting Up Webhooks

1

Create Endpoint

Set up an HTTPS endpoint in your application to receive webhook POST requests:
app.post('/webhooks/givebutter', async (req, res) => {
  const event = req.body;

  // Process the event
  console.log('Received event:', event.type);

  // Respond with 200
  res.status(200).json({ received: true });
});
2

Configure in Dashboard

Add your endpoint URL in Givebutter Dashboard: - Go to SettingsIntegrationsWebhooks - Click Add Webhook Endpoint - Enter your endpoint URL (must be HTTPS) - Select which events to receive - Save your webhook
3

Verify Signature

Verify webhook authenticity using the signature header (see Security)
4

Test

Use the Dashboard to send test events to your endpoint

Handling Webhooks

Basic Handler

app.post('/webhooks/givebutter', async (req, res) => {
  const event = req.body;

// Always respond quickly to avoid timeouts
res.status(200).json({ received: true });

// Process asynchronously
try {
switch (event.type) {
case 'transaction.created':
await handleNewTransaction(event.data);
break;
case 'transaction.refunded':
await handleRefund(event.data);
break;
case 'contact.created':
await handleNewContact(event.data);
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
} catch (error) {
console.error('Error processing webhook:', error);
}
});

async function handleNewTransaction(transaction) {
// Save to database
await db.transactions.create({
givebutter_id: transaction.id,
amount: transaction.amount,
donor_email: transaction.donor.email,
campaign_id: transaction.campaign.id
});

// Send thank you email
await sendThankYouEmail(transaction.donor.email, transaction.amount);
}

Security

Verifying Webhook Signatures

Givebutter signs all webhook requests so you can verify they’re authentic:
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}

app.post('/webhooks/givebutter', (req, res) => {
const signature = req.headers['x-givebutter-signature'];
const webhookSecret = process.env.GIVEBUTTER_WEBHOOK_SECRET;

// Verify signature
if (!verifyWebhookSignature(req.body, signature, webhookSecret)) {
return res.status(401).json({ error: 'Invalid signature' });
}

// Process webhook
const event = req.body;
// ...
});

Best Practices

Always respond with a 200 status code within 10 seconds. Process the webhook asynchronously to avoid timeouts:
app.post('/webhooks/givebutter', async (req, res) => {
  // Respond immediately
  res.status(200).json({ received: true });

  // Process asynchronously
  processWebhookAsync(req.body).catch(err => {
    console.error('Webhook processing error:', err);
  });
});
Use the event id to prevent processing the same event twice:
async function processWebhook(event) {
  // Check if already processed
  const exists = await db.processedEvents.findOne({ id: event.id });
  if (exists) {
    console.log(`Event ${event.id} already processed`);
    return;
  }

  // Process event
  await handleEvent(event);

  // Mark as processed
  await db.processedEvents.create({ id: event.id, processed_at: new Date() });
}
If processing fails, retry with exponential backoff:
async function processWithRetry(event, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      await processEvent(event);
      return; // Success
    } catch (error) {
      if (attempt === maxRetries - 1) {
        // Log final failure
        console.error(`Failed after ${maxRetries} attempts:`, error);
        await logFailedWebhook(event, error);
      } else {
        // Wait before retry
        await new Promise(resolve =>
          setTimeout(resolve, Math.pow(2, attempt) * 1000)
        );
      }
    }
  }
}
Track and alert on webhook processing failures:
async function processWebhook(event) {
  try {
    await handleEvent(event);

    // Log success
    await metrics.increment('webhooks.success', { type: event.type });
  } catch (error) {
    // Log failure
    console.error('Webhook processing failed:', error);
    await metrics.increment('webhooks.failure', { type: event.type });

    // Alert if too many failures
    const recentFailures = await getRecentFailureCount();
    if (recentFailures > 10) {
      await sendAlert('High webhook failure rate detected');
    }
  }
}
Webhook endpoints must use HTTPS. HTTP endpoints will be rejected:
✅ https://myapp.com/webhooks/givebutter
❌ http://myapp.com/webhooks/givebutter
For local development, use tools like ngrok to create HTTPS tunnels.

Testing Webhooks

Local Development

Use ngrok to test webhooks locally:
# Install ngrok
npm install -g ngrok

# Start your local server
node server.js # Running on http://localhost:3000

# Create HTTPS tunnel
ngrok http 3000

# Use the HTTPS URL in Givebutter Dashboard
# https://abc123.ngrok.io/webhooks/givebutter

Test Events

Send test events from the Givebutter Dashboard:
  1. Go to SettingsWebhooks
  2. Select your webhook endpoint
  3. Click Send Test Event
  4. Choose event type
  5. Verify your endpoint receives and processes the test event

Need Help?

Webhook support is coming soon. For early access or questions:
  • Email: [email protected]
  • Subject: “Webhook Early Access Request”
  • Include: Your use case and expected webhook volume

Next Steps