openwebhook.coOpen inspector →
developer guide

Stripe Webhook Payload Example: JSON, Headers, and Signature

A complete Stripe webhook payload example with Event JSON, Stripe-Signature header, and a cURL you can send to a live inspector.

Search results for “stripe webhook payload example” usually show a truncated Event object. This page is a full request: JSON body, headers, and how Stripe signs it. Paste the inspector URL into the Stripe Dashboard → Webhooks “Send test webhook” action, or replay the cURL below.

Ingestion host:

https://hooks.openwebhook.co/YOUR_UUID/stripe

Open the free inspector to get a UUID, or use a Pro slug such as billing.

HTTP request

POST /stripe HTTP/1.1
Host: hooks.openwebhook.co
Content-Type: application/json
Stripe-Signature: t=1716400000,v1=8f3c0a1b9e2d4c6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f
User-Agent: Stripe/1.0 (+https://stripe.com/docs/webhooks)

Stripe-Signature is t=<unix_seconds>,v1=<hex_hmac_sha256>. The signed payload is t + . + the raw body bytes. Verify with the endpoint’s signing secret (whsec_...), not the secret key. Do not JSON.parse and re-stringify before verifying.

Event object (checkout.session.completed)

{
  "id": "evt_1Pexample000000000000000",
  "object": "event",
  "api_version": "2024-06-20",
  "created": 1716400000,
  "data": {
    "object": {
      "id": "cs_test_a1b2c3",
      "object": "checkout.session",
      "amount_total": 4900,
      "currency": "eur",
      "customer": "cus_example",
      "customer_email": "buyer@example.com",
      "mode": "payment",
      "payment_status": "paid",
      "status": "complete",
      "success_url": "https://example.com/ok",
      "metadata": {
        "order_id": "ord_1042"
      }
    }
  },
  "livemode": false,
  "pending_webhooks": 1,
  "request": {
    "id": "req_example",
    "idempotency_key": null
  },
  "type": "checkout.session.completed"
}

Other types you will see often: invoice.paid, customer.subscription.updated, payment_intent.payment_failed, charge.refunded. The envelope is always id, type, data.object. Store id for idempotency.

Send it to the inspector

curl -X POST \
  'https://hooks.openwebhook.co/YOUR_UUID/stripe' \
  -H 'content-type: application/json' \
  -H 'stripe-signature: t=1716400000,v1=test' \
  --data-binary @- <<'EOF'
{"id":"evt_1Pexample000000000000000","object":"event","api_version":"2024-06-20","created":1716400000,"type":"checkout.session.completed","data":{"object":{"id":"cs_test_a1b2c3","object":"checkout.session","amount_total":4900,"currency":"eur","payment_status":"paid","status":"complete"}},"livemode":false}
EOF

Keep the tab open. You should see POST /stripe, the signature header, and the JSON. Copy cURL from the inspector to replay against your handler.

For retries, point a custom endpoint at Stripe and return 500 once, then 200.

Related guides