Gazebo
    ServicesAgentsDocsSpecWritingPricing
    Log inSign up
    Log in
    GazeboWorkflowsStripeHow to Test Stripe Webhooks Locally with the Stripe CLI

    Workflow

    How to Test Stripe Webhooks Locally with the Stripe CLI

    Forward real Stripe events to localhost for local webhook development.

    Last updated June 2026

    That's 5 steps.

    Describe it once — Gazebo generates a plan, you approve it, it runs.

    "Set up Stripe CLI webhook forwarding to my local server at localhost:3000"

    Let Gazebo handle this

    What you're doing and why it's painful

    Stripe webhooks don't work on localhost — Stripe can't reach your machine from the internet. The common workaround is ngrok, but it requires a separate account, generates a random URL every time, and needs its own signing secret. The Stripe CLI solves all of this in one command.

    The pain: finding the right install method, realising your production signing secret won't work locally (it's a different key), and figuring out how to trigger specific events without going through a real checkout flow.

    Prerequisites

    • Stripe account (test mode is fine)
    • A local server running with a webhook handler endpoint (e.g. localhost:3000/api/webhooks/stripe)
    • The Stripe CLI installed (covered below)

    Step 1 — Install the Stripe CLI

    macOS (Homebrew):

    brew install stripe/stripe-cli/stripe
    

    Windows (Scoop):

    scoop bucket add stripe https://github.com/stripe/scoop-stripe-cli.git
    scoop install stripe
    

    Linux / manual install:

    Download the latest binary from stripe.com/docs/stripe-cli and add it to your PATH.

    Verify the install:

    stripe --version
    

    Step 2 — Authenticate the CLI

    stripe login
    

    This opens a browser window. Log in to your Stripe account and click Allow access. The CLI stores your credentials locally — you only need to do this once per machine.

    To confirm it worked:

    stripe whoami
    

    Step 3 — Start forwarding events to your local server

    stripe listen --forward-to localhost:3000/api/webhooks/stripe
    

    Replace 3000 with whatever port your server runs on, and the path with your actual webhook route.

    The CLI prints something like:

    > Ready! Your webhook signing secret is whsec_abc123def456...
    

    Important: copy this local signing secret — it is different from the one in your Stripe Dashboard. You need it in Step 4.

    The CLI stays running and forwards all webhook events from your Stripe account to your local server in real time. Leave this terminal open while you develop.

    Step 4 — Use the local signing secret

    In your local .env file, set the CLI secret (not your production secret):

    STRIPE_WEBHOOK_SECRET=whsec_abc123def456...
    

    If you use the production signing secret for local testing, signature verification will fail and every webhook will return a 400.

    Your server code doesn't need to change — just the value of the environment variable.

    Step 5 — Trigger test events

    Open a second terminal and trigger any Stripe event:

    stripe trigger checkout.session.completed
    

    Other useful events to trigger:

    stripe trigger payment_intent.succeeded
    stripe trigger customer.subscription.created
    stripe trigger invoice.payment_failed
    

    Check your server logs — you should see the event arrive, the signature verify, and your handler run.

    To see all available trigger names:

    stripe trigger --help
    

    Common errors and gotchas

    No signatures found matching the expected signature for payload You're using the wrong signing secret. The CLI prints a local secret (whsec_...) that is different from your production webhook secret. Use the CLI secret in your .env file.

    stripe: command not found after install The Stripe CLI binary isn't in your PATH. On macOS, Homebrew usually handles this automatically. On Linux, move the binary to /usr/local/bin/stripe or add its directory to PATH.

    Server receives events but returns 400 Check your middleware. The webhook route must use express.raw({ type: 'application/json' }) — not express.json(). Parsing the body as JSON before signature verification corrupts it.

    stripe listen times out or disconnects The CLI maintains a persistent connection. If your network is flaky, it will reconnect automatically. If it doesn't, restart the command.

    Events aren't arriving Make sure your server is actually running on the port you specified. Run curl -X POST localhost:3000/api/webhooks/stripe manually to confirm the route exists and isn't returning a 404.

    Skip the manual steps.

    Describe it once — Gazebo generates a plan, you approve it, it runs.

    "Set up Stripe CLI webhook forwarding to my local server at localhost:3000"

    Let Gazebo handle this
    ← All Stripe workflowsAll workflows
    Gazebo

    IAM for AI agents. Scoped credentials, access policies, and audit trails — without rotating keys.

    Product

    • Pricing
    • Status

    Explore

    • Services
    • Agents
    • Workflows
    • Integrations

    Content

    • Writing
    • Topics
    • Blog
    • Docs

    Free Tools

    • Scanner

    Company

    • About
    • [email protected]
    • [email protected]

    © 2026 Gazebo. All rights reserved.

    PrivacyTermsSecurity