Xzero UI
Pro library

Webhook testerPro

A developer webhook tester where you pick an event, edit its JSON payload and send a signed test event. You watch it go from signed to sent to 200 OK in 184 ms, then read the response body, headers and exact request, and retry failed deliveries from a recent list.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui-pro/webhook-tester
Live · keyboard ready

Put it on the Test endpoint screen of any product that sends webhooks. Pass your own events (type plus default payload), the endpoint's secret and an onSend(request, signal) that hands the signed request to your backend. Your backend does the real POST and resolves with { status, durationMs, headers, body }, or with status 0 and an error when nothing came back. onRetry re-sends a failed delivery and falls back to onSend. source and signatureHeader replace the Stripe defaults with your own product's name, mark and header. With no props it simulates the endpoint and sends one sample event when it scrolls into view.

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui-pro/webhook-tester

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { WebhookTester } from "@/components/xzero/blocks/webhook-tester/webhook-tester";

export function EndpointTest({ endpointId }: { endpointId: string }) {
  return (
    <WebhookTester
      defaultEndpoint="https://api.acme.com/webhooks/billing"
      secret={signingSecret}
      onSend={async (request, signal) => {
        const res = await fetch(`/api/endpoints/${endpointId}/test`, { method: "POST", body: JSON.stringify(request), signal });
        return res.json(); // { status, durationMs, headers, body }
      }}
    />
  );
}

API reference

WebhookTester

A developer webhook tester in one card. The request side has the endpoint URL, an event type select, the signing secret with reveal and copy, and a JSON payload editor with syntax tint, line numbers, validation and Format. Send test event signs the body with real HMAC SHA-256, runs a request timeline (signed, sent, 200 OK in 184 ms) and shows the response body, response headers and the exact request in tabs. Recent deliveries list every attempt with a status chip; failed ones have Retry. With no props it simulates the endpoint and sends one sample event when it scrolls into view.

PropTypeDefaultDescription
defaultEndpointstring"https://api.northwind.dev/webhooks/stripe"Endpoint the test events go to. https is required, except http on localhost.
onEndpointChange(url: string) => void–Called as the endpoint field is edited.
events{ type: string; payload: unknown }[]five Stripe events (invoice.paid, customer.created, customer.subscription.updated, checkout.session.completed, payment_intent.payment_failed)Event types in the select. Choosing one loads its payload (an object, pretty printed, or a JSON string kept as is) into the editor.
defaultEventstringthe first eventEvent selected on first render.
secretstringa sample whsec_ secretThe endpoint's signing secret. Shown masked with the prefix visible; the body is signed in the browser as HMAC SHA-256 of ${timestamp}.${body}.
defaultDeliveriesWebhookDelivery[]five sample deliveries, two failedDeliveries shown on first render, newest first. Each has id, event, time, request ({ url, event, body, headers, timestamp, signature }) and response. The first one is selected.
onSend(request: WebhookTestRequest, signal: AbortSignal) => Promise<WebhookTestResponse>–Sends the signed test event, usually through your backend. Resolve with { status, durationMs, headers?, body? }, or status 0 with error (and timedOut) when nothing came back; a rejection is shown as a failed delivery. Without it every delivery is simulated and the status line says so.
onRetry(delivery: WebhookDelivery, signal: AbortSignal) => Promise<WebhookTestResponse>–Re-sends a failed delivery with a fresh timestamp and signature. Defaults to onSend with the same body.
source{ name: string; mark: ReactNode }{ name: "Stripe", mark: <StripeMark /> }Who sends the events, shown in the header as a 16px mark and "Signed test events from Stripe".
signatureHeaderstring"stripe-signature"Name of the header that carries t=…,v1=… in the request.
autoPlaybooleantrue without onSendSends one event about a second after the card first scrolls half into view, unless someone has already interacted with it.
classNamestring–Class on the card.

Keyboard interactions

KeysAction
Mod+EnterSends the test event from the payload editor or anywhere in the endpoint field (Enter also works in the endpoint field).
EnterIn the payload editor, starts a new line that keeps the current indentation, and indents after { or [.
ArrowLeft / ArrowRight, Home / EndMove between the Body, Headers and Request tabs.
TabMoves through endpoint, event, reveal, copy, payload, Format, Send, tabs, copy, the response panel and each delivery with its Retry.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Guidance for AI tools

Blocks are complete, self-contained screens with sample data. Replace the sample data and connect the callbacks described above. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components