Display order history, products, tracking, and shipping information in your members area
ElasticFunnels provides two ways to display order information on your pages: the <order> HTML tag (for the visual builder) and backend functions like getOrders() / getOrder() / getSessionOrders() / getPurchasedProducts() for code-based pages. Both retrieve data from the customer’s purchase history.
Member-area “library” pages — purchased products with their bonuses + downloads
Backend scripts / .ef pages
For a member-area page that needs each purchased product with its included bonuses and download links, prefer getPurchasedProducts() over manually joining getOrders() + getAllProducts() + getBonusProducts() on the client. It returns a flat list with same-order bonuses already attached and a pre-rolled-up downloads[] array (each entry tagged with kind). See the data-functions reference and the “My Library” pattern for examples.
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.
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.
When you already know which order to show, use getOrder(code) instead of loading the full order list and searching manually. This is ideal for pages like /members-order?order=EF-12345.getOrder() uses the same customer/session scope as getOrders(), so it only returns orders that belong to the currently logged-in customer for that brand.
Public order ID, internal order ID, or conversion code to match
For an order detail page, prefer getOrder(request.query.order) over getOrders() plus a manual loop/filter. It is shorter, clearer, and communicates intent directly.
Use getOrderFulfillment(code) on an order detail page to show 3PL fulfillment status and timestamps. Responses are allowlisted (no raw provider payloads).Use getOrderFulfillments() with no arguments to list every tracking row across all of the customer’s orders—each row includes order_number so you can link to /members-order?order=….For a single order, order.tracking from getOrder / getOrders is often enough for carrier links. The fulfillment helpers add lifecycle status (getOrderFulfillment) and a cross-order shipment list (getOrderFulfillments).
If your orders have physical shipments, tracking information is automatically extracted from fulfillment data. The system checks multiple sources for tracking numbers:
Direct conversion fields (tracking_number, tracking_url)
Fulfillment provider response data
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.
getSessionOrders() returns only the orders that were placed during the current browser session. Unlike getOrders(), which returns the full purchase history for a customer, getSessionOrders() is scoped to the active checkout session — making it the right choice for thank-you pages where you only want to show what was just bought.By default it returns all orders from the current session. Pass an optional limit to cap the count.
Prefer getSessionOrders() over getOrders('newest', 1) on thank-you pages. A customer with an existing purchase history could see a previous order with getOrders if the new conversion hasn’t been indexed yet. getSessionOrders() is scoped to the current session so it only shows what was just purchased.
Thank-you pages are a natural place to show order details. Since the customer is auto-authenticated from checkout, order data is available immediately.Use getSessionOrders() on thank-you pages so that only the orders from the current checkout session are shown — not the customer’s full history.
@set(orders = getSessionOrders())<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, getSessionOrders() 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.
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.
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.