LemonSqueezy

Set up revenue attribution with LemonSqueezy.

LemonSqueezy

LemonSqueezy is a merchant of record that handles payments, taxes, and subscriptions. This guide shows how to pass EngageTrack visitor and session IDs through LemonSqueezy's custom_data field for revenue attribution.

How It Works

  1. The EngageTrack SDK generates a visitor ID and session ID (stored in browser storage, accessible via the SDK's JavaScript API)
  2. When creating a checkout, you pass these values in the custom_data field
  3. After payment, LemonSqueezy sends a webhook to EngageTrack with the custom data
  4. EngageTrack reads the visitor ID and attributes the revenue to the traffic source

Checkout API

Node.js / Express

import { lemonSqueezySetup, createCheckout } from "@lemonsqueezy/lemonsqueezy.js";
 
lemonSqueezySetup({ apiKey: process.env.LEMONSQUEEZY_API_KEY });
 
app.post("/create-checkout", async (req, res) => {
	// Receive visitor/session IDs from the client request body
	const { engagetrack_visitor_id: visitorId, engagetrack_session_id: sessionId } = req.body;
 
	const { data } = await createCheckout(process.env.LEMONSQUEEZY_STORE_ID, {
		productOptions: {
			redirectUrl: "https://yoursite.com/success",
		},
		checkoutData: {
			custom: {
				engagetrack_visitor_id: visitorId,
				engagetrack_session_id: sessionId,
			},
		},
	});
 
	res.json({ url: data.data.attributes.url });
});

Next.js App Router (Route Handler)

import { NextRequest, NextResponse } from "next/server";
import { lemonSqueezySetup, createCheckout } from "@lemonsqueezy/lemonsqueezy.js";
 
lemonSqueezySetup({ apiKey: process.env.LEMONSQUEEZY_API_KEY! });
 
export async function POST(request: NextRequest) {
	// Receive visitor/session IDs from the client request body
	const { variant_id, engagetrack_visitor_id, engagetrack_session_id } =
		await request.json();
	const visitorId = engagetrack_visitor_id ?? "";
	const sessionId = engagetrack_session_id ?? "";
 
	const { data } = await createCheckout(process.env.LEMONSQUEEZY_STORE_ID!, {
		productOptions: {
			redirectUrl: "https://yoursite.com/success",
		},
		checkoutData: {
			variantId: Number(variant_id),
			custom: {
				engagetrack_visitor_id: visitorId,
				engagetrack_session_id: sessionId,
			},
		},
	});
 
	return NextResponse.json({ url: data!.data.attributes.url });
}

LemonSqueezy uses custom_data (accessed via the custom field in the SDK) to pass arbitrary data through the checkout. EngageTrack expects the keys engagetrack_visitor_id and engagetrack_session_id inside this object.

If you use LemonSqueezy Checkout Links (no server code), append the custom data as URL parameters:

<a id="ls-checkout" href="https://yourstore.lemonsqueezy.com/buy/abc123">
	Buy Now
</a>
 
<script>
	document.addEventListener("DOMContentLoaded", function () {
		const visitorId = window.engagetrack?.getVisitorId() || "";
		const sessionId = window.engagetrack?.getSessionId() || "";
 
		document
			.querySelectorAll('a[href*="lemonsqueezy.com/buy"]')
			.forEach((link) => {
				const url = new URL(link.href);
				url.searchParams.set(
					"checkout[custom][engagetrack_visitor_id]",
					visitorId,
				);
				url.searchParams.set(
					"checkout[custom][engagetrack_session_id]",
					sessionId,
				);
				link.href = url.toString();
			});
	});
</script>

The URL parameter syntax for LemonSqueezy checkout links uses bracket notation: checkout[custom][engagetrack_visitor_id]. This is how LemonSqueezy maps URL parameters to the custom_data field.

Set Up the Webhook

  1. Go to LemonSqueezy Dashboard → Settings → Webhooks
  2. Click Add endpoint
  3. Enter the webhook URL:
https://api.engagetrack.net/api/v1/webhooks/revenue/lemonsqueezy/{YOUR_SITE_PUBLIC_ID}
  1. Under Events, select:
    • order_created
    • subscription_payment_success
    • order_refunded
  2. Enter a signing secret and save it — you will need this when connecting LemonSqueezy in EngageTrack
  3. Click Save

If you connected LemonSqueezy via the EngageTrack dashboard (Site Settings → Revenue), the webhook is registered automatically and you can skip this step.

Verify

  1. Open your site and confirm the SDK is loaded by running window.engagetrack.getVisitorId() in the browser console
  2. Complete a test purchase using LemonSqueezy's test mode
  3. Go to your EngageTrack dashboard → Revenue tab
  4. The test payment should appear within a few seconds, attributed to your traffic source

If the payment appears without attribution:

  • Check the LemonSqueezy webhook logs for delivery errors (LemonSqueezy Dashboard → Webhooks → select endpoint)
  • Verify the custom_data field in the webhook payload contains engagetrack_visitor_id
  • Ensure the cookie values are non-empty when creating the checkout