Requex.me LogoRequex.me

Documentation

Browse by section

Keep all guides, tool docs, automation recipes, and comparison pages in one navigable place.

Docs Home
Docs

Foundation docs for getting started fast, understanding key terms, and tracking what has changed.

Guides

Start with fundamentals, then move into provider-specific webhook testing and production hardening.

Tool Docs

These pages explain what each tool does, when to use it, and how it fits into a webhook debugging workflow.

Automation Docs

Use these setup guides when you want forwarding rules, custom responses, security checks, or multi-destination fanout.

Compare

Use these pages to compare developer workflows, pricing tradeoffs, and feature differences between webhook tools.

How to Test Stripe Webhooks: Complete Guide

How to inspect Stripe payment events, verify signatures, and test the event flow your backend actually depends on.

Editorially reviewed by the Requex team14 min readAbout the product

Why Stripe Webhooks Need Real Testing

Stripe webhooks are asynchronous. A customer can complete checkout successfully while your own backend is still waiting for a later webhook to mark the order paid, provision access, or send a receipt. If that webhook fails, the customer sees success while your system quietly falls behind.

That is why Stripe is worth testing with real payloads instead of trimmed-down mocks. The details that break handlers usually live in the full object shape, the delivery headers, or the order in which events arrive.

Key Stripe Webhook Events You Should Handle First

EventWhen It FiresPriority
payment_intent.succeededPayment completedCritical
payment_intent.payment_failedPayment declinedCritical
checkout.session.completedCheckout flow finishedCritical
invoice.paidSubscription invoice paidHigh
customer.subscription.deletedSubscription cancelledHigh
charge.dispute.createdCustomer filed a disputeHigh

Method 1: Test with Requex.me (Fastest)

If you want to see the raw Stripe payload before your own code touches it, a temporary inspection endpoint is the fastest starting point. Requex.me works well for that:

  1. Visit requex.me and copy your unique webhook URL.
  2. Go to Stripe Dashboard → Developers → Webhooks → Add Endpoint.
  3. Paste your Requex URL, select the events you want to test, and click "Add endpoint".
  4. Click "Send test webhook" in Stripe's dashboard for any event type.
  5. Watch the payload appear instantly in your Requex dashboard.

That gives you the exact JSON Stripe sent, including nested `data.object` fields, metadata, and delivery details that are easy to miss in docs.

Method 2: Stripe CLI for Local Testing

The Stripe CLI provides direct forwarding to your local server:

# Install Stripe CLI
brew install stripe/stripe-cli/stripe

# Login to your Stripe account
stripe login

# Forward events to your local server
stripe listen --forward-to localhost:3000/api/webhooks/stripe

# In another terminal, trigger test events:
stripe trigger payment_intent.succeeded
stripe trigger customer.subscription.created
stripe trigger invoice.payment_failed

The CLI provides a temporary webhook signing secret (displayed when you run stripe listen). Use this secret in your local environment for signature verification.

Stripe Webhook Signature Verification

Stripe signs every webhook with your endpoint's signing secret. Always verify this signature in production:

// Node.js / Express example
const stripe = require('stripe')('sk_test_...');

app.post('/api/webhooks/stripe', express.raw({type: 'application/json'}), (req, res) => {
  const sig = req.headers['stripe-signature'];
  const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
  
  let event;
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
  } catch (err) {
    console.log('Webhook signature verification failed:', err.message);
    return res.status(400).send('Webhook Error');
  }

  // Handle the event
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      // Fulfill the order...
      break;
    case 'payment_intent.payment_failed':
      // Notify the customer...
      break;
    default:
      console.log('Unhandled event type:', event.type);
  }

  res.status(200).json({received: true});
});

⚠️ Critical: You must use express.raw() instead of express.json() for the webhook route. Stripe's signature verification requires the raw request body.

Common Stripe Webhook Issues

401 Unauthorized errors

If Stripe receives a 401 from your endpoint, it will retry the webhook. This typically means your handler is rejecting the request before signature verification passes. See the webhook 401 unauthorized guide for diagnosis steps.

Signature verification fails every time

Make sure you're using the webhook endpoint secret (starts with whsec_), not your API secret key (starts with sk_). Also ensure the body hasn't been parsed by middleware before verification.

Events received out of order

Stripe doesn't guarantee event order. A invoice.paid might arrive before invoice.created. Always fetch the latest state from the API if order matters.

Duplicate events

Stripe retries failed deliveries. Store processed event IDs in your database and skip duplicates. Use the event.id field as your idempotency key.

Language-Specific Stripe Webhook Handlers

See full implementation guides for your language stack:

Testing Checklist for Stripe Webhooks

  • Test payment_intent.succeeded — Verify order fulfillment
  • Test payment_intent.payment_failed — Verify customer notification
  • Test signature verification with valid and invalid signatures
  • Test idempotency by sending the same event twice
  • Test timeout handling (use Requex.me delay simulation)
  • Test in both Stripe test mode and live mode

Start Testing Webhooks Now

Generate your unique URL and test webhooks instantly. Free, no signup.

Open Webhook Tester →