Fix Shopify Webhook Signature in Next.js

Shopify webhook verification uses HMAC-SHA256 but encodes the result as Base64, not hex. This is different from Stripe and GitHub. Using .digest('hex') instead of .digest('base64') causes every verification to fail.

App Router handler

// app/api/webhooks/shopify/route.ts
import { createHmac, timingSafeEqual } from 'crypto';
import { NextResponse } from 'next/server';

const secret = process.env.SHOPIFY_WEBHOOK_SECRET!;

export async function POST(request: Request) {
  const body = await request.text();
  const sig  = request.headers.get('x-shopify-hmac-sha256');

  if (!sig) {
    return NextResponse.json({ error: 'Missing X-Shopify-Hmac-Sha256' }, { status: 400 });
  }

  // Shopify uses Base64, not hex
  const computed = createHmac('sha256', secret).update(body, 'utf8').digest('base64');

  const sigBuf  = Buffer.from(sig);
  const compBuf = Buffer.from(computed);

  if (sigBuf.length !== compBuf.length || !timingSafeEqual(sigBuf, compBuf)) {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
  }

  const payload = JSON.parse(body);
  const topic   = request.headers.get('x-shopify-topic');

  switch (topic) {
    case 'orders/create':
      // handle new order
      break;
    case 'orders/cancelled':
      // handle cancellation
      break;
    case 'customers/create':
      // handle new customer
      break;
  }

  return NextResponse.json({ received: true });
}
Base64 not hex. Shopify sends X-Shopify-Hmac-Sha256 as a Base64-encoded HMAC. Using .digest('hex') (like Stripe or GitHub) produces the wrong value and every verification fails.

Get the webhook secret

# Shopify Admin → Settings → Notifications → Webhooks
# Each webhook has its own signing secret shown under the endpoint
# Or via Admin API: GET /admin/api/webhooks.json

Generate the complete Shopify webhook handler for your framework.

Open WebhookFix →
For informational purposes only. Always test in staging before production. MetricLogic accepts no responsibility for issues arising from use of these tools. © 2026 MetricLogic.
HttpFixer by MetricLogic · Blog · All Tools · Generators MIT · GitHub →