Shopify, Lemon Squeezy, Vercel

First-class providers for three common HMAC-signed webhooks.

For Shopify, the signing secret is your app's client secret, or the value shown under Settings, then Notifications, for shop-configured webhooks. The event type is the topic header (orders/create, app/uninstalled) and deliveries dedupe by x-shopify-webhook-id.

app/api/webhooks/shopify/route.ts
import { webhook, shopify } from "next-webhooks";

export const POST = webhook({
  provider: shopify({ secret: process.env.SHOPIFY_WEBHOOK_SECRET! }),
  handler: async (event) => {
    if (event.type === "orders/create") {
      // event.payload is the order resource
    }
  },
});

Lemon Squeezy

The signing secret is the one you entered when creating the webhook. The event type comes from the x-event-name header, and deliveries dedupe when the payload carries meta.webhook_id:

app/api/webhooks/lemonsqueezy/route.ts
import { webhook, lemonsqueezy } from "next-webhooks";

export const POST = webhook({
  provider: lemonsqueezy({ secret: process.env.LEMONSQUEEZY_WEBHOOK_SECRET! }),
  handler: async (event) => {
    if (event.type === "order_created") {
      // event.payload.data has the order
    }
  },
});

Vercel

Create the webhook in the Vercel dashboard (account or integration settings) and copy its secret. The event id and type come from the payload:

app/api/webhooks/vercel/route.ts
import { webhook, vercel } from "next-webhooks";

export const POST = webhook({
  provider: vercel({ secret: process.env.VERCEL_WEBHOOK_SECRET! }),
  handler: async (event) => {
    if (event.type === "deployment.succeeded") {
      // event.payload.payload.deployment has the deployment
    }
  },
});

Notes

  • All three accept secret: string | string[] for rotation
  • The CLI can fire and replay all three: npx next-webhooks fire shopify orders/create