stripe-webhook-securitylisted
Install: claude install-skill GoldenWing-360/claude-security-skills
# Stripe Webhook Security
Stripe webhooks are how a payment provider tells your backend that things happened. If they are wrong — forged, replayed, or processed twice — you ship product without payment, or charge customers twice, or skip a refund. This skill covers the patterns that prevent that.
Applies to Stripe (and largely to other PSPs with similar webhook designs: Paddle, Mollie, Adyen). Examples are Node/Express; the principles port.
## When to invoke
- Wiring a new Stripe webhook endpoint
- Adding a new event type to an existing handler
- Investigating a payments incident (mismatched orders, double-charge, missing refunds)
- Migrating from test mode to live mode
- Auditing an inherited integration
## The three rules
A webhook handler must do all three of these. Skipping any one is a bug.
1. **Verify the signature** before trusting any field
2. **Be idempotent** — receiving the same event twice does nothing extra
3. **Use the event as a hint, not a source of truth** for high-value actions
## Rule 1 — Signature verification (on raw body)
Stripe signs the request with `STRIPE_WEBHOOK_SECRET`. Verification only works on the **exact raw bytes** Stripe sent — JSON-parsing first destroys the signature.
```ts
// Express — register the raw-body middleware ONLY for the webhook route
import express from 'express';
import Stripe from 'stripe';
const app = express();
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2024-12-18.acacia' });
// IMPO