Profit as the conversion value

Last updated ·

Why bid on profit

Revenue is a poor optimisation target when your margins vary. A campaign selling high-margin products at a return on ad spend of 4 is worth more than one selling low-margin products at 6, and a bidding strategy working from revenue cannot tell the two apart. It will spend your budget on the second.

GTM Kit Premium works out each order’s gross profit on your server and sends it with the order, so your bidding can optimise on what you actually earned.

Where the number comes from

Profit starts from your WooCommerce cost prices, which WooCommerce has carried in core since 10.3, and subtracts the costs you configure. Nothing is estimated for you.

The settings live in the GTM Kit settings under WooCommerce, in the server-side webhooks section. Switch on Profit as the conversion value, then fill in your cost model:

  • Default margin for products without a cost price (%). Used for any product with no cost price in WooCommerce. Left at 0, those products contribute no profit at all, so the figure understates rather than invents.
  • Payment fee, percentage of order value (%) and Payment fee, fixed amount per order. Most gateways charge both.
  • What shipping costs you, with three choices: do not subtract a shipping cost, a share of the shipping you charged, or a flat amount per order. The second and third reveal a field for the percentage or the amount.
  • Packaging and handling per order.

Every field starts at zero, and that is deliberate. GTM Kit does not guess your payment rates or your shipping costs, because a plausible guess produces a plausible profit figure that is wrong and nothing about it looks wrong. An order with no cost basis behind it carries no profit at all rather than a number assembled from defaults.

How much of your catalogue has a cost price

The setting’s description shows the share of your catalogue that has a cost price. An incomplete profit figure is a visible problem rather than a silent one. If that number is low, fix your cost prices before you point bidding at the result.

The figure is stamped when the order is placed

Profit is worked out once, at order creation, and stored on the order. A resent or retried event reports the same figure as the original. Changing your cost model later does not rewrite orders that already exist, which is what you want: a conversion value that moves after the fact is worse than one that is slightly wrong.

Where the number goes

Profit rides the server-side event as two flat fields, gross_profit and margin_pct, alongside the order’s other data.

It stays out of your page source by default. There is a setting, Also send profit from the browser, that adds profit and margin to the browser purchase event as well. Anyone who views the page source of an order confirmation can then read your margins, competitors included. Leave it off unless you have a specific reason and have accepted that trade.

Make your container use it

Sending the field changes nothing on its own. Your server container has to be told what to do with it, and until you do that, your bidding behaves exactly as it did before.

For reporting in GA4: create a custom metric in your GA4 property for profit, then in your server container map the incoming gross_profit field to that metric as an event parameter on your GA4 tag.

For bidding in Google Ads: in your server container, on the Google Ads conversion tag, set the conversion value from the event data field gross_profit instead of the order value.

Do not switch your primary conversion action over on day one. Set up profit as a secondary conversion action and let it run alongside your revenue conversions for at least two weeks. Then compare, promote it to primary, and re-baseline your targets. A return on ad spend of 5 is roughly a profit-on-ad-spend of 1.5. If you promote profit without lowering your target, your campaigns will read as a sudden collapse and the bidding will throttle spend accordingly.

Reading an order’s profit from your own code

A read-only REST endpoint returns the stored figure, for headless storefronts and custom reporting that need the same number the server-side event reports:

GET /wp-json/gtmkit/v1/order-profit/<order id>

It returns the order id, the currency, gross_profit, margin_pct and the catalogue cost coverage percentage. It requires the manage_woocommerce capability, which the gtmkit_profit_rest_capability filter can change. It never writes: an order that has no stored profit returns a 404 rather than having a figure computed and frozen for it on the spot.

When an order has no profit

Three cases, and all three are silence rather than a wrong number: profit tracking was off when the order was placed, no product in the order had a cost price and your default margin is 0, or the order predates the feature. In each case the fields are simply absent from the event.

Related articles

← Previous

Previous article

Next →

Next article