Revenue attribution
Pulse shows how much money each source, page, country and device brought, not just how many people they sent. It does this by tying every paid order to the visit that led to it.
How it works#
- The script gives each visitor an id.
The first time your page reports a visit, Pulse answers with an anonymous visitor id (a salted hash, rotated monthly). The script keeps it in the tab's session storage.
- The id travels with the checkout.
When a visitor clicks a Lemon Squeezy, Stripe Payment Link or Polar checkout link, the script adds the id to the link. It recognises them by address: Lemon Squeezy
/buy/…and/checkout/buy/…links,buy.stripe.com, and Polar checkout links. Any other link that leads to one of these checkouts can be marked withdata-pulse-checkout="lemonsqueezy"(orstripe,polar). For Paddle, or checkouts you create on your server, you pass the id yourself (see each provider). - Your provider reports the payment.
Pulse reads orders with a read-only key and also listens to the provider's webhooks, so new sales arrive within seconds.
- Pulse credits the visitor's first visit.
The order is joined to the earliest event Pulse recorded for that visitor id. That visit's source, channel, campaign, landing page, country and device get the revenue.
The rules#
- First visit wins. A sale is credited to where the buyer first arrived, not the last click before paying. A visitor who found you on Threads, came back from Google and then bought is a Threads sale.
- Net of tax. Amounts are what you receive before fees and after tax (total minus tax). Pulse does not subtract payment fees.
- Refunds leave the totals. A fully refunded order stops counting, and a partial refund reduces the sale by the refunded share, on every provider. Lost chargebacks count as refunds on Stripe and Paddle. Without webhooks, Pulse still finds refunds of sales up to 90 days old, within 6 hours.
- Source name.
utm_source(or?ref=) if the first visit had one, otherwise the referrer host, otherwise Direct. - Unmatched orders still count. They add to Sales and Revenue on Analytics, but they have no source. Pulse says how many orders it could trace, for example “5 of 8 orders traced to a visit”.
- Test orders are skipped (Lemon Squeezy test mode).
- Emails are stored only as a keyed one-way hash, to count repeat customers. The dashboard never shows them.
Connect your provider#
Open Settings, Revenue, click Connect on a site, pick a provider, and paste a read-only key. Pulse checks the key, imports the last 365 days, and registers a webhook for you. Keys are encrypted at rest.
| Provider | Key | Links tagged for you | Webhook events |
|---|---|---|---|
| Stripe | Restricted key | Payment Links (buy.stripe.com) | checkout.session.completed, checkout.session.async_payment_succeeded, invoice.paid, charge.refunded |
| Lemon Squeezy | API key | Checkout links | order_created, order_refunded, subscription_payment_success, subscription_payment_refunded |
| Polar | Organization access token | Checkout links (buy.polar.sh) | order.paid, order.refunded |
| Paddle | API key | None: pass the id in custom data | transaction.completed, adjustment.created, adjustment.updated |
How fresh is it#
- Webhook: a new sale is stored within seconds and keeps the visitor id the checkout carried.
- Background resync: whenever you open the dashboard, connections not synced for 10 minutes are refreshed (with a one-day overlap so late-settling payments are not missed).
- Sync now in Settings, Revenue re-imports the last 365 days on demand.
Longer attribution (opt-in)#
By default the visitor id and first source live in the tab's session storage, so a buyer who closes the tab and pays three days later has no id to carry and the sale arrives untraced. If your customers often decide slowly, add data-attribution to the script tag:
<script defer data-site="YOUR_SITE_ID" data-attribution="30d" src="https://stats.shedi.app/script.js"></script>Use 7d, 30d or 90d. The script then keeps the visitor id and first source in localStorage (key pulse_ft) until they expire, and puts them on checkout links whenever the buyer returns. The sale is credited to the first visit as usual.
Currencies#
Pulse shows everything in US dollars. Lemon Squeezy reports a USD amount for each order, and Pulse uses it. For Stripe, Polar and Paddle, each order is converted when you view it, at the exchange rate of the day it was paid: the ECB's daily rates, with a free fallback source for currencies the ECB does not publish. Rates are cached in the database. If no rate can be found for a currency, those orders are left out of the totals and the dashboard says how many.
One store, several sites#
If one provider account sells products for several sites, pick the product when you connect (Lemon Squeezy shows a picker). Pulse then keeps only orders whose product name contains that text, so each site sees its own sales.
Imported Umami sites#
Sites imported from Umami have no Pulse events, so there is no visit to join. Revenue still syncs, and a sale gets a source only when the checkout carried a source value in its custom data. See Import from Umami.
Guides by provider#
Common issues#
- Sales show up but with no source
- The checkout did not carry a visitor id. Make sure the script is on the page with the buy link, the link points at the provider's hosted checkout, and (Lemon Squeezy) the webhook is connected. Sales made before you installed the script cannot be traced.
- Sales are missing
- Check Settings, Revenue: the connection should say Connected. Click Sync now. If the product filter is set, orders for other products are skipped on purpose.
- Revenue is lower than my store’s total
- Stores show what customers paid, tax and refunded orders included (Lemon Squeezy calls it “All revenue”). Pulse shows what you keep: that total minus tax and refunds, before payment fees. The Revenue mix card shows the bridge: charged, then tax, then refunds, then net. They add up to the cent.
- Totals look too high or too low
- Mixed currencies (see above), or refunds that were partial. Pulse reports net of tax and before payment fees.
- Can I attribute a sale to the last click instead?
- No. Pulse always credits the first visit.