Measuring
Revenue
Add an amount and a currency to any event — a purchase, a subscription, an upgrade — and the Revenue page shows what people paid, where they came from and when. Every figure opens the query that produced it, like everything else here.
Send it
vitrus("purchase", { revenue: 49.90, currency: "USD" });
Or on a button or link, without code:
<button data-vitrus="purchase" data-vitrus-event-revenue="49.90" data-vitrus-event-currency="USD">Buy</button>
From your server — the most reliable place, because a payment is confirmed there and not in the
browser — post the event to /api/d and name the visitor with two headers.
The visitor id is a hash of IP and user agent, so with both the purchase joins the visit that led to it;
without them it would count as a separate visitor from your server.
curl https://app.vitrus.dev/api/d -H "Content-Type: application/json" -H "User-Agent: <the visitor's user agent>" -H "X-Vitrus-Client-IP: <the visitor's IP>" -d '{"site":"SITE_ID","type":"event","name":"purchase","url":"/checkout/done", "props":{"revenue":49.90,"currency":"USD"}}'
| Property | Rule |
|---|---|
revenue | A number, in the currency's main unit (dollars, not cents), 0 or more, at most one billion. A numeric string such as "49.90" is accepted; "49,90" and "$49" are not. |
currency | A three-letter ISO 4217 code: USD, EUR, TRY… Case does not matter. |
What you see
| Figure | How it is counted |
|---|---|
| Revenue | The sum of the amounts, in one currency. |
| Orders | Events that carried an amount. |
| Average order value | Revenue ÷ orders. |
| Revenue per visitor | Revenue ÷ all visitors in the window, not just the ones who paid — what a visit is worth. |
| Conversion rate | Sessions with at least one payment ÷ all sessions. |
Broken down by channel, source, campaign, event, page, country and device, and over time, with the previous period for comparison. Filters apply as everywhere else. Channel, source and campaign are where the visit came from — the first page of the session — not the checkout page, which almost never has an outside referrer; page, event, country and device are the payment's own.
Three deliberate choices
- No currency conversion. Each currency is reported on its own. A total in "USD" that includes converted euros would depend on an exchange rate from somewhere else, and that number could not be checked against anything in your data. If you sell in several currencies, the page shows a tab each.
- A bad amount never loses the event. If the amount is not a number, negative, or has no currency, the event is still recorded and the page tells you how many amounts were rejected and why — it does not quietly report less.
- People only. Bots are excluded, as everywhere. Purchases in sessions driven by a verified AI agent are shown on their own line, not added to the totals — an agent that checks out is revenue, but it is not a visitor.
Refunds
Negative amounts are rejected. Record a refund as its own event — for example
vitrus("refund", { refund_amount: 49.90, currency: "USD" }) — so the original
sale stays what it was and the refund is visible as a separate event.