Lemon Squeezy
Connect Lemon Squeezy with an API key. Pulse imports your orders, and a webhook it sets up for you delivers each new sale together with the visitor id the checkout link carried.
Connect Lemon Squeezy#
- Create an API key
In Lemon Squeezy open Settings, API and create a key.
- Paste it into Pulse
Settings, Revenue, Connect, Lemon Squeezy. If your account has more than one store or product, Pulse asks which store to read and, optionally, which product to count (so one store can feed several sites).
- Check the webhook
Pulse registers a webhook in your store automatically when its address is
https. After connecting, Lemon Squeezy's Settings, Webhooks should list one pointing at your Pulse domain. If Pulse could not register it, it shows you the URL, a signing secret and the events to add by hand.
What is synced#
- Orders that are paid, refunded or partially refunded. Test-mode orders are skipped.
- Amount is Lemon Squeezy's USD total minus its USD tax, so every order is in dollars.
- Product is the first order item; country comes from the customer record; the email is stored only as a keyed one-way hash.
- Subscription renewals arrive through the webhook only (the first payment is the order itself, later payments are renewals).
| Webhook event | What Pulse does |
|---|---|
order_created | Stores the order with its custom data (visitor id and source). |
order_refunded | Marks the order refunded. |
subscription_payment_success | Stores renewals (the first payment is skipped, it is the order). |
subscription_payment_refunded | Marks that renewal refunded. |
Attribution#
Nothing to do for links. When a visitor clicks a link to a lemonsqueezy.com checkout (paths starting /buy/ or /checkout/buy/), the script adds two parameters at click time. If your buy button reaches Lemon Squeezy another way (a redirect, a custom domain), mark the link with data-pulse-checkout="lemonsqueezy".
checkout[custom][pulse_vid]=<visitor id>
checkout[custom][source]=<first source: utm_source, ?ref= or the referrer host>Both end up in the order's custom data. Existing parameters on your link are never overwritten, and, unless you turned automatic events off, the click is also logged as a checkout event.
If you create checkouts with the API, pass the same two keys yourself:
// Creating a checkout through the Lemon Squeezy API? Pass the id as custom data.
const vid = window.pulse?.visitorId(); // read it in the browser, send it to your server
// server:
await fetch('https://api.lemonsqueezy.com/v1/checkouts', {
method: 'POST',
headers: { Authorization: 'Bearer ' + process.env.LS_API_KEY, 'Content-Type': 'application/vnd.api+json' },
body: JSON.stringify({ data: { type: 'checkouts', attributes: {
checkout_data: { custom: { pulse_vid: vid, source: 'newsletter' } },
}, relationships: { /* store and variant */ } } }),
});Refunds#
A refunded order, or a refunded renewal, stops counting. A partial refund reduces the sale by the refunded share of its amount and keeps the rest.
Common issues#
- “Lemon Squeezy rejected this API key”
- Create a new key in Settings, API and paste it again.
- Sales have no source
- Check that Settings, Webhooks lists the Pulse webhook, that the buyer clicked a link on a page running the Pulse script, and that the sale is newer than the webhook. Use revenue attribution to see how many orders were traced.
- A test purchase does not show up
- Test-mode orders are ignored on purpose. Make a live order, then refund it.
- I have several stores
- Pick the store you want when you connect. To read two stores, connect them to two sites.