Introduction to Webhooks
Imagine you're waiting for a package. You could check the front door every 5 minutes (polling), or you could wait for the doorbell to ring (webhooks).
Webhooks are the doorbell of the internet.
POLLING
"Is there an update yet?"
- Client repeatedly asks server
- Wastes API calls
- Delayed updates (poll interval)
- Higher server load
WEBHOOKS (Push)
"I'll tell you when something happens"
- Server notifies client
- Only calls when needed
- Real-time updates
- Efficient resource usage
How Webhooks Work
┌─────────────────┐ ┌─────────────────┐
│ Stripe │ │ Your App │
│ (Event Source)│ │ (Receiver) │
└────────┬────────┘ └────────┬────────┘
│ │
│ 1. Customer pays $99 │
│ ──────────────────────────────────> │
│ │
│ 2. Stripe processes payment │
│ │
│ 3. POST /webhooks/stripe │
│ { │
│ "type": "payment_intent.succeeded", │
│ "data": { "amount": 9900, ... } │
│ } │
│ ─────────────────────────────────────>│
│ │
│ 4. Your app updates database │
│ │
│ 5. HTTP 200 OK │
│ <─────────────────────────────────────│
│ │
Anatomy of a Webhook
A webhook is just an HTTP POST request with event data:
// Incoming webhook from Stripe
POST /webhooks/stripe HTTP/1.1
Host: yourapp.com
Content-Type: application/json
Stripe-Signature: t=1699999999,v1=abc123...
{
"id": "evt_1234567890",
"type": "payment_intent.succeeded",
"created": 1699999999,
"data": {
"object": {
"id": "pi_1234567890",
"amount": 9900,
"currency": "usd",
"customer": "cus_ABC123",
"status": "succeeded"
}
}
}
Key Components
Where to send events
What happened
Event data (JSON)
Verify authenticity
Polling vs Webhooks: The Numbers
Let's compare checking for new orders every minute vs receiving webhooks:
Real-World: GitHub Webhooks
When you push code to GitHub, webhooks can trigger:
// GitHub webhook payload for push event
{
"ref": "refs/heads/main",
"before": "abc123",
"after": "def456",
"repository": {
"full_name": "your-org/your-repo",
"default_branch": "main"
},
"pusher": {
"name": "developer",
"email": "dev@example.com"
},
"commits": [
{
"id": "def456",
"message": "Add new feature",
"author": { "name": "developer" },
"added": ["src/feature.js"],
"modified": ["package.json"]
}
]
}
Common GitHub Webhook Use Cases
| Event | Use Case |
|---|---|
| push | Trigger CI/CD pipeline, deploy code |
| pull_request | Run tests, add reviewers, update Jira |
| issues | Sync with project management tools |
| release | Publish to npm, update documentation |
Real-World: Stripe Webhooks
Stripe uses webhooks to notify you about payment events:
payment_intent.succeeded
Payment completed - fulfill the order, send receipt
invoice.payment_failed
Subscription payment failed - notify customer, retry
customer.subscription.deleted
Subscription cancelled - downgrade access, send survey
charge.dispute.created
Chargeback initiated - gather evidence, respond
Payment processing is asynchronous. A customer might pay via bank transfer (takes days), or a charge might be disputed weeks later. You can't just poll for these - webhooks ensure you're notified immediately.
Basic Webhook Receiver
Here's a simple Express.js webhook endpoint:
const express = require('express');
const app = express();
// Important: Use raw body for signature verification
app.post('/webhooks/stripe',
express.raw({ type: 'application/json' }),
(req, res) => {
const event = JSON.parse(req.body);
// Handle different event types
switch (event.type) {
case 'payment_intent.succeeded':
const paymentIntent = event.data.object;
console.log(`Payment succeeded: ${paymentIntent.id}`);
// Fulfill the order...
break;
case 'payment_intent.payment_failed':
console.log('Payment failed');
// Notify customer...
break;
default:
console.log(`Unhandled event type: ${event.type}`);
}
// Always respond quickly with 200
res.status(200).json({ received: true });
}
);
app.listen(3000, () => console.log('Webhook server running'));
When to Use Webhooks vs Polling
| Use Webhooks When | Use Polling When |
|---|---|
| Real-time updates are important | Webhooks aren't available |
| Events are infrequent | You need to sync large datasets |
| You want to reduce API calls | Network reliability is poor |
| Events trigger actions (side effects) | As a backup for missed webhooks |
Key Takeaways
- Webhooks = HTTP callbacks - Server pushes data when events occur
- More efficient than polling - Only network calls when needed
- Real-time updates - No polling interval delay
- Used everywhere - Stripe, GitHub, Slack, Twilio, and more
Next up: Webhook Security - Verifying that webhooks really came from who they claim.