Test Stripe webhooks locally
Tofu gives you one Stripe webhook endpoint that never changes, while your local handler can move between ports, apps, and branches without touching the Stripe dashboard.
$ tofu hooks create stripe --name "Stripe"$ tofu hooks url stripe$ tofu targets set local "http://127.0.0.1:3000/api/webhooks/stripe" --hook stripe$ tofu watch stripeSetup checklist
- Paste the provider URL into the Stripe webhook endpoint.
- Keep your handler on the raw request body so Stripe signature verification still works.
Keep signature verification working
Stripe signs every webhook with the secret you configure in the Stripe dashboard. The signature covers the raw request body, so your handler must read the body as bytes before any JSON parsing. Tofu forwards the body unchanged, including the Stripe-Signature header.
Diagnose failed deliveries
When a Stripe delivery returns a non-2xx response, Tofu can diagnose the failure from retained request headers, payload preview, target status, and target response preview. The Stripe pack looks for raw-body mutation, signing-secret mismatches, test/live mode hints, unhandled event types, and Stripe retry behavior.
Replay events while iterating
When you change your checkout.session.completed or invoice.payment_failedhandler, replay the latest real event rather than asking Stripe to send another test. The signature still verifies, and you avoid generating noise in Stripe's event log.
Common pitfalls
- Framework middleware (Express
body-parser, Next.js route handlers with default JSON parsing) can replace the request body. Reach for the raw body API your framework exposes. - If you have multiple Stripe accounts (live and test), create one Tofu hook per account so the signing secrets do not collide on the same handler.