Setting up a revenue goal in Kameleoon is straightforward, but it does require a few careful steps to make sure everything works as expected. Every website has its own structure, purchase flow, tracking setup, and edge cases—which means there’s no one-size-fits-all solution. Without proper configuration, you risk missing key data points, double-counting transactions, or misinterpreting performance.
To help you avoid these pitfalls and ensure your revenue tracking is both accurate and meaningful, we’ve compiled a set of practical guidelines. These recommendations are designed to cover the most common challenges our clients encounter, while offering flexible solutions you can adapt to your specific setup.
Implementation method
Using a Tag Manager (e.g., Google Tag Manager)
Our first recommendation is to implement the kameleoonQueue which ensures that conversion events are triggered synchronously with your analytics platform, maintaining data consistency across tools and improving the site’s performance. For a detailed implementation guide in Google Tag Manager (GTM), refer to our step-by-step GTM guide and the configuration steps below to correctly set up the revenue goal.
Using the Global Custom Script
If the kameleoonQueue is not suitable for your tech stack, follow the steps below to confidently configure your revenue goal using the Global Custom Script in the Kameleoon Back Office.
Using the Kameleoon Data API for offline goal conversions
For scenarios where conversions occur offline or outside the typical online flow where Kameleoon is installed, you can use the Kameleoon Data API to process offline goal conversions. This method allows you to send conversion data programmatically and integrate those offline conversions into your experiments.
Configuration
Scope
Before setting up your revenue goal, check whether the transaction confirmation always occurs on a single, consistent page. In some setups, especially those involving mobile apps, embedded checkouts, or third-party payment providers, the confirmation might appear in a web-view or on a separate domain. Make sure Kameleoon is properly installed on all relevant pages or views where the confirmation may appear. This ensures conversions are reliably tracked and no revenue data is missed. If a transaction may be completed across multiple URLs (e.g., due to variations in query parameters or different payment flows), ensure accurate tracking, by adding all relevant URLs in Kameleoon’s settings to be tracked. This avoids missing any conversions.
Transaction goal (Access to the confirmation page)
It is always a good idea to set a goal for accessing the confirmation page, without the revenue amount. This could help track missing conversions for the revenue goal, which are often caused by delays in loading the revenue amount on the page (whether in the DOM, dataLayer, or another similar object). For setting up the Transaction goal, you can choose between two types of goals:
- Access to a page: You simply need to set the URL in the goal’s configuration. Depending on the structure of the URL, you can use either “URL contains” or “Matches the regular expression” to account for variations of the URL (e.g., different paths or query parameters). Avoid using “Corresponds exactly to”, as the URL will likely include parameters that can vary.
Note: When using the “Access to a page” goal type, if visitors can reload the confirmation page without being redirected (e.g., to the homepage), the goal may be triggered again. In this case, it’s best to rely on the “converted visits” metric rather than “all conversions” in the results page of your experiments to avoid overcounting.
- Custom goal: This type is useful to ensure the goal doesn’t convert again if the confirmation page is reloaded. You can implement it in the Global Custom Script and use a
sessionStorage
check to prevent duplicate conversions (see the example code below). This approach is recommended because the same code can also be used to trigger the revenue goal, improving performance by eliminating the need for a native “Access to a page” goal.
if ( document.location.href.includes("/confirmation/") && !window.sessionStorage.getItem("kameleoonGoalConverted") ) { // Set an item in sessionStorage to prevent a second conversion if the page is reloaded window.sessionStorage.setItem("kameleoonGoalConverted", "true"); // Convert the transaction goal, replace the ID below Kameleoon.API.Goals.processConversion(355733); } else if (!document.location.href.includes("confirmation")) { // Remove the item from sessionStorage to allow conversion for a new transaction window.sessionStorage.removeItem("kameleoonGoalConverted"); }
Revenue format
Ensure the revenue amount is properly formatted and validated before processing. This includes:
- Replacing commas (
,
) with periods (.
) for decimal consistency. - Removing any spaces (often present in amounts over 1 ,000).
- Stripping out currency symbols (such as
$
,€
,£
). - Converting the cleaned string into a numeric data type for accurate calculations.
See the example code below:
let revenue = parseFloat(revenue.replace(",", ".").replace(/[^0-9.]/g, "").replace(/\s+/g, ""));
Currencies
A website may support multiple currencies. Make sure you are comparing conversion values all expressed in the same currency to avoid misleading results or incorrect analyses. Verify that the currency used in your tracking and reporting is consistent across all conversions.
You can trigger a goal for each currency and/or use Kameleoon’s currency conversion web service. The endpoint is provided below – ensure that all arguments passed are valid when using it.
<https://customers.kameleoon.com/kameleoon/currencies/convert?inputCurr=${inputCurr}&outputCurr=${outputCurr}&amount=${revenue}>;
Be careful: Never convert the same goal using amounts in different currencies. You’ll need to either create a separate goal for each currency, or unify these by setting up a global goal using the web service endpoint mentioned above. This service will convert all amounts into a single currency of your choice.
See the complete code example at the end of this article for a detailed implementation of the currency conversion web service.
Order ID
It’s recommended to add a Custom Data (CD) to store the order ID (order number) and use it as metadata for the revenue goal. This will link each conversion to the orderID and help you accurately match transactions with your analytics tool and investigate any potential data discrepancies.
To configure the Custom Data, refer to the screenshot below. Adjust the format depending on whether the order ID on your site is a number or a string.

Next, associate the “OrderID” Custom Data with your revenue goal. See the screenshot below for reference.

Finally, see the complete example code below, which sets the Custom Data value.
Complete Example
Now that you’ve reviewed each key element—scope, transaction logic, revenue format, currency handling, and order ID tracking—you’re ready to bring everything together.
Below is a complete example of how to implement the revenue goal using the Global Custom Script in Kameleoon.
// Amount conversion using Kameleoon's currency conversion web service const convertCurrency = async (revenue, inputCurr, outputCurr) => { if (revenue == 0) return 0; const response = await fetch( `https://customers.kameleoon.com/kameleoon/currencies/convert?inputCurr=${inputCurr}&outputCurr=${outputCurr}&amount=${revenue}`, { method: 'GET', headers: { 'Content-Type': 'text/plain', }, } ); return response.json(); }; // Logic to: // - Convert the transaction goal // - Convert a goal for each currency // - Convert the global revenue goal // - Set the orderID custom data // repalce all goal IDs in the code if (document.location.href.includes("/confirmation/") && !window.sessionStorage.getItem("kameleoonGoalConverted")) { Kameleoon.API.Goals.processConversion(355733); // Transaction goal sessionStorage.setItem("kameleoonGoalConverted", "true"); let revenueLayer; Kameleoon.API.Core.runWhenConditionTrue(() => { revenueLayer = window.dataLayer?.find(layer => layer.ecommerce?.purchase?.actionField?.revenue); return revenueLayer; }, () => { let revenue = parseFloat(revenueLayer.ecommerce.purchase.actionField.revenue); const inputCurr = revenueLayer.ecommerce.purchase.actionField.inputCurrency; const orderID = revenueLayer.ecommerce.purchase.actionField.orderID; if (!isNaN(revenue)) { revenue = revenue.toString().replace(",", ".").replace(/[^0-9.]/g, "").replace(/\s+/g, ""); // Currency-specific revenue goals switch (inputCurr) { case 'GBP': Kameleoon.API.Goals.processConversion(355641, revenue); break; case 'USD': Kameleoon.API.Goals.processConversion(355643, revenue); break; case 'EUR': Kameleoon.API.Goals.processConversion(355642, revenue); break; default: Kameleoon.API.Goals.processConversion(355649); // Other currencies (no revenue passed) } // Global revenue goal in output currency (you can use ISO 4217 codes for each country) const outputCurr = "USD"; convertCurrency(revenue, inputCurr, outputCurr).then((convertedRevenue) => { // The custom data must be set before the goal is converted Kameleoon.API.Data.setCustomData("orderID", orderID); Kameleoon.API.Goals.processConversion(353518, convertedRevenue); }).catch((error) => { // Create a Custom Data to store potential errors for debugging Kameleoon.API.Data.setCustomData("[KAM] - currency webservice error", `error: ${error.toString()}; revenue: ${revenue}; inputCurr ${inputCurr}; outputCurr ${outputCurr}`); console.error("Error in currency conversion:", error); }); } }); } else if (!document.location.href.includes("/confirmation/")) { sessionStorage.removeItem("kameleoonGoalConverted"); }
Below is a screenshot of the dataLayer structure on the confirmation page for reference.

Setting up a reliable revenue goal in Kameleoon requires careful alignment with your site’s structure, dataLayer setup, and currency formats. By following the guidelines above, whether through a tag manager or the Global Custom Script, you can ensure accurate tracking, reduce discrepancies with your analytics tools, and gain more meaningful insights from your experiments. Don’t forget to test thoroughly and validate your implementation to maintain data integrity.