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
Configure Endpoint
Set up a webhook endpoint URL in your Givebutter Dashboard that can receive POST requests
Event Occurs
An event happens in your account (e.g., a donation is made)
Givebutter Sends Request
Givebutter sends an HTTPS POST request to your endpoint with event data
Your App Processes
Your application receives and processes the webhook payload
Respond with 200
Your endpoint responds with a 200 status code to acknowledge receipt
Setting Up Webhooks
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 });
});
Configure in Dashboard
Add your endpoint URL in Givebutter Dashboard: - Go to Settings → Integrations →
Webhooks - Click Add Webhook Endpoint - Enter your endpoint URL (must be HTTPS) - Select
which events to receive - Save your webhook
Verify Signature
Verify webhook authenticity using the signature header (see Security )
Test
Use the Dashboard to send test events to your endpoint
Handling Webhooks
Basic Handler
Node.js / Express
Python / Flask
PHP
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:
Go to Settings → Webhooks
Select your webhook endpoint
Click Send Test Event
Choose event type
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