The server-side purchase webhook

Last updated ·

How the purchase event reaches your server container

GTM Kit Premium can send the purchase event to your server container directly from your shop, without the customer’s browser being involved. That matters because the browser is the unreliable half of the journey: a payment provider can fail to return the customer to your shop, a container can be blocked, a script error earlier on the page can stop everything below it. When the browser event never arrives, the sale is never recorded.

The server-side event is not a replacement for the browser event. It is a second path to the same destination, and you choose how the two relate.

Choosing when the server sends

The purchase webhook trigger has three options.

On order creation. The event is sent as soon as the order exists, before payment is confirmed. Use this when you want the conversion recorded at the earliest possible moment and you are comfortable counting orders that may later fail payment.

On payment complete. The event is sent when the order reaches a paid status. This is the common choice: it records real, paid conversions, and it is the default for most shops.

Only when the browser did not confirm. The shop waits, checks whether the browser reported that the purchase reached Google Tag Manager, and sends the server-side event only if it did not. On a healthy checkout your shop sends nothing from the server. This is a specialist option for measuring how many sales the server-side path rescues. It is not the recommended default, and the two options above stay correct for most shops.

What the third option is actually for

With either of the first two options, both paths send, and your container decides what to do with two copies. That is the fail-safe arrangement, and nothing is ever lost. What it cannot tell you is which path delivered a given conversion, and whether it would have been lost without the webhook. A container that keeps whichever copy arrives first cannot distinguish a rescued sale from one where the server simply won the race, so any recovery rate you calculate from it is not a real number.

With the third option, everything the server sends is a conversion the browser did not deliver. That count is readable under WooCommerce, Status, Logs.

The wait

The third option adds a “Wait before deciding (minutes)” field, five minutes by default and adjustable between one and sixty. It gives the browser time to report before the shop decides. The field is blank until you save a value, and blank means five.

Before you switch this on

Four things change the behaviour of the third option, and all four are quiet rather than loud.

Remove any custom snippet that already does this. If you are running a custom snippet or must-use plugin that implements browser-confirmed sending, remove it before selecting this option. The two do not compose: the snippet detaches the plugin’s own sending step and does not recognise the new setting, so neither side sends the purchase and nothing is recorded at all.

Do not combine it with disabling the frontend purchase event. If the browser never sends the purchase, nothing ever confirms, so every order waits out the timer and then sends. You get the delay without the benefit.

Check your caching plugin’s JavaScript handling. A plugin that delays JavaScript until the visitor interacts with the page will hold the confirmation script long enough that many orders never confirm. The option then behaves as an always-send, which is safe but not what you selected it for.

Turn on WooCommerce logging. The recovery count is written to the WooCommerce log. Without logging enabled, the number this option exists to produce is not recorded anywhere.

What the confirmation proves, and what it does not

The confirmation tells your shop that Google Tag Manager loaded, was processing the data layer, and had the purchase event available to it. It does not prove that a specific purchase tag inside your container fired. A tag that is misconfigured or paused is a container problem, and this option will read it as a successful browser delivery.

Attribution on a recovered conversion

A conversion the webhook recovers can keep the traffic source of the visit it belongs to, rather than arriving with no session attached and showing its source and medium as “(not set)”.

This used to fail in a specific and counterintuitive way. When a shop runs its tagging through its own subdomain, the analytics session and visitor cookies are commonly set so that JavaScript cannot read them at all, so the capture running in the visitor’s browser had nothing to record. The better your server-side setup, the more reliably attribution was lost. Those identifiers are now also read from the order request itself, where the cookies are visible whatever they are set to. Anything the browser did capture is kept as it was.

Your server container needs the updated template. The session details now travel in the payload, but your container has to be told to read them. Re-import the template from the Template Assistant once after updating. Until you do, the data is arriving and being ignored.

One honest limit. This works when the visit itself reached Google Analytics and only the purchase went missing, which is the common case after a payment provider fails to return the customer. A visitor whose browser never reached Google Analytics at all has no session to join, and those conversions still arrive without a source.

Related articles

← Previous

Previous article

Next →

Next article