SDK
Custom Providers
Build type-safe providers for webhook sources not covered by built-in SDK packages.
Custom Providers
For webhook sources not covered by built-in providers, use @better-webhook/core to define events and create a custom provider.
1) Define event schemas and event definitions
import { defineEvent, z } from "@better-webhook/core";
const OrderSchema = z.object({
orderId: z.string(),
status: z.enum(["pending", "completed", "cancelled"]),
amount: z.number(),
});
export const orderCreated = defineEvent({
name: "order.created",
schema: OrderSchema,
provider: "my-ecommerce" as const,
});
export const orderUpdated = defineEvent({
name: "order.updated",
schema: OrderSchema,
provider: "my-ecommerce" as const,
});2) Create a provider
import { createProvider, createHmacVerifier } from "@better-webhook/core";
export const myProvider = createProvider({
name: "my-ecommerce",
getEventType: (headers) => headers["x-event-type"],
getDeliveryId: (headers) => headers["x-delivery-id"],
verify: createHmacVerifier({
algorithm: "sha256",
signatureHeader: "x-signature",
signaturePrefix: "sha256=",
}),
});3) Build a webhook and register handlers
import { createWebhook } from "@better-webhook/core";
import { myProvider, orderCreated, orderUpdated } from "./provider";
const webhook = createWebhook(myProvider)
.event(orderCreated, async (payload) => {
await handleOrderCreated(payload.orderId);
})
.event(orderUpdated, async (payload) => {
await handleOrderUpdated(payload.orderId, payload.status);
});4) Attach to an adapter
import { toNextJS } from "@better-webhook/nextjs";
export const POST = toNextJS(webhook);Envelope payloads
If your provider wraps payloads in an envelope, extract the event and payload with getEventType and getPayload:
const envelopeProvider = createProvider({
name: "my-envelope-provider",
getEventType: (headers, body) => {
if (body && typeof body === "object" && "type" in body) {
return (body as { type: string }).type;
}
return undefined;
},
getPayload: (body) => {
if (body && typeof body === "object" && "payload" in body) {
return (body as { payload: unknown }).payload;
}
return body;
},
verify: createHmacVerifier({
algorithm: "sha256",
signatureHeader: "x-signature",
}),
});createHmacVerifier covers common signature formats. If needed, provide your own verify implementation.
Canonical reference: Providers