Pro Plan15 minutesintermediate

Setting Up Revenue Attribution

Configure revenue tracking and attribution - connect purchases to traffic sources with step-by-step implementation.

revenueattributionsetuptracking
Last updated: January 15, 2025
Pro Plan

Set up revenue attribution to track which marketing channels drive actual sales. Step-by-step implementation guide.

Prerequisites

Before starting:

  • Zenovay tracking script installed
  • Access to checkout/purchase code
  • Revenue goal enabled

Basic Setup

Simple Revenue Tracking

Track revenue when a purchase completes:

// On order confirmation page or in success callback
zenovay('revenue', 99.99, 'USD');

That's it for basic tracking!

With Goal Name

Associate with a specific goal:

zenovay('goal', 'purchase', {
  value: 99.99
});

Complete Implementation

Full Revenue Object

Include all relevant data:

zenovay('revenue', 149.99, 'USD', {
  // Recommended
  order_id: 'ORD-12345',

  // Optional - for detailed analysis
  items: [
    {
      id: 'SKU-001',
      name: 'Product Name',
      price: 49.99,
      quantity: 2,
      category: 'Electronics'
    },
    {
      id: 'SKU-002',
      name: 'Accessory',
      price: 50.00,
      quantity: 1,
      category: 'Accessories'
    }
  ],

  // Optional metadata
  coupon: 'SAVE10',
  shipping: 9.99,
  tax: 12.50
});

Implementation by Platform

Shopify

For Shopify stores:

  1. Go to Settings → Checkout
  2. Add to "Order status page":
{% if first_time_accessed %}
<script>
  zenovay('revenue', {{ total_price | money_without_currency }}, '{{ currency }}', {
    order_id: '{{ order_number }}',
    items: [
      {% for item in line_items %}
      {
        id: '{{ item.sku }}',
        name: '{{ item.title | escape }}',
        price: {{ item.final_price | money_without_currency }},
        quantity: {{ item.quantity }}
      }{% unless forloop.last %},{% endunless %}
      {% endfor %}
    ]
  });
</script>
{% endif %}

WooCommerce

For WordPress/WooCommerce:

  1. Add to your theme's functions.php or a plugin:
add_action('woocommerce_thankyou', 'zenovay_track_revenue');
function zenovay_track_revenue($order_id) {
    $order = wc_get_order($order_id);
    ?>
    <script>
    zenovay('revenue', <?php echo $order->get_total(); ?>, '<?php echo $order->get_currency(); ?>', {
        order_id: '<?php echo $order_id; ?>'
    });
    </script>
    <?php
}

React/Next.js

In your checkout success component:

import { useEffect } from 'react';

function OrderConfirmation({ order }) {
  useEffect(() => {
    if (order && window.zenovay) {
      window.zenovay('revenue', order.total, order.currency, {
        order_id: order.id,
        items: order.items.map(item => ({
          id: item.sku,
          name: item.name,
          price: item.price,
          quantity: item.quantity
        }))
      });
    }
  }, [order]);

  return <div>Thank you for your order!</div>;
}

Server-Side Tracking

Enterprise Plan

For secure server-side tracking, use the tracking endpoint with your tracking code:

// Node.js example - use the tracking endpoint directly
app.post('/api/order/complete', async (req, res) => {
  const order = await processOrder(req.body);

  await fetch('https://api.zenovay.com/e/YOUR_TRACKING_CODE', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Forwarded-For': req.headers['x-forwarded-for'] || req.socket.remoteAddress,
    },
    body: JSON.stringify({
      type: 'revenue',
      url: req.headers.referer || 'https://yoursite.com/checkout',
      revenue: order.total,
      order_id: order.id,
      currency: 'USD'
    }),
  });

  res.json({ success: true });
});

Attribution Configuration

Attribution Window

Set how long to attribute:

  1. Go to your domain settings → Revenue tab
  2. Choose window length
  3. Save
WindowUse Case
7 daysQuick purchases
14 daysStandard e-commerce
30 daysConsidered purchases
60 daysB2B/high-value

Attribution Model

Choose how credit is assigned:

  1. Go to your domain settings → Revenue tab
  2. Select default model
  3. Apply to reports

Models available:

  • Last Touch (default)
  • First Touch
  • Linear
  • Time Decay
  • Position-Based

Cross-Device Attribution

Enterprise Plan

Track across devices:

  1. Identify users when they log in
  2. Journey stitched automatically
  3. Full path visible
// When user logs in
zenovay('identify', userId);

UTM Parameter Setup

Campaign Tracking

Ensure UTM parameters are used:

https://yoursite.com/?utm_source=google
                     &utm_medium=cpc
                     &utm_campaign=spring_sale
                     &utm_content=banner_1

UTM Parameters

ParameterPurposeExample
utm_sourceTraffic sourcegoogle, facebook
utm_mediumMarketing mediumcpc, email
utm_campaignCampaign namespring_sale
utm_contentAd variantbanner_a
utm_termKeywordsblue shoes

Testing Setup

Debug Mode

Enable debug logging:

zenovay('debug');

Then track a test purchase and check console.

Test Purchase

  1. Place test order
  2. Check browser console
  3. Verify in real-time view
  4. Confirm in revenue report

Verification Checklist

  • Revenue value correct
  • Order ID recorded
  • Items tracked (if sent)
  • Source attributed correctly
  • Currency correct

Handling Edge Cases

Recurring Revenue

For subscriptions:

// Track initial purchase
zenovay('revenue', 29.99, 'USD', {
  order_id: 'SUB-001',
  type: 'subscription',
  interval: 'monthly'
});

// Track renewals
zenovay('revenue', 29.99, 'USD', {
  order_id: 'SUB-001-RENEWAL',
  type: 'subscription_renewal',
  original_order: 'SUB-001'
});

Refunds

Handle refunds properly:

// Track refund
zenovay('revenue', -49.99, 'USD', {
  order_id: 'REFUND-ORD-12345',
  type: 'refund',
  original_order: 'ORD-12345'
});

Partial Shipments

If revenue is recognized at shipping:

// Track each shipment
zenovay('revenue', 50.00, 'USD', {
  order_id: 'ORD-12345-SHIP-1',
  parent_order: 'ORD-12345'
});

Data Quality

Prevent Duplicates

Ensure revenue isn't tracked twice:

// Using localStorage to prevent duplicates
function trackOrderOnce(order) {
  const tracked = localStorage.getItem(`tracked_${order.id}`);
  if (tracked) return;

  zenovay('revenue', order.total, 'USD', {
    order_id: order.id
  });

  localStorage.setItem(`tracked_${order.id}`, 'true');
}

Validate Before Sending

Check data quality:

function trackRevenue(orderData) {
  // Validate
  if (!orderData.value || orderData.value <= 0) {
    console.warn('Invalid order value');
    return;
  }

  if (!orderData.order_id) {
    console.warn('Missing order ID');
    return;
  }

  // Track
  zenovay('revenue', orderData.value, orderData.currency || 'USD', {
    order_id: orderData.order_id
  });
}

Troubleshooting

Revenue Not Appearing

If revenue doesn't show:

  1. Check tracking fires

    • Debug mode enabled?
    • Console errors?
  2. Verify goal setup

    • Revenue goal created?
    • Goal active?
  3. Check timing

    • After page fully loads?
    • In correct callback?
  4. Validate data

    • Value is number?
    • Not $0?

Attribution Missing

If source not credited:

  1. Check UTM parameters present
  2. Verify referrer not blocked
  3. Check attribution window
  4. Review cookie settings

Amounts Don't Match

If totals differ from accounting:

  1. Compare date ranges
  2. Check for refunds
  3. Verify currency handling
  4. Look for missing orders

Security Considerations

Client-Side Limitations

Be aware:

  • Values can be manipulated
  • Not for billing purposes
  • For analytics only

Server-Side for Accuracy

For critical accuracy:

  • Implement server-side tracking
  • Verify against backend
  • Use for reporting

Next Steps

Was this article helpful?