🔥 0
0
Lesson 1 of 5 15 min +150 XP

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

🔗
Endpoint URL

Where to send events

📋
Event Type

What happened

📦
Payload

Event data (JSON)

🔐
Signature

Verify authenticity

Polling vs Webhooks: The Numbers

Let's compare checking for new orders every minute vs receiving webhooks:

43,200
Polling API calls/day
(1 per minute)
~100
Webhook calls/day
(only when orders happen)
432x
More efficient
(fewer wasted calls)

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

Why Stripe Requires Webhooks

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.

🧠 Quick Quiz

Test your understanding of this lesson.

1

What is a webhook?

2

What is the main advantage of webhooks over polling?

3

In a webhook system, who initiates the HTTP request?