Skip to content

Guides

Testing Stripe Webhooks

Point a Stripe sandbox webhook destination at a temporary endpoint. Trigger a test event and compare delivery status, event data and signature headers.

On this page

Reduced synthetic Snapshot event. id identifies the event; type names payment_intent.succeeded; created is its Unix timestamp; livemode=false marks sandbox data; api_version records the version used to render data.object. The nested PaymentIntent has its own id, succeeded status, amount and currency. pending_webhooks counts outstanding destinations, while request identifies the API request when available. Stripe-Signature contains t (timestamp) and v1 (signature); this demonstrative placeholder is cryptographically invalid. Your handler must verify the original request bytes with its signing secret. Capture alone does not verify authenticity.

HTTP
content-type: application/json
stripe-signature: t=1767271333,v1=ILLUSTRATIVE_NOT_VALID

{
  "id": "evt_synthetic_001",
  "object": "event",
  "api_version": "2026-09-30.preview",
  "type": "payment_intent.succeeded",
  "created": 1767271333,
  "livemode": false,
  "pending_webhooks": 1,
  "request": {
    "id": "req_synthetic_001",
    "idempotency_key": "synthetic-payment-001"
  },
  "data": {
    "object": {
      "id": "pi_synthetic_001",
      "object": "payment_intent",
      "amount": 4900,
      "currency": "usd",
      "status": "succeeded"
    }
  }
}

Create a test endpoint

Use a Stripe sandbox or test environment and synthetic data. You need permission to manage webhook destinations. Create a fresh WebhookKit endpoint and copy its receiving URL; keep it active while testing.

Configure Stripe

In Stripe Workbench, open Webhooks and create an event destination for your sandbox account. Choose the Snapshot payload format, select the API version and payment_intent.succeeded, then choose Webhook endpoint and paste the receiving URL. Stripe also supports Thin destinations, but their payload shape differs from this reduced Snapshot example.

Follow Stripe’s current setup instructions for your environment. Dashboard labels and available formats can change.

Trigger an event

Complete a synthetic sandbox payment that succeeds so Stripe produces payment_intent.succeeded. Check the destination’s Event deliveries record for the HTTP attempt and result. An unrelated event will not exercise this subscription.

Inspect the delivery

A new WebhookKit endpoint returns HTTP 200 by default. Select the corresponding POST and compare id, type,created, livemode, api_version, pending_webhooks and request. In data.object, inspect the PaymentIntent ID, status, amount and currency. The Stripe-Signature header’s t value is a timestamp and v1 is a signature for verification.

A successful capture proves receipt and persistence of the request. It does not prove signature authenticity and does not execute your payment handler or other application business logic. Verify the exact raw body, header and endpoint secret in your own handler.

Common mistakes

If no capture appears, check the receiving URL rather than the workspace URL, endpoint expiration, Stripe environment and selected events. Do not paste a signing secret into captured test data. This workflow is for temporary debugging, not production payment processing.

To observe sender behavior under failure, use the retry testing guide. Stripe currently retries sandbox deliveries three times over a few hours and live-mode deliveries with exponential backoff for up to three days. A manual resend is separate and does not cancel the automatic retry sequence; check Stripe’s linked documentation for current policy.