Tracking Purchase Events

Last updated: January 30, 2026 • 7 min read

Detailed guide to tracking purchase events correctly, including required parameters, user data, and transaction IDs.

Introduction

Purchase events are the most important conversion events for e-commerce tracking. This guide covers everything you need to know about tracking purchase events correctly with ServerTrack, including required parameters, user data, and best practices.

Critical: Purchase events require accurate user data (email, phone) for optimal event match quality and attribution. Always include user data when available.

When to Fire Purchase Events

Purchase events should be fired when:

  • A customer successfully completes a purchase
  • Payment is confirmed (not just order placed)
  • The order confirmation/thank you page loads
  • All order details are available (transaction ID, products, amounts)

Do NOT fire Purchase events:

  • When cart is created
  • When checkout is initiated
  • Before payment is confirmed
  • On order placement without payment confirmation

Required Parameters

Purchase events require these essential parameters:

transaction_id

Purpose: Unique identifier for the transaction (used for deduplication)

Format: String (alphanumeric)

Example: "ORD-12345" or "20240101-ABC123"

Important: transaction_id must be unique per order. Reusing the same transaction_id will cause issues with deduplication and may result in events being rejected.

value

Purpose: Total transaction value (including taxes, shipping, discounts)

Format: Number (decimal)

Example: 99.99 (for $99.99)

currency

Purpose: Currency code (ISO 4217 format)

Format: String (3-letter code)

Examples: "USD", "EUR", "BDT", "GBP"

Important Optional Parameters

contents (Product Array)

Purpose: Array of products in the order

Format: Array of objects

contents: [
    {
        id: "12345",           // Product ID (string)
        quantity: 2,           // Quantity purchased (number)
        item_price: 29.99      // Price per item (number)
    },
    {
        id: "67890",
        quantity: 1,
        item_price: 49.99
    }
]

content_ids

Purpose: Array of product IDs (used for product catalog matching)

Format: Array of strings

Example: ["12345", "67890"]

shipping

Purpose: Shipping cost

Format: Number

Example: 5.99

tax

Purpose: Tax amount

Format: Number

Example: 8.50

User Data (Critical for Purchase Events)

Purchase events should always include user data for optimal event match quality and attribution:

var userData = {
    em: "customer@example.com",    // Email (will be hashed automatically)
    ph: "+1234567890",             // Phone number (will be hashed)
    fn: "John",                    // First name (hashed)
    ln: "Doe",                     // Last name (hashed)
    ct: "New York",                // City (hashed)
    st: "NY",                      // State (hashed)
    zp: "10001",                   // ZIP code (hashed)
    country: "us"                  // Country code (lowercase, hashed)
};

Note: ServerTrack automatically hashes email, phone, and other PII data using SHA256 before sending to platforms. You send the raw data, and we handle the hashing.

Complete Purchase Event Example

// User data (collected from checkout form)
var userData = {
    em: "john.doe@example.com",
    ph: "+1234567890",
    fn: "John",
    ln: "Doe",
    ct: "New York",
    st: "NY",
    zp: "10001",
    country: "us"
};

// Purchase event
st('track', 'Purchase', {
    currency: "USD",
    value: 104.98,                    // Total: $99.99 (products) + $4.99 (shipping)
    transaction_id: "ORD-20240101-12345",
    shipping: 4.99,
    tax: 0,                           // If applicable
    content_type: 'product',
    content_ids: ["12345", "67890"],  // Product IDs
    contents: [
        {
            id: "12345",
            quantity: 2,
            item_price: 29.99
        },
        {
            id: "67890",
            quantity: 1,
            item_price: 49.99
        }
    ]
}, userData);

Platform-Specific Notes

Facebook Conversions API

  • transaction_id is required and used for deduplication
  • User data (especially email/phone) significantly improves Event Match Quality
  • contents array helps with product catalog matching
  • value should include all charges (products, shipping, tax)

TikTok ePIG

  • Event is automatically mapped to "CompletePayment"
  • Similar requirements to Facebook CAPI
  • User data improves algorithm optimization

Google Analytics 4

  • Event is mapped to "purchase"
  • transaction_id, value, and currency are required
  • Items array (contents) should include item_id, price, and quantity

Implementation Examples

Shopify Implementation

{% if first_time_accessed %}
<script>
var userData = {
    em: "{{ checkout.email }}",
    ph: "{{ checkout.shipping_address.phone }}",
    fn: "{{ checkout.shipping_address.first_name }}",
    ln: "{{ checkout.shipping_address.last_name }}",
    ct: "{{ checkout.shipping_address.city }}",
    country: "{{ checkout.shipping_address.country_code | downcase }}"
};

var contents = [];
{% for line_item in checkout.line_items %}
contents.push({
    id: "{{ line_item.product_id }}",
    quantity: {{ line_item.quantity }},
    item_price: {{ line_item.price | divided_by: 100.0 }}
});
{% endfor %}

st('track', 'Purchase', {
    currency: "{{ checkout.currency }}",
    value: {{ checkout.total_price | divided_by: 100.0 }},
    transaction_id: "{{ checkout.order_id }}",
    shipping: {{ checkout.shipping_price | divided_by: 100.0 }},
    content_ids: [{% for line_item in checkout.line_items %}"{{ line_item.product_id }}"{% unless forloop.last %},{% endunless %}{% endfor %}],
    contents: contents
}, userData);
</script>
{% endif %}

WooCommerce Implementation

add_action('woocommerce_thankyou', 'track_purchase_event', 10, 1);
function track_purchase_event($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    $userData = array(
        'em' => $order->get_billing_email(),
        'ph' => $order->get_billing_phone(),
        'fn' => $order->get_billing_first_name(),
        'ln' => $order->get_billing_last_name(),
        'ct' => $order->get_billing_city(),
        'country' => strtolower($order->get_billing_country())
    );

    $contents = array();
    foreach ($order->get_items() as $item) {
        $contents[] = array(
            'id' => (string)$item->get_product_id(),
            'quantity' => $item->get_quantity(),
            'item_price' => $item->get_subtotal() / $item->get_quantity()
        );
    }

    $eventData = array(
        'currency' => $order->get_currency(),
        'value' => $order->get_total(),
        'transaction_id' => (string)$order_id,
        'shipping' => $order->get_shipping_total(),
        'content_ids' => array_map(function($item) {
            return (string)$item->get_product_id();
        }, $order->get_items()),
        'contents' => $contents
    );

    echo "<script>st('track', 'Purchase', " . json_encode($eventData) . ", " . json_encode($userData) . ");</script>";
}

Best Practices

  • Always include user data: Email and phone significantly improve event match quality
  • Use unique transaction IDs: Never reuse transaction IDs
  • Include all charges: value should equal sum of products + shipping + tax
  • Fire on confirmation page: Only fire after payment is confirmed
  • Include product details: contents array helps with product catalog and optimization
  • Test thoroughly: Use test purchases to verify events before going live

Testing Purchase Events

  • Complete a test purchase on your store
  • Check ServerTrack dashboard → Event Logs
  • Look for Purchase event with status "success" or "pending"
  • Verify all parameters are present and correct
  • Check Facebook Events Manager Test Events (should appear within seconds)
  • Verify transaction_id is unique and not duplicated

Troubleshooting

Purchase Events Not Appearing

  • Verify script is loaded before purchase event code
  • Check that event is firing on the correct page (order confirmation)
  • Ensure Server Deck status is "Active"
  • Review event logs for error messages

Duplicate Purchase Events

  • Ensure transaction_id is unique for each order
  • Fire event only once per order (use flags to prevent duplicate fires)
  • Check if both browser pixel and server-side are firing (should use same event_id for deduplication)

Summary

Purchase events are critical for conversion tracking. Always include:

  • Required: transaction_id, value, currency
  • Recommended: user data (email, phone), contents array, shipping, tax
  • Fire only after payment confirmation
  • Use unique transaction IDs
  • Test thoroughly before going live

For more information, see our Standard Events Reference Guide and User Data Collection and Privacy guide.

Was this article helpful?

Please log in to provide feedback on this article.