Integrate a Third-Party Conversion Tag
Report the Pixel Manager's purchase event to an external tag that the Pixel Manager does not support natively, such as an affiliate network, a partner platform or an in-house tracker.
The worked example below uses Adtraction, but the pattern is the same for every network. Only the tag's own script URL and parameter names change.
The pattern
Three rules carry the whole integration. Everything else is the network's own API.
- Register the purchase listener synchronously. The purchase event fires once per order and is then locked out permanently, a page reload included. A listener that registers after any wait, such as loading the network's script, can miss the order and never get a second chance.
- Load the external script inside the handler. Not before it. The script is only needed once there is a conversion to report.
- Check consent inside the handler. The visitor's consent state is available to the Command Queue, but reading it inside the handler keeps the decision next to the conversion it governs, which is also correct when consent is granted after the page has loaded.
If your integration reports clicks or page views but never a sale, this is almost always the cause. See Missing Purchase Conversions.
The recipe below uses pmw.bus, which is available from version 1.65.0, and reads the consent state from the event payload, which works on every version from 1.52.0.
On versions older than 1.65.0, replace pmw.bus.on('pmw:event:purchase', function (payload) { … }) with jQuery(document).on('pmw:event:purchase', function (event, payload) { … }). Everything else stays the same.
Do not read pmw.consent at the top level of a queued command on version 1.64.0 or older: the consent module had not loaded at that point, so the command failed silently and never registered its listener. Reading the consent state from the event payload, as this recipe does, avoids the problem on every version.
The code
Add this to your child theme's functions.php or to a small custom plugin.
add_action('wp_head', function () {
?>
<script>
window._pmwq = window._pmwq || [];
window._pmwq.push(function () {
const programId = 1234567890; // your network's program/account ID
const transactionTypeId = 9876543210; // your network's transaction type ID
// Register immediately. Never behind an await or a .then().
pmw.bus.on('pmw:event:purchase', function (payload) {
// The consent state travels with the event.
if (!payload.context.consent.categories.marketing) return;
const order = pmwDataLayer.order;
if (!order) return;
pmw.loadScriptAndCacheIt(
'https://gtm.adt313.net/jsTag?ap=' + programId
).then(function () {
if (typeof ADT === 'undefined' || !ADT.Tag) {
console.error('[Adtraction] Script loaded but ADT.Tag is unavailable.');
return;
}
ADT.Tag.t = 3; // 3 = sale
ADT.Tag.tp = transactionTypeId;
ADT.Tag.ti = order.number; // order number
ADT.Tag.am = order.value.marketing; // conversion value
ADT.Tag.c = order.currency;
ADT.Tag.xd = order.billing_email_hashed; // sha256 of the email
ADT.Tag.cpn = order.coupon || '';
ADT.Tag.doEvent();
});
});
});
</script>
<?php
});
The order data
The purchase payload and pmwDataLayer.order give you everything a conversion tag normally asks for:
| Field | Contents |
|---|---|
order.number | The order number as the customer sees it, which is what belongs in the network's transaction ID |
order.id | The internal WooCommerce order ID |
order.value.marketing | The conversion value, following the store's configured marketing value logic |
order.currency | The order's currency code |
order.coupon | The coupon codes used, comma-separated, empty when none were used |
order.billing_email_hashed | The billing email, lowercased, trimmed and SHA-256 hashed |
payload.context.consent.categories | The visitor's consent state at the moment of the event |
Use order.value.marketing rather than the order total, so the value you report to the network follows the same logic as the value reported to every other platform.
The field names above are the Pixel Manager's. The ADT.Tag.* names, the transaction type IDs and the program IDs belong to the network and are documented by them. Verify them against your network's own documentation and your account.
Testing it
Place one test order and, on the order confirmation page, check the following in the browser console.
-
The page is recognized as a confirmation page and the order is present:
pmwDataLayer.shop.page_type; // "order_received_page"pmwDataLayer.order; // the order object -
Your handler runs. Add a
console.logas the first line inside the purchase handler and confirm it appears. -
No queued command failed. Search the console for
Pixel Manager: Error executing queued command. If it is there, your command threw and everything after the failing line was skipped. -
The conversion actually leaves the browser. In the Network tab, confirm the request to the network's endpoint after your handler ran.
The Console Logger shows the Pixel Manager's own event flow alongside your output. Enable it with ?pmwloggeron.
Because a purchase is only ever tracked once per order, reloading the confirmation page will not fire the event again. Add ?nodedupe to the confirmation URL to test repeatedly with the same order.
Related Documentation
- Command Queue - When queued commands run and what is available to them
- JavaScript Events - The full event reference
- Consent API - Driving and reading the consent state