Skip to content
Integration

Consuming Lemon Squeezy Webhooks: Orders, Subscriptions & Signature Verification

How to receive and verify Lemon Squeezy webhooks with X-Signature (HMAC-SHA256), process subscription events (order_created, subscription_updated), and handle retries.

Published 2 min read
On this page

Lemon Squeezy is a popular Merchant of Record for SaaS products and digital software. It sends HTTP POST webhooks for all customer actions: checkout completions, subscription renewals, payment failures, and refunds.

Lemon Squeezy Webhook Architecture

Every payload from Lemon Squeezy follows JSON:API conventions:

  • meta.event_name: The event name (order_created, order_refunded, subscription_created, subscription_updated, subscription_cancelled, license_key_created).
  • meta.custom_data: Custom metadata passed during checkout.
  • data: The primary resource object (id, type, attributes, relationships).

Verifying X-Signature

Lemon Squeezy signs every webhook request using your Signing Secret configured in Settings → Webhooks:

  • Header: X-Signature
  • Algorithm: HMAC-SHA256 in hexadecimal encoding over the raw UTF-8 request body.
import crypto from 'node:crypto';

export function verifyLemonSqueezy(rawBody: string, signature: string, secret: string): boolean {
  const hmac = crypto.createHmac('sha256', secret);
  const digest = Buffer.from(hmac.update(rawBody).digest('hex'), 'utf8');
  const signatureBuffer = Buffer.from(signature, 'utf8');

  return (
    digest.length === signatureBuffer.length &&
    crypto.timingSafeEqual(digest, signatureBuffer)
  );
}

Idempotency and License Keys

When order_created fires, your application typically provisions licenses or unlocks features. Because Lemon Squeezy will retry any request that does not return HTTP 200 within 5 seconds, ensure you store the Lemon Squeezy order ID (data.id) as a unique constraint to avoid double-issuing license keys.

Debugging Lemon Squeezy Webhooks with HookWatch

HookWatch allows inspecting the full JSON:API response hierarchy, comparing event attempt timestamps, and safely replaying failed order events after server deploys.

Get started

See what happened to every webhook.

HookWatch keeps the request, the response, and every attempt for each delivery — so the debugging, retry, and replay steps in this article are a matter of reading, not reconstructing.