Generate realistic Stripe webhook payloads and test code. Choose an event, customize the payload, and get ready-to-run code.
Payment Intent Succeeded
Find this in Stripe Dashboard → Developers → Webhooks → Signing secret
curl -X POST "https://example.com/api/webhooks/stripe" \
-H "Content-Type: application/json" \
-H "Stripe-Signature: t=$(date +%s),v1=COMPUTED_SIGNATURE" \
-d '{
"id": "evt_Sr4OTHhg4V9Ppl0NugKKGvqI",
"object": "event",
"api_version": "2024-12-18.acacia",
"created": 1773852921,
"type": "payment_intent.succeeded",
"livemode": false,
"pending_webhooks": 1,
"request": {
"id": "req_jRDYnUfQx2QZEaiGXIsJu6NV",
"idempotency_key": null
},
"data": {
"object": {
"id": "pi_1OIlUXPguab9rVegkp0B7UNa",
"object": "payment_intent",
"amount": 2000,
"amount_capturable": 0,
"amount_received": 2000,
"currency": "usd",
"status": "succeeded",
"description": "Payment for order #1234",
"customer": "cus_DEUmIHod8b4dAeeWqIo4a3VX",
"payment_method": "pm_SyYfe4UHy44IU5KxORHIM8vv",
"payment_method_types": [
"card"
],
"created": 1773852891,
"metadata": {
"order_id": "1234"
},
"latest_charge": "ch_wtgQHAgQovQuDt0SPX01J9C9",
"livemode": false
}
}
}'
# NOTE: For a valid signature, compute HMAC SHA256:
# signature = HMAC-SHA256(
# key: "whsec_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
# message: "${timestamp}.${payload}"
# )
# Then set: Stripe-Signature: t=${timestamp},v1=${signature}Stripe signs every webhook with a Stripe-Signature header using HMAC SHA256. Your server should verify this to ensure the webhook is authentic.
Signature format:
t=1234567890,v1=abc123def456...How it's computed:
timestamp = current unix time
signed_payload = `${timestamp}.${raw_body}`
signature = HMAC_SHA256(webhook_secret, signed_payload)
header = `t=${timestamp},v1=${signature}`Tip: Use Stripe's official library for verification:
stripe.webhooks.constructEvent(body, sig, secret)