Skip to content

Lemon Squeezy

Connect the Lemon Squeezy webhook so orders, renewals and refunds are credited to the source that brought the buyer.

Lemon Squeezy is a merchant of record, so it handles tax and invoicing and then tells Statsy what was sold. It appears in the app as LemonSqueezy.

Connect Lemon Squeezy

  1. Copy the webhook URL

    In Statsy, open Site settings › Integrations and press Connect on the LemonSqueezy tile. The dialog shows the URL for your site, ending in /api/hooks/lemonsqueezy/ and your ws_ site key, with a copy button.

  2. Add it as a webhook in LemonSqueezy

    Paste the URL into a new webhook endpoint in LemonSqueezy and subscribe it to the events listed below.

  3. Paste the signing secret back

    Lemon Squeezy asks you to choose a signing secret when you create the webhook. Paste it into the second field in the dialog and press Save and connect. It is stored encrypted and never shown again, so keep your own copy.

Which events to subscribe to

EventWhat Statsy does with it
order_createdRecords the payment.
subscription_payment_successRecords a renewal. Only payments whose billing reason is renewal count, so the initial order is not counted twice.
order_refundedRecords a refund.
subscription_cancelled, subscription_expiredMarks the customer as churned.

Passing the visitor through

Lemon Squeezy carries arbitrary custom data through checkout and hands it back on the webhook. The script does this for you on any Lemon Squeezy checkout link a visitor clicks, adding checkout[custom][statsy_vid] to the URL.

If you build checkout URLs yourself, or create them through the Lemon Squeezy API, add the same key:

js
const vid = statsy.visitorId();
const url = new URL('https://yourstore.lemonsqueezy.com/checkout/buy/PRODUCT_ID');
if (vid) url.searchParams.set('checkout[custom][statsy_vid]', vid);
location.href = url.href;

Tip. Custom data is set once, at checkout. Renewals arrive months later carrying the same subscription, so they are matched by customer, not by the original link.

How the webhook is verified

Lemon Squeezy signs the request body with the secret you chose and sends the result in the X-Signature header. Statsy recomputes it and rejects anything that does not match. There is no timestamp in the signature, so the secret is the whole of the security: treat it like a password.

Amounts

Amounts arrive in the smallest unit of the order's currency and are stored in that currency, plus a converted USD figure. Refunds are stored as negative amounts.

Selling somewhere Lemon Squeezy does not cover? Send those payments to the Payment API.

Last updated · Markdown version