Revfaro Docs

Revenue attribution

Connect Lemon Squeezy

Send Lemon Squeezy orders, subscription payments and refunds to Revfaro with a webhook, and pass the visitor to checkouts as custom data.

In short

Add a webhook in Lemon Squeezy for order_created, order_refunded, subscription_payment_success and subscription_payment_refunded pointing to your website's Revfaro address, with a signing secret you choose (and paste into Revfaro as well). Pass the visitor in the checkout's custom data; hosted checkout links and Lemon.js buttons on your pages are tagged by the script. Set each product's confirmation and receipt button to your site with ?order_identifier=[order_identifier].

On this page

You need a Lemon Squeezy store and a website in Revfaro with tracking installed. Open Website settings › Setup, go to Connect payments and choose the Lemon Squeezy tab.

These steps work with the script or npm SDK. With npm, initialize tracking on checkout and return pages, and use your shared tracker.attribution() instead of window.revfaro?.attribution?.() in browser examples. The SDK does not create a window global.

The Lemon Squeezy tab of Connect payments with the webhook address and signing secret
Website settings › Setup › Connect payments › Lemon Squeezy.
  1. Add the webhook in Lemon Squeezy

    In Lemon Squeezy, go to Settings › Webhooks and add a webhook with your website's address from the Lemon Squeezy tab:

    https://revfaro.com/api/webhooks/lemonsqueezy/YOUR_SITE_ID

    Select order_created, order_refunded, subscription_payment_success and subscription_payment_refunded. Add it in live mode: test-mode orders are acknowledged but never counted.

  2. Use the same signing secret in both places

    Lemon Squeezy asks you to choose the webhook's signing secret, a random string of 6 to 40 characters. Click Generate a secret in the Lemon Squeezy tab to get one, enter the same secret in Lemon Squeezy, then click Save in Revfaro. The tab shows Connected.

  3. Pass the visitor to your checkout

    When your server creates a checkout with the Lemon Squeezy API, add the visitor's cookies as custom data:

    checkout.ts
    import { createCheckout } from '@lemonsqueezy/lemonsqueezy.js';
    
    const jar = await cookies(); // next/headers
    
    await createCheckout(STORE_ID, VARIANT_ID, {
      checkoutData: {
        custom: {
          rf_visitor_id: jar.get('rf_vid')?.value ?? '',
          rf_session_id: jar.get('rf_sid')?.value ?? '',
        },
      },
    });

    Calling the REST API directly? The same two keys go into data.attributes.checkout_data.custom.

  4. Send buyers back to your site

    In each product's Confirmation modal and Email receipt settings, set the button link to a page on your site with the order number:

    https://example.com/thanks?order_identifier=[order_identifier]

    Use the UUID order_identifier; sequential order_id values are not accepted for attribution because they can be guessed. Lemon Squeezy fills in [order_identifier], and Revfaro links the order to whoever lands there, even without custom data. The page must load the script and must not be excluded.

Hosted checkout links (https://STORE.lemonsqueezy.com/checkout/buy/…), including Lemon.js overlay buttons, need no code: the script adds checkout[custom][rf_visitor_id] and checkout[custom][rf_session_id] to them, which Lemon Squeezy saves as custom data.

Opening a checkout from your own code, such as LemonSqueezy.Url.Open(url)? Add the same parameters yourself:

JavaScript
const { rf_visitor_id, rf_session_id } = window.revfaro?.attribution?.() ?? {};
const url = new URL('https://STORE.lemonsqueezy.com/checkout/buy/VARIANT');
if (rf_visitor_id) {
  url.searchParams.set('checkout[custom][rf_visitor_id]', rf_visitor_id);
  url.searchParams.set('checkout[custom][rf_session_id]', rf_session_id);
}
LemonSqueezy.Url.Open(url.toString());

What Revfaro records

  • Orders: order_created, including the first payment of a subscription.
  • Renewals: subscription_payment_success is credited to the visitor who first subscribed.
  • Refunds: order_refunded and subscription_payment_refunded are subtracted, partial refunds included.
  • Currency: when your website's revenue currency is USD, orders paid in another currency are counted with Lemon Squeezy's USD amount.

Requests are checked against Lemon Squeezy's X-Signature header, so only your store can send payments to your website.

Frequently asked questions

Do Lemon Squeezy checkout links and Lemon.js overlays work?

Yes. The script adds the visitor as custom data (checkout[custom][rf_visitor_id]) to every lemonsqueezy.com/checkout/buy/ link on your pages, including Lemon.js overlay buttons.

Are Lemon Squeezy test-mode orders counted?

No. Test-mode events are acknowledged but never counted, so you can test your setup safely.

My store sells products for several websites. What happens?

A Lemon Squeezy store sends every order to every webhook. Add the webhook to each website in Revfaro; a payment counts where its buyer was tracked, or where the same customer paid before. Orders with neither signal count on every website that has the webhook, so pass the visitor at checkout.

Last updated · View as Markdown