Webhook Payload Generator

Realistic webhook event payloads for testing

Generate realistic webhook payload JSON for Stripe, GitHub, and Shopify-style events. Payload shapes follow the documented public structures with random test IDs and values, ideal for testing webhook handlers, parsers, and integration tooling. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

Are the payload structures accurate?

Yes. Each shape mirrors the documented public structure for that service, such as the Stripe event envelope with a data.object, the GitHub push and pull_request shapes, and Shopify order and customer objects.

The Webhook Payload Generator produces realistic event payloads in the shapes used by popular services, so you can test webhook handlers, parsers, and integration logic without wiring up real accounts or waiting for live events.

How it works

Each service has its own builder that follows the documented payload structure:

  • Stripe wraps a data.object inside the standard event envelope with id, type, created, and livemode: false.
  • GitHub produces push, pull_request, issues, or star events with a repository, sender, and a 40-character commit SHA.
  • Shopify emits order, product, customer, or checkout objects with line_items, total_price, and a customer.

IDs use each service’s prefixes and formats (for example evt_, cus_ for Stripe, a hex SHA for GitHub), and amounts, timestamps, and identifiers are randomised on every generation.

Why payload shape matters more than values

A webhook handler typically does two things with a payload: it checks the type (or topic header) to decide what action to take, and it destructures specific fields to read values. Both of these fail silently if the shape is wrong, even when the values are present.

This generator reproduces the documented shapes for each service so that shape-dependent destructuring works correctly. For example:

  • A Stripe payment_intent.succeeded handler expects event.data.object.amount — the value is nested two levels inside the event envelope. A handler that reads event.amount directly would work on a flat test object but fail on a real Stripe event.
  • A GitHub pull_request handler expects payload.pull_request.head.sha — the SHA is nested under pull_request, not at the top level. A flat mock SHA would not reveal this.
  • A Shopify orders/create handler expects payload.line_items to be an array with price and quantity fields per item.

Generating from this tool exposes shape bugs that a hand-written flat mock would hide.

Signature verification and why these fail it

Real Stripe webhooks include a Stripe-Signature header built from the payload bytes and your webhook secret using HMAC-SHA256. Because this generator does not know your secret, the generated payload will fail signature verification if you pass it through your normal verification middleware.

This is intentional. When testing the parsing path of a handler — what happens after verification succeeds — you should bypass or stub the signature check. When testing the verification path itself, you need real signing secrets and cannot use pre-generated payloads. The two concerns are best tested separately.

A common pattern is to write two test layers: an integration test that sends a correctly-signed payload to a real endpoint (using the Stripe CLI’s stripe trigger command or GitHub’s delivery re-send), and a unit test that passes a generated payload directly to the handler function, skipping the HTTP layer entirely.

Service-specific notes

Stripe. The livemode: false flag is set on all generated payloads so they are clearly synthetic. The type field uses real Stripe event type names. Payment amounts are in the currency’s smallest unit (for example cents for USD, pence for GBP).

GitHub. Commit SHAs are 40-character hex strings. The ref field follows the refs/heads/branch-name format. pusher and sender are separate objects, which is a common gotcha for handlers that conflate them.

Shopify. Line item prices are strings, not numbers — Shopify uses decimal strings for currency. A handler that coerces price with parseInt will silently lose cents.

Practical tips

  • Use the generated JSON as a request body in curl or your test runner to exercise the parsing path of a handler.
  • Switch services to confirm your router branches correctly on the event type or the X-GitHub-Event / X-Shopify-Topic header.
  • Everything is local with no API key, so generate freely during rapid iteration.