we don’t have these keys as part of our Client side APIs fl_order_value, fl_product_name, fl_product_id unless you populate them yourself they’d always be empty.
You have two options:
Option 1: Track Purchases Manually (Recommended)
Track what’s being bought (in checkout and upsells) yourself and store its value on those variables, this might be the best options for most cases since it does not rely on undocumented behavior from our client side javascript library.
eg. in Checkout/upsells. track the sales this way:
<script>
// this event gets triggered on checkout purchase attempts (note, it triggers right before processing the purchase, must always check if the purchase went through before tracking).
funnelish.on('of_purchase', (products)=>{
/// store products into localstorage.
// or can calculate amount using something like: products.forEach(p=>{total += p.qty * p.product?.price }
})
// this event gets triggered on upsells/downsells purchase attempts.
funnelish.on('oto_yes', (productId)=>{
/// find the product by Id then get its price/qty.
/// PS. if productId=0 that means the upsells/downsell is using dynamic upsell CTA buttons, in which case you can find the selected product/variants using `funnelish.getSelectedProducts()`.
})
</script>
Must add the code above inside <body>.
The option above might be little tricky but it’s more flexible if you are trying to track something more than just order values.
Option 2: Rely on Facebook Pixel App indirectly
Second option is relying on on of the apps (Google Analytics or Facebook Pixel apps we provide)
Eg. If you are using Facebook Pixel app, then the app stores temporarily the checkout/upsell purchase values inside a localStorage item named funnelish_order_value.
This cookie is only populated after the purchase button is clicked. and then cleared once the next step/page of the funnel is loaded. So the value must be read once in <head> before it’s gone.
We can easily benefit from that by adding this code in <head> HTML of our Upsell/TYP steps:
<script>
let yourOrderTotal = localStorage.getItem("funnelish_order_value")
</script>
Might want to check the localStorage item funnelish_lastPageUrl in which we store the url of the page from which the order value was taken, this insures that you do not accidentally count failed purchases.
order_id we do not store that, but we do have ?activityId parameter which works the same and you can use to identify orders you can recover that by:
let activityId = new URL(window.location).searchParams.get("activityId");
Using this last method the new code becomes like this:
<script>
(function() {
function ls(key) {
return localStorage.getItem(key) || undefined;
}
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ ecommerce: null });
// We retrieve the activityId.
let activityId = new URL(window.location).searchParams.get("activityId");
// Safety check! making sure the purchase actually went through.
if (!activityId || funnelish.pageUrl === funnelish_lastPageUrl) return;
window.dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: activityId, // confirm exact key — may be fl_order_id
value: parseFloat(ls('funnelish_order_value')) || 0,
currency: ls('fnsh.core.customer.meta.wt:currency'),
items: [{
price: parseFloat(ls('funnelish_order_value')) || 0,
quantity: 1
}]
},
user_data: {
email: ls('fnsh.core.customer.email'),
first_name: ls('fnsh.core.customer.first_name'),
last_name: ls('fnsh.core.customer.last_name'),
phone: ls('fnsh.core.customer.phone'), // confirm if exists
// Shipping
address: {
street: ls('fnsh.core.customer.shipping_address'),
city: ls('fnsh.core.customer.shipping_city'),
zip: ls('fnsh.core.customer.shipping_zip'),
country: ls('fnsh.core.customer.shipping_country')
},
// Platform identifiers — already stored by Funnelish
fbp: ls('fnsh.core.customer.meta.wt:fbp'), // Meta _fbp
ttp: ls('fnsh.core.customer.meta.wt:ttp'), // TikTok _ttp
ip: ls('fnsh.core.customer.meta.wt:ip'),
ua: ls('fnsh.core.customer.meta.wt:ua'),
vid: ls('fnsh.core.customer.meta.wt:vid')
}
});
})();
</script>
PS. I’d recommend adjusting the code further to store product names and ids if needed.