# Lemon Squeezy

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

Section: Revenue attribution  
Canonical page: https://statsy.co/docs/revenue/lemon-squeezy  
Last updated: 2026-09-15

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 URLIn 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 LemonSqueezyPaste the URL into a new webhook endpoint in LemonSqueezy and subscribe it to the events listed below.
3. Paste the signing secret backLemon 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

| Event | What Statsy does with it |
| --- | --- |
| `order_created` | Records the payment. |
| `subscription_payment_success` | Records a renewal. Only payments whose billing reason is `renewal` count, so the initial order is not counted twice. |
| `order_refunded` | Records a refund. |
| `subscription_cancelled`, `subscription_expired` | Marks 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](https://statsy.co/docs/revenue/payment-api).

Previous: [Stripe](https://statsy.co/docs/revenue/stripe)  
Next: [Paddle](https://statsy.co/docs/revenue/paddle)