Revenue Tracking
Attribute revenue to traffic sources manually
Overview
The Stripe integration is the easiest way to track revenue. But if you use a different payment processor, have offline sales, or need custom revenue tracking, you can send revenue events directly.
Use cases:
- PayPal, Paddle, Gumroad, or other payment processors
- Offline or enterprise sales
- Custom checkout flows
- Revenue from multiple sources
- Subscription renewals and upgrades
Client-side tracking
Track revenue directly from your frontend after a successful purchase:
// On your thank-you page or purchase confirmation
window.loamly?.event('purchase', {
order_id: 'order_abc123',
amount: 99.00,
currency: 'USD'
});Required properties
| Property | Type | Description |
|---|---|---|
amount | number | Revenue amount (in major currency units, e.g., dollars not cents) |
currency | string | ISO 4217 currency code (USD, EUR, GBP, etc.) |
Optional properties
| Property | Type | Description |
|---|---|---|
order_id | string | Unique order identifier for deduplication |
product | string | Product or plan name |
quantity | number | Number of items purchased |
type | string | Transaction type: purchase, renewal, upgrade, refund |
Examples
// One-time purchase
window.loamly?.event('purchase', {
order_id: 'ord_123',
amount: 299,
currency: 'USD',
product: 'Pro Plan (Annual)'
});
// Subscription renewal
window.loamly?.event('purchase', {
order_id: 'sub_renewal_456',
amount: 29,
currency: 'USD',
product: 'Pro Plan',
type: 'renewal'
});
// Refund (negative amount)
window.loamly?.event('purchase', {
order_id: 'refund_789',
amount: -99,
currency: 'USD',
type: 'refund'
});Deduplication
order_id to prevent duplicate revenue if the confirmation page is refreshed. Loamly will ignore duplicate order IDs.Server-side tracking
For payments that happen entirely server-side (webhooks, API calls), use the Loamly API to send revenue events:
// After receiving a payment webhook
const response = await fetch('https://api.loamly.ai/v1/events', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.LOAMLY_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
event: 'purchase',
email: customer.email, // Required for attribution
properties: {
order_id: payment.id,
amount: payment.amount / 100, // Convert from cents
currency: payment.currency.toUpperCase(),
product: payment.product_name
}
})
});Email matching
For server-side revenue to be attributed, you must include the customer's email. Loamly matches this email to a visitor record to attribute the revenue to the original traffic source.
Match requirements
identify()) before the purchase occurs. If no visitor has that email, the revenue is recorded but unattributed.How attribution works
- Visitor arrives: Loamly tracks their traffic source (ChatGPT, Google, etc.)
- Email captured: Visitor submits a form or is identified
- Purchase occurs: You send a purchase event with the email
- Attribution: Revenue is credited to the original traffic source
Attribution window
By default, Loamly uses a 30-day attribution window. A visitor who first arrived from Perplexity and converts within 30 days has that revenue attributed to Perplexity.
Multi-touch attribution
If a visitor has multiple touchpoints, Loamly uses first-touch attribution by default. The first traffic source gets credit for the conversion.
Best practices
- Always use order_id. This prevents duplicate revenue from page refreshes or retry logic.
- Track refunds. Send refunds as negative amounts to keep revenue accurate.
- Use consistent currency. Convert to a single currency if possible, or let Loamly handle conversion.
- Include product details. This helps segment revenue by product in your reports.
- Test thoroughly. Verify revenue appears correctly in your dashboard before going live.
Prefer Stripe?