# Lemon Squeezy

Attribute Lemon Squeezy orders from the Checkout API or plain checkout links.

## 1. Connect Lemon Squeezy

1. In VisitTrack, open **Settings → Revenue** and pick **Lemon Squeezy**.
2. Copy the webhook URL shown there. It looks like `https://visitrack.app/api/lemonsqueezy-webhook/YOUR_SITE_ID`.
3. In Lemon Squeezy: Settings → Webhooks → **+**, with a signing secret of your choice. Paste the URL and subscribe to `order_created` and `order_refunded`.
4. Copy the same signing secret Lemon Squeezy gives you back into VisitTrack and press **Connect**. It's stored encrypted and only used to verify signatures.

## 2. Pass the visitor id

Lemon Squeezy calls it custom data. Set `visitrack_visitor_id` there, either through the API or as a URL parameter on a checkout link.

Checkout API:
```
import { createCheckout } from "@lemonsqueezy/lemonsqueezy.js";

const { data } = await createCheckout(storeId, variantId, {
  checkoutData: {
    custom: { visitrack_visitor_id: visitorId ?? "" },
  },
});

return Response.json({ url: data?.data.attributes.url });
```

Checkout links:
```
<script>
  document.addEventListener("DOMContentLoaded", () => {
    const visitorId = localStorage.getItem("_ana_vid");
    if (!visitorId) return;
    document.querySelectorAll('a[href*=".lemonsqueezy.com/checkout"]').forEach((a) => {
      const url = new URL(a.href);
      url.searchParams.set("checkout[custom][visitrack_visitor_id]", visitorId);
      a.href = url.toString();
    });
  });
</script>
```

## Events

| Event | What VisitTrack does |
| --- | --- |
| `order_created` | Records the order (`total`, `currency`, `user_email`) against the visitor in `meta.custom_data.visitrack_visitor_id`. |
| `order_refunded` | Subtracts `refunded_amount` from the original order. |
| anything else | Acknowledged with `200` and ignored. |

> **Subscriptions** — Recurring payments don't create a new order in Lemon Squeezy, so only the first payment of a subscription is attributed. That's usually the one you care about: it's the payment the channel actually earned.

## Test it

1. Open your site in a normal browser tab so the tracker records a visit (localhost is ignored unless the script tag has `data-allow-local`).
2. Complete a checkout in test mode.
3. Open **Revenue** in the dashboard. The payment shows up within a few seconds, with the referrer, campaign and landing page that brought that visitor in.

> **Nothing showed up?** — See [Missing or unattributed payments](https://visitrack.app/docs/revenue-troubleshooting). The webhook response body always says why a payment was skipped.
