Does Fastify Work With Lemon Squeezy?
Yes, Fastify works excellently with Lemon Squeezy as your backend framework for handling webhooks, API integrations, and checkout flows.
Quick Facts
How Fastify Works With Lemon Squeezy
Fastify is an ideal backend framework for Lemon Squeezy integrations because it's lightweight, fast, and handles high-concurrency scenarios efficiently—perfect for processing payment webhooks and customer requests. You'll typically use Fastify to build a REST API that manages your product catalog, handles webhook events from Lemon Squeezy (order confirmations, subscription updates, refunds), and orchestrates checkout flows via the Lemon Squeezy JavaScript SDK. The framework's plugin ecosystem makes it simple to add authentication, request validation, and database middleware. Lemon Squeezy provides webhook signatures for security verification, which integrates seamlessly into Fastify's request lifecycle. The typical architecture involves creating webhook endpoints that validate signatures, process events atomically, and update your local database—Fastify's async-first design makes this straightforward. You might also use Fastify to proxy requests to Lemon Squeezy's API for inventory synchronization or customer management, though most checkout flows happen directly through Lemon Squeezy's hosted pages or embeddable forms.
Best Use Cases
Quick Setup
npm install fastify @lemon.io/lemon-squeezy cryptoimport Fastify from 'fastify';
import crypto from 'crypto';
const fastify = Fastify({ logger: true });
const WEBHOOK_SECRET = process.env.LEMON_SQUEEZY_WEBHOOK_SECRET;
fastify.post('/webhooks/lemon-squeezy', async (request, reply) => {
const signature = request.headers['x-signature'] as string;
const body = request.rawBody as Buffer;
// Verify webhook signature
const hash = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(body)
.digest('hex');
if (hash !== signature) {
return reply.code(403).send({ error: 'Invalid signature' });
}
const event = JSON.parse(body.toString());
// Process events
if (event.meta.event_name === 'order:created') {
console.log('Order created:', event.data.id);
// Update database, grant access, send email, etc.
}
reply.code(200).send({ received: true });
});
fastify.listen({ port: 3000 }, (err, address) => {
if (err) throw err;
console.log(`Listening on ${address}`);
});Known Issues & Gotchas
Webhook signature verification must happen before body parsing in some middleware configurations, or signatures become invalid
Fix: Verify signatures on raw body buffers before JSON parsing. Use Fastify's bodyLimit and custom hooks in the correct order: raw body → signature validation → parsing
Lemon Squeezy webhooks can retry failed deliveries; idempotent processing is essential to avoid duplicate orders or refunds
Fix: Store webhook event IDs in your database and check for duplicates before processing. Implement idempotent operations using database unique constraints
Rate limiting and timeout issues when syncing large product catalogs or customer lists with Lemon Squeezy API
Fix: Implement exponential backoff, use Fastify's async queue plugins, and paginate API requests. Cache product data and refresh periodically rather than on-demand
Alternatives
- •Next.js API Routes + Lemon Squeezy: Full-stack framework with built-in serverless functions, better for jamstack deployments
- •Express.js + Lemon Squeezy: More mature ecosystem and middleware, but slower and heavier than Fastify
- •AWS Lambda + Lemon Squeezy: Serverless approach with native webhook integration, eliminates infrastructure management
Resources
Related Compatibility Guides
Explore more compatibility guides