> ## Documentation Index
> Fetch the complete documentation index at: https://bobprince.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Stripe

> Capture and debug Stripe webhooks with Hookdrop

## Setup

<Steps>
  <Step title="Open the Webhooks page">
    Go to the [Stripe Dashboard](https://dashboard.stripe.com) and navigate to **Developers → Webhooks**.
  </Step>

  <Step title="Add an endpoint">
    Click **Add endpoint**.
  </Step>

  <Step title="Paste your Hookdrop URL">
    Enter your Hookdrop capture URL as the endpoint:

    ```
    https://hookdrop.dev/in/{your-token}
    ```
  </Step>

  <Step title="Select events">
    Choose the events you want to capture. Start with `payment_intent.succeeded` and `payment_intent.payment_failed` to cover the most common payment outcomes.
  </Step>

  <Step title="Save">
    Click **Add endpoint**. Stripe will begin sending matching events to Hookdrop immediately.
  </Step>
</Steps>

## Common events

| Event                           | When it fires                  |
| ------------------------------- | ------------------------------ |
| `payment_intent.succeeded`      | Payment completed successfully |
| `payment_intent.payment_failed` | Payment attempt failed         |
| `customer.subscription.created` | New subscription started       |
| `customer.subscription.deleted` | Subscription cancelled         |
| `invoice.paid`                  | Invoice payment succeeded      |

## Verifying signatures

Stripe signs every webhook request with a `Stripe-Signature` header. Verify it in your handler before processing the event:

```typescript theme={null}
import crypto from 'crypto'

const verifyStripeWebhook = (payload: string, signature: string, secret: string) => {
  const elements = signature.split(',')
  const timestamp = elements.find(e => e.startsWith('t='))?.split('=')[1]
  const sig = elements.find(e => e.startsWith('v1='))?.split('=')[1]

  const signedPayload = `${timestamp}.${payload}`
  const expected = crypto.createHmac('sha256', secret).update(signedPayload).digest('hex')

  return expected === sig
}
```

Your webhook secret is available in the Stripe Dashboard under the endpoint's details.

<Note>
  Stripe fires test events from the dashboard that you can use to verify your capture is working. Look for events with `livemode: false` in the Hookdrop payload inspector.
</Note>

## Local development

<Tip>
  Use your Hookdrop capture URL instead of ngrok during local development. Events appear in the Hookdrop dashboard instantly — no terminal session required, and your URL stays stable across restarts.
</Tip>
