WebTracker tracks three things: web traffic, downloads and sales. Traffic and downloads come from a tiny script in your pages; sales come from your server as events. Everything lands in the same event stream, so revenue, campaigns and downloads can be compared side by side.
Paste this into your site's <head>. Replace wbf_xxx with the tracking ID shown for your site in Sites.
<script async src="https://webtracker.app/w.js" data-site="wbf_xxx"></script>
The script is cookie-free: it uses a first-party anonymous ID and a session ID, records pageviews (including single-page-app route changes), referrers, device, OS and country, and stores UTM parameters for the whole session so campaign attribution survives redirects.
Call webtracker from anywhere on the page. Any properties you pass are stored with the event and become selectable columns in the Events panel.
window.webtracker('track', 'Signup', { plan: 'pro' });
window.webtracker('track', 'Trial started', { product: 'iCash' });Downloads are first-class in WebTracker. The script automatically sends a Download event when a visitor clicks a link to a downloadable file (.dmg, .exe, .zip, .pkg, .msi, and similar). The Downloads panel then shows totals for today, this week, this month and all time — each compared with the previous period — plus top files, operating systems and countries.
To record a download from your own code (for example a server-side download script or a button that streams a file), send the event yourself:
window.webtracker('track', 'Download', {
file: 'MaxBulkMailer.dmg',
product_name: 'MaxBulk Mailer',
version: '8.7.2',
os: 'macOS'
});Country is filled in automatically from the request when you don't provide one.
Sales are tracked with a Sale event sent from your server — your order script, your payment callback, or your IPN handler. Server-side means no ad blocker and no browser required, and it works with any payment provider (Stripe, PayPal, FastSpring, CoinPayments, bank transfer, manual orders…).
Endpoint — POST https://webtracker.app/api/public/collect/event with a JSON body:
{
"tid": "wbf_xxx",
"name": "Sale",
"path": "/checkout/complete",
"props": {
"transaction_id": "9GH12345XY",
"sku": "MBM-PRO",
"quantity": 1,
"product_name": "MaxBulk Mailer Pro",
"customer_name": "Jane Doe",
"customer_email": "jane@example.com",
"invoice_number": "INV-10231",
"store_name": "PayPal",
"country_code": "US",
"os": "macOS",
"amount_cents": 8900,
"currency": "USD",
"profit_cents": 7600
}
}amount_cents and profit_cents are integers in the smallest unit of currency. Non-USD amounts are converted to USD for reporting.transaction_id is what makes an order unique, so retries and imports never create duplicates.
Example in PHP:
$payload = json_encode([
'tid' => 'wbf_xxx',
'name' => 'Sale',
'props' => [
'transaction_id' => $txn,
'sku' => $sku,
'quantity' => (int) $qty,
'product_name' => $product,
'customer_email' => $email,
'store_name' => 'PayPal',
'country_code' => $country,
'amount_cents' => (int) round($amount * 100),
'currency' => $currency,
'profit_cents' => (int) round($profit * 100),
],
]);
$ch = curl_init('https://webtracker.app/api/public/collect/event');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 200 = stored. Anything else: queue the payload and retry later.The endpoint only answers 200 when the event is stored. Treat any other status as "not recorded yet" and retry — the recommended pattern is to append the JSON payload to a local queue_events/ folder and flush it from a cron job, so a slow network never loses a sale. The Integrations panel in the app has ready-made cURL, PHP, Python and Node.js snippets with your real tracking ID.
Send a Refund event with the same transaction_id as the original sale. The order is marked refunded and refunded amounts are excluded from net revenue while remaining visible in the refund totals.
{ "tid": "wbf_xxx", "name": "Refund", "props": { "transaction_id": "9GH12345XY", "amount_cents": 8900, "currency": "USD" } }Have years of orders in a spreadsheet or a database export? Use Sales → Import to upload a CSV and map the columns. Common export headers are detected automatically, foreign currencies are converted to USD, and rows whose transaction ID already exists are skipped. The same importer handles refund files.
In Settings you choose your timezone and whether the week starts on Monday or Sunday. Every "today", "this week" and "this month" figure across Sales, Downloads and Dashboard is calculated with those settings, so your reports match your own calendar.