Skip to main content
ElasticFunnels provides two ways to display order information on your pages: the <order> HTML tag (for the visual builder) and the getOrders() backend function (for code-based pages). Both retrieve the same data from the customer’s purchase history.

Two Approaches

ApproachBest forUsed in
<order> tagVisual builder pages, simple layoutsDrag-and-drop editor
getOrders() functionCode-based pages, complex layouts with full template controlBackend scripts / .ef pages

Using the <order> Tag

The <order> tag is processed server-side and automatically loops through the customer’s purchase history. See the full Order Tag reference for all placeholders and options.
<order sort-by="newest" limit="5">
  <h3>Order #{order_number}</h3>
  <p>Date: {order_date}</p>
  <p>Shipping: {shipping_address}</p>

  <order-product>
    <img src="{product_image_url}" alt="{product_name}" />
    <p>{product_name} — {price}</p>
  </order-product>

  <order-bonus-product>
    <p>Bonus: {bonus_product_name}</p>
    <a href="{bonus_download}">Download</a>
  </order-bonus-product>
</order>

Using getOrders() in Backend Scripts

For code-based pages (.ef files or pages with backend scripts), getOrders() gives you full control over the layout. It returns an array of order objects you can loop through with @foreach.

Basic Usage

<script scope="backend">
var orders = getOrders('newest', 10);
setVariable('orders', orders);
</script>

@if(orders.length gt 0)
  @foreach(order in orders)
  <div class="order-card">
    <h3>Order #{{ order.order_number }}</h3>
    <p>{{ order.created_at | date:'dd, MMM yyyy' }}</p>

    @foreach(product in order.products)
    <div class="product-row">
      <img src="{{ product.image_url }}" alt="{{ product.name }}" />
      <span>{{ product.name }}</span>
      <span>{{ product.price | formatPrice:product.currency_code }}</span>
    </div>
    @endforeach
  </div>
  @endforeach
@else
  <p>No orders found.</p>
@endif

Alternative: Inline Call

You can also call getOrders() directly in a @set directive without a backend script block:
@set(orders = getOrders('newest', 5))

@foreach(order in orders)
  <p>#{{ order.order_number }} — {{ order.created_at | date:'dd MMM yyyy' }}</p>
@endforeach

Parameters

ParameterTypeDefaultDescription
sortBystring'newest'Sort order: 'newest' or 'oldest'
limitnumber50Maximum number of orders to return (max 1000)

Order Object Structure

Each order returned by getOrders() contains:
{
  order_number: "EF-12345",        // Public order ID
  created_at: "2026-03-15T...",    // ISO date string
  currency: "USD",                 // Order currency code

  // Billing address
  billing_address: "123 Main St",
  billing_city: "New York",
  billing_state: "NY",
  billing_zip: "10001",
  billing_country: "US",

  // Shipping address
  shipping_address: "123 Main St",
  shipping_address2: "",
  shipping_city: "New York",
  shipping_state: "NY",
  shipping_zip: "10001",
  shipping_country: "US",

  // Customer info
  customer_name: "John Doe",
  customer_email: "john@example.com",

  // Products array
  products: [
    {
      name: "Premium Course",
      image_url: "https://...",
      price: 97.00,
      quantity: 1,
      currency_code: "USD",
      is_bonus: false
    }
  ],

  // Tracking array (if fulfilled)
  tracking: [
    {
      tracking_number: "9400111899223456789012",
      tracking_url: "https://t.17track.net/en#nums=...",
      carrier: "USPS"
    }
  ]
}

Displaying Tracking Information

If your orders have physical shipments, tracking information is automatically extracted from fulfillment data. The system checks multiple sources for tracking numbers:
  1. Direct conversion fields (tracking_number, tracking_url)
  2. Fulfillment provider response data
  3. Fulfillment order data
Carriers are auto-detected from tracking number patterns (USPS, FedEx, UPS, DHL, UniUni). If no tracking URL is provided, a universal tracking link via 17track.net is generated. order.tracking is always an array. When the order has not yet been fulfilled it is empty ([]). Use order.shipping_address as the signal that the order contains a physical product — if there is a shipping address but no tracking yet, show a “being processed” message.

Example: Physical order with processing/tracking states

@set(orders = getOrders('newest', 5))

@foreach(order in orders)
<div class="order">
  <h3>Order #{{ order.order_number }}</h3>
  <p>{{ order.created_at | date:'dd MMM yyyy' }}</p>

  @if(order.shipping_address)
  <div class="shipping-address">
    <h4>Ships to</h4>
    <p>{{ order.shipping_address }}</p>
    <p>{{ order.shipping_city }}, {{ order.shipping_state }} {{ order.shipping_zip }}</p>
    <p>{{ order.shipping_country }}</p>
  </div>

  @if(order.tracking.length gt 0)
  <div class="tracking-info">
    <h4>Shipment Tracking</h4>
    @foreach(t in order.tracking)
    <div class="tracking-row">
      <span>{{ t.carrier }}</span>
      <a href="{{ t.tracking_url }}" target="_blank">{{ t.tracking_number }}</a>
    </div>
    @endforeach
  </div>
  @else
  <div class="tracking-pending">
    <p>Your order is being processed. Tracking information will appear here once your order ships.</p>
  </div>
  @endif

  @endif
</div>
@endforeach
The key pattern:
  • order.shipping_address is present → physical product → show the shipping address block.
  • Inside that block, order.tracking.length gt 0 → shipment is on the way → show carrier + tracking link.
  • Otherwise → show “Your order is being processed.”
Tracking numbers are auto-linked to 17track.net when no carrier URL is provided. The carrier is auto-detected from the number pattern (USPS, UPS, FedEx, DHL, UniUni). You do not need to map carriers yourself.

Thank You Pages

Thank-you pages are a natural place to show order details. Since the customer is auto-authenticated from checkout, order data is available immediately.

Example: Thank You Page with Order Summary

@set(orders = getOrders('newest', 1))

<h2>Order Confirmed!</h2>
<p>Thank you for your purchase.</p>

@if(orders.length gt 0)
  @foreach(order in orders)
  <div class="order-summary">
    <p>Order #{{ order.order_number }}</p>
    <p>Date: {{ order.created_at | date:'dd, MMM yyyy' }}</p>

    @foreach(product in order.products)
    <div class="product">
      <span>{{ product.name }}</span>
      <span>{{ product.price | formatPrice:product.currency_code }}</span>
    </div>
    @endforeach
  </div>
  @endforeach
@else
  <div class="processing">
    <p>Your order is still being processed. This page will refresh automatically.</p>
  </div>
@endif

<a href="/members">Access Member Area</a>
If the order hasn’t been indexed yet when the thank-you page loads, the getOrders() call may return empty. Add a JavaScript auto-refresh timer so the page retries after a few seconds — the order typically appears within 5–10 seconds.

Customer Data Outside of Orders

You can also display customer information directly using the customer template object (populated from the session):
<p>Welcome back, {{ customer.name|default:"Member" }}!</p>
<p>Email: {{ customer.email }}</p>
The customer object includes: name, email, first_name, last_name, phone, order_id, order_ids, and full billing/shipping address fields. It is automatically available in every backend script and template — no function call needed.

Order Grouping

Orders are grouped intelligently — multiple conversions from the same purchase session (e.g., a main product and an upsell bought in the same checkout flow) are combined into a single order. The grouping logic uses:
  • Session ID matching — Conversions from the same browser session
  • Time proximity — Conversions within 6 hours of each other
This means an upsell purchased immediately after the main product shows under the same order, not as a separate entry.

Order Tag Reference

Full reference for the <order> HTML tag and all placeholders

Backend Scripts

Learn about backend scripts and available functions

Template Engine Syntax

Filters, conditionals, and loops for displaying data

Thank You Pages

Best practices for post-purchase confirmation pages