Skip to main content

Creating Webhook Listeners with Freemius JS SDK

The Freemius SDK provides a robust system to listen and process webhook events from the Freemius platform. This guide explains how to set up, configure, and process webhooks in various environments, including Next.js, Node.js, and serverless platforms.

note

Check out the installation guide if you haven't set up the SDK yet.

Create a Webhook Listener

To create a webhook listener, use the freemius.webhook.createListener method.

const listener = freemius.webhook.createListener();

You can create multiple listeners if you want to handle different sets of events separately. However for most use cases, a single listener is sufficient.

Register Event Handlers

The listener object exposes an on method to register event handlers for specific Freemius events. Each handler receives the event data as a parameter.

listener.on('license.created', async ({ objects: { license } }) => {
await syncLicenseFromWebhook(license);
console.log('License created:', license);
});

listener.on(
'subscription.renewal.failed',
async ({ objects: { subscription } }) => {
await sendRenewalFailureEmail(subscription);
console.log('Subscription renewal failed:', subscription);
}
);

The payload of the callback function will be strictly typed based on the event type, providing you with full TypeScript support. You can register multiple handlers for the same event if needed.

tip

You can use TypeScript IntelliSense to explore all available methods on the listener object.

Handling Multiple Events

For events that has same payload, you can pass an array of event names to register the same handler for multiple events:

listener.on(
[
'license.created',
'license.extended',
'license.shortened',
'license.updated',
'license.cancelled',
'license.expired',
'license.plan.changed',
],
async ({ objects: { license } }) => {
await syncLicenseFromWebhook(license);
console.log('License updated/activated/deactivated:', license);
}
);

Process Webhook Requests

Once the listener is set up and handlers are registered, you need to process incoming webhook requests. The SDK provides two methods for this: processFetch for environments that support the Fetch API (like Next.js or Cloudflare Workers), and processNodeHttp for Node.js HTTP servers.

Using the Fetch API (e.g., Next.js, Cloudflare Workers)

The processFetch method processes requests in environments that support the Fetch API:

export async function POST(request: Request): Promise<Response> {
return await webhookService.processFetch(listener, request);
}

You can use it in Next.js API routes, serverless functions, or any environment that supports the Fetch API.

Easy Next.js Integration

In Next.js, you can reduce boilerplate by using the createRequestProcessor method:

const processor = freemius.webhook.createRequestProcessor(listener);

export { processor as POST };

For a more framework-specific example, see the full Next.js integration guide.

Using Node.js HTTP

The processNodeHttp method processes requests in a Node.js HTTP server:

import { createServer } from 'http';

const server = createServer(async (req, res) => {
if (req.url === '/webhook') {
await webhookService.processNodeHttp(listener, req, res);
} else {
res.statusCode = 404;
res.end('Not Found');
}
});

server.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});

Security Considerations

  • The SDK automatically verifies the authenticity of incoming webhook requests using the secret key configured in the Freemius instance.
  • If you want to create your own custom processor, make sure to use the listener.verifyRequest method to validate the request before processing it.