Transform and Route Stripe Webhook Events

Stripe sends webhook events for everything: charges, subscriptions, invoices, disputes, payouts. Most of that payload is noise for your application. With Hookpipe, you can transform Stripe webhooks to extract only the fields you need, filter by event type, and forward clean payloads to your endpoints. No middleware to deploy, no code to maintain.

Why Transform Stripe Webhook Events?

A typical Stripe webhook event carries 50+ fields across deeply nested objects. The invoice.payment_succeeded event alone includes the full invoice object, line items, customer details, subscription metadata, and billing timestamps. Your application probably needs three or four of those fields.

Without a webhook relay sitting between Stripe and your app, you end up writing boilerplate parsing code in every handler. Worse, if you need to route different Stripe webhook events to different services — charges to your billing service, disputes to your support tool, payouts to your finance dashboard — you're building a routing layer from scratch.

⚙️ Extract What Matters

Pull just the customer email, amount, and status from a charge event. Drop the 40 other fields your app ignores.

🚦 Route by Event Type

Send charge.succeeded events to your billing service and customer.subscription.deleted to your churn tracker. Use separate hooks with filters.

🔁 Normalize for Your App

Rename Stripe's nested field paths into the flat structure your API expects. No more data.object.customer chains in your handler.

What a Stripe Webhook Event Looks Like

Here's a real-world invoice.payment_succeeded event payload from Stripe. This is what arrives at your webhook endpoint:

{
  "id": "evt_1RBx2kJf8aLzKp4qXdV",
  "object": "event",
  "type": "invoice.payment_succeeded",
  "data": {
    "object": {
      "id": "in_1RBx2kJf8aLzKp4qN7m",
      "object": "invoice",
      "customer": "cus_PqR8xYkL3mN",
      "customer_email": "jamie@example.com",
      "customer_name": "Jamie Chen",
      "amount_paid": 2900,
      "currency": "usd",
      "status": "paid",
      "subscription": "sub_1RBx2kJf8aLz",
      "period_start": 1708300800,
      "period_end": 1710979200,
      "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1R.../inv_...",
      "lines": {
        "data": [
          {
            "description": "Pro Plan (Feb 18 - Mar 18, 2026)",
            "amount": 2900,
            "price": {
              "id": "price_1RBxKp4q",
              "product": "prod_PqR8",
              "unit_amount": 2900,
              "recurring": { "interval": "month" }
            }
          }
        ]
      },
      "payment_intent": "pi_3RBx2kJf8aLz",
      "charge": "ch_3RBx2kJf8aLz",
      "billing_reason": "subscription_cycle",
      "metadata": {}
    }
  },
  "created": 1708300860,
  "livemode": true,
  "pending_webhooks": 2,
  "request": { "id": "req_Kp4qXdV", "idempotency_key": null }
}

That's a lot of data. Your billing dashboard probably only needs the customer email, amount, currency, and subscription ID. Your Slack notification might only need the customer name and what they paid. Hookpipe lets you define exactly what to extract.

Setting Up Stripe Webhook Forwarding

Here's how to set up a Hookpipe hook that transforms Stripe webhook events into clean, flat payloads and forwards them to your app.

1Create an API Key

curl -X POST https://hookpipe.app/api/auth/keys \
  -H "Content-Type: application/json" \
  -d '{"name": "stripe-integration"}'

Save the API key from the response — it's shown only once.

2Create a Hook with Transform Rules

This hook extracts the essential payment fields from any Stripe invoice event and forwards a clean payload to your app:

curl -X POST https://hookpipe.app/api/hooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "stripe-invoices",
    "destinationUrl": "https://your-app.com/api/billing/webhook",
    "transformConfig": {
      "fieldMapping": {
        "event_type": "type",
        "customer_id": "data.object.customer",
        "customer_email": "data.object.customer_email",
        "amount_cents": "data.object.amount_paid",
        "currency": "data.object.currency",
        "invoice_status": "data.object.status",
        "subscription_id": "data.object.subscription",
        "billing_reason": "data.object.billing_reason",
        "source": "stripe",
        "processed_by": "hookpipe"
      },
      "filters": [
        {"field": "type", "operator": "contains", "value": "invoice."}
      ]
    }
  }'

3Configure Stripe to Send Here

In your Stripe Dashboard → Webhooks, add a new endpoint:

https://hookpipe.app/hooks/YOUR_HOOK_ID

Select the events you want — invoice.payment_succeeded, invoice.payment_failed, etc. Stripe will now send those events to Hookpipe, which transforms and forwards them.

What Your App Receives

Instead of the full Stripe event object, your endpoint gets this:

{
  "event_type": "invoice.payment_succeeded",
  "customer_id": "cus_PqR8xYkL3mN",
  "customer_email": "jamie@example.com",
  "amount_cents": 2900,
  "currency": "usd",
  "invoice_status": "paid",
  "subscription_id": "sub_1RBx2kJf8aLz",
  "billing_reason": "subscription_cycle",
  "source": "stripe",
  "processed_by": "hookpipe"
}

Clean. Flat. Exactly what your billing service needs. No nested object traversal in your handler code.


More Transform Patterns for Stripe

Charge Events — Extract Payment Status

Track successful and failed charges with just the fields that matter:

curl -X POST https://hookpipe.app/api/hooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "stripe-charges",
    "destinationUrl": "https://your-app.com/api/payments",
    "transformConfig": {
      "fieldMapping": {
        "event": "type",
        "charge_id": "data.object.id",
        "amount": "data.object.amount",
        "currency": "data.object.currency",
        "customer": "data.object.customer",
        "status": "data.object.status",
        "failure_reason": "data.object.failure_message",
        "receipt_url": "data.object.receipt_url",
        "source": "stripe"
      },
      "filters": [
        {"field": "type", "operator": "contains", "value": "charge."}
      ]
    }
  }'

Subscription Lifecycle — Track Churn

Route subscription cancellations and updates to your analytics pipeline:

curl -X POST https://hookpipe.app/api/hooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "stripe-subscriptions",
    "destinationUrl": "https://your-app.com/api/churn-tracker",
    "transformConfig": {
      "fieldMapping": {
        "event": "type",
        "subscription_id": "data.object.id",
        "customer_id": "data.object.customer",
        "plan_status": "data.object.status",
        "cancel_at": "data.object.cancel_at",
        "canceled_at": "data.object.canceled_at",
        "current_period_end": "data.object.current_period_end"
      },
      "filters": [
        {"field": "type", "operator": "contains", "value": "customer.subscription."}
      ]
    }
  }'

Testing Your Stripe Webhook Relay

You don't need to trigger real Stripe events to test. Send a simulated payload directly to your hook:

curl -X POST https://hookpipe.app/hooks/YOUR_HOOK_ID \
  -H "Content-Type: application/json" \
  -d '{
    "type": "invoice.payment_succeeded",
    "data": {
      "object": {
        "customer": "cus_test123",
        "customer_email": "test@example.com",
        "amount_paid": 4900,
        "currency": "usd",
        "status": "paid",
        "subscription": "sub_test456",
        "billing_reason": "subscription_create"
      }
    }
  }'

Check what was received and forwarded using the payloads API:

curl https://hookpipe.app/api/hooks/YOUR_HOOK_ID/payloads \
  -H "Authorization: Bearer YOUR_API_KEY"

Each stored payload shows both the original rawBody and the transformedBody so you can verify your field mappings are correct. If the forward failed (maybe your destination was down), use the replay endpoint to retry:

curl -X POST https://hookpipe.app/api/hooks/YOUR_HOOK_ID/payloads/PAYLOAD_ID/replay \
  -H "Authorization: Bearer YOUR_API_KEY"

Tips for Production Stripe Webhook Forwarding

Start Transforming Stripe Webhooks

Create your first hook in three API calls. No account required for the free tier.