The Webhooks page finds the routes your app receives webhooks on, warns about the usual mistakes, records every delivery with your app's answer, checks signatures, explains failures with the fix, and replays deliveries or sends signed test events.
Webhook routes
LaraMonster looks for POST routes with webhook, hook, callback or a provider's name (Stripe, GitHub, Paddle, Shopify, Lemon Squeezy, Svix, Slack…) in their URL, name or controller, and for Laravel Cashier, Paddle and spatie/laravel-webhook-client. Each route gets checks:
| Check | Why it matters |
|---|---|
| CSRF check on | Every delivery gets a 419. Copy fix gives you the line that excludes the route. |
| Needs a logged-in user | Providers never log in: move the route out of the auth middleware group. |
| Signing secret | Whether the secret (e.g. STRIPE_WEBHOOK_SECRET) is in .env, with Add it if not. |
The CSRF fix for Laravel 11 and newer, in bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'stripe/*',
]);
})Route named differently? Add its URL under Watch this URL.
Letting providers reach you
Stripe or GitHub can't reach your computer by itself. Open a public link for the site; the Webhooks page then lists the full public URL of each webhook route with Copy public URL, to paste into the provider's dashboard. Webhook routes stay reachable even if you protect the rest of the site with a password.
Deliveries
Click Start recording. Every delivery is recorded: headers, body, and what the app answered, with its status and time. Filter by All, Failed or From the internet. Pick one to see:
- Signature: valid, doesn't match, not signed, or not checked (no secret set)
- The app answered: status, time and body, with a plain explanation for
419(CSRF), redirects (usually auth),401/403(signature or middleware),500(with a link to the Debugger) and timeouts
Replaying and test events
| Action | What it does |
|---|---|
| Replay | Sends the delivery again, re-signed with your secret, so the signature check passes even though time has passed. |
| Replay as is | Exactly as it arrived, with its original signature. |
| Send a test event | Pick a provider and event type (e.g. Stripe checkout.session.completed) and LaraMonster sends a realistic payload signed like the real thing. |
Example: a Stripe webhook that returns 419
- Spot it
The route shows CSRF check on: deliveries get 419.
- Fix it
Copy fix, paste it into
bootstrap/app.php. - Check the secret
Add
STRIPE_WEBHOOK_SECRETif the route says it's missing. - Replay
Replay the failed delivery: it's re-signed and now answers
200.