webhooks

Express (with signature verification)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "webhooks" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-webhooks

Webhooks

Receiving Webhooks

Express (with signature verification)

app.post('/webhooks/stripe', express.raw({ type: 'application/json' }), (req, res) => { const signature = req.headers['stripe-signature']!; const event = stripe.webhooks.constructEvent(req.body, signature, WEBHOOK_SECRET);

// Idempotency: check if already processed const existing = await db.webhookEvent.findUnique({ where: { eventId: event.id } }); if (existing) return res.json({ received: true });

// Process switch (event.type) { case 'checkout.session.completed': await fulfillOrder(event.data.object); break; }

// Mark as processed await db.webhookEvent.create({ data: { eventId: event.id, type: event.type } }); res.json({ received: true }); });

Generic HMAC Verification

import { createHmac, timingSafeEqual } from 'crypto';

function verifyWebhookSignature(payload: string, signature: string, secret: string): boolean { const expected = createHmac('sha256', secret).update(payload).digest('hex'); return timingSafeEqual(Buffer.from(signature), Buffer.from(sha256=${expected})); }

app.post('/webhooks/github', express.raw({ type: '/' }), (req, res) => { const sig = req.headers['x-hub-signature-256'] as string; if (!verifyWebhookSignature(req.body.toString(), sig, GITHUB_SECRET)) { return res.status(401).json({ error: 'Invalid signature' }); } // Process event... res.status(200).json({ received: true }); });

Sending Webhooks

class WebhookDispatcher { async dispatch(url: string, event: WebhookEvent, secret: string) { const payload = JSON.stringify(event); const signature = createHmac('sha256', secret).update(payload).digest('hex');

const response = await fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-Webhook-Signature': `sha256=${signature}`,
    'X-Webhook-Id': event.id,
    'X-Webhook-Timestamp': new Date().toISOString(),
  },
  body: payload,
  signal: AbortSignal.timeout(10000),
});

if (!response.ok) throw new WebhookDeliveryError(response.status);

} }

Retry with Exponential Backoff

// Use job queue for reliable delivery await webhookQueue.add('deliver', { url: subscription.url, event: { id: uuid(), type: 'order.created', data: order }, secret: subscription.secret, }, { attempts: 5, backoff: { type: 'exponential', delay: 60000 }, // 1m, 2m, 4m, 8m, 16m });

Webhook Event Schema

interface WebhookEvent { id: string; // Unique event ID (for idempotency) type: string; // 'order.created', 'user.deleted' timestamp: string; // ISO 8601 data: unknown; // Event payload version: string; // API version }

Anti-Patterns

Anti-Pattern Fix

No signature verification Always verify HMAC signature

Processing before responding 200 Respond 200 immediately, process async

No idempotency check Store processed event IDs

Using parsed body for verification Use raw body for signature check

No retry on send failures Use job queue with exponential backoff

Synchronous webhook delivery Dispatch via background job queue

Production Checklist

  • HMAC signature verification on receive

  • Raw body parsing (not JSON-parsed) for signature

  • Idempotency: deduplicate by event ID

  • Respond 200 before processing

  • Retry with exponential backoff on send

  • Dead letter queue for failed deliveries

  • Webhook event log for debugging

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

Stripe Production Engineering

Provides best practices and code patterns for building, scaling, and operating production Stripe payment systems from checkout to enterprise billing.

Registry SourceRecently Updated
3170Profile unavailable
Coding

ScrapeSense.com Developer

Comprehensive ScrapeSense public API developer skill for scan orchestration, places extraction, campaign lifecycle, email cleaning, billing endpoints, and AP...

Registry SourceRecently Updated
3460Profile unavailable
Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review