Server-Side GTM Implementation for OpenCart with GA4 and Google Ads

Standard

Server-Side Google Tag Manager (ssGTM) is the modern foundation for privacy-safe and robust tracking in OpenCart. By shifting tracking logic from browsers to a secure server, you gain:

  • Improved conversion accuracy
  • Protection against ad blockers
  • Compliance with consent regulations
  • Seamless integration with GA4 and Google Ads (including Enhanced Conversions)


🎯 Goal

Track key eCommerce events in OpenCart (like purchase, add_to_cart, view_item) through Web GTM → ssGTM → GA4 & Google Ads, with deduplication and first-party data.


🧰 Prerequisites

Requirement Notes
OpenCart 3.x/4.x FTP and theme access required
GTM Web Container Installed on all frontend pages
GTM Server Container Hosted with custom subdomain (e.g., gtm.yoursite.com)
GA4 & Google Ads Measurement IDs and Conversion Labels ready
Consent System (optional) For GDPR compliance


🧱 Step 1: Setup Web GTM Container in OpenCart

Edit catalog/view/theme/*/template/common/header.twig:

<!-- Google Tag Manager -->
<script>
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXXX');
</script>
<!-- End GTM -->

Repeat similar for <noscript> tag inside <body>.

✅ Web GTM is now active on your OpenCart frontend.


🔐 Step 2: Configure Server GTM on Custom Subdomain

  1. Set up a subdomain like: gtm.yoursite.com
  2. Point DNS to GTM server IP or use App Engine/Cloud Run
  3. Deploy GTM Server Container
  4. Enable GA4 and Google Ads built-in clients
  5. Update Web GTM → GA4 Config Tag to point to server container:

transport_url: 'https://gtm.yoursite.com'


🛒 Step 3: Push DataLayer Events in OpenCart

Example: Purchase Event (in success.php)

$order_id = $this->session->data['order_id'];
$order_info = $this->model_checkout_order->getOrder($order_id);
$products = $this->model_checkout_order->getOrderProducts($order_id);

$email = strtolower(trim($order_info['email']));
$phone = preg_replace('/\D/', '', $order_info['telephone']);

$items = [];
foreach ($products as $product) {
$items[] = [
'item_id' => $product['model'],
'item_name' => $product['name'],
'price' => $product['price'],
'quantity' => $product['quantity'],
];
}

$data['ss_purchase'] = json_encode([
'event' => 'purchase',
'transaction_id' => $order_id,
'currency' => $order_info['currency_code'],
'value' => $order_info['total'],
'email' => hash('sha256', $email),
'phone' => hash('sha256', $phone),
'items' => $items,
'event_id' => uniqid('ss_', true)
]);

In success.twig:

<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({{ ss_purchase|raw }});
</script>


🧩 Step 4: GA4 Configuration in Web GTM (With Server Transport)

Tag Type: GA4 Configuration
Fields to Set:

Field Value
Measurement ID G-XXXXXXXXXX
transport_url https://gtm.yoursite.com

✅ This tells GA4 events to route through your server.


⚙️ Step 5: GA4 Event Tag (e.g., purchase)

Event Name: purchase
Event Parameters:

  • transaction_id: {{DL - transaction_id}}
  • value: {{DL - value}}
  • currency: {{DL - currency}}
  • items: {{DL - items}}

✅ Trigger on Custom Event = purchase


🔁 Step 6: Google Ads Conversion Tag (Client & Server)

Web GTM Google Ads Tag

  • Conversion ID: AW-XXXXXXXXX
  • Conversion Label: ABCD1234XYZ
  • Include event_id: {{DL - event_id}}

✅ Use same event_id for deduplication.


🛰️ Step 7: Forward Events to Server-Side GTM

In Web GTM, use a tag (or modify GA4 tag) to send event_id, email, phone via headers or body using:

fetch('https://gtm.yoursite.com/event', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event_name: 'purchase',
email: '{{DL - email}}',
phone: '{{DL - phone}}',
event_id: '{{DL - event_id}}',
value: '{{DL - value}}',
currency: '{{DL - currency}}',
transaction_id: '{{DL - transaction_id}}',
items: {{DL - items}},
gclid: '{{url - gclid}}'
})
});

✅ Forwarded to your Server GTM container.


📦 Step 8: Setup GA4 and Google Ads Tags in Server GTM

GA4 Tag in ssGTM:

Field Value
Measurement ID G-XXXXXXXXXX
Event Name purchase
Event ID {{event_id}}
Parameters items, value, currency, etc.

Google Ads Tag in ssGTM:

Field Value
Conversion ID Your Google Ads ID
Conversion Label Label from Ads Manager
Email & Phone {{email}}, {{phone}} (hashed)
Event ID Same as client side
GCLID If available


📊 Step 9: Verify & Test

Tool Purpose
GTM Preview Mode Validate dataLayer & event_id
Server GTM Preview Confirm requests arrive
GA4 DebugView Real-time confirmation
Google Ads → Conversions → Diagnostics Check for deduplication success


🔁 Deduplication Strategy

Ensure the same event_id is used:

  • In Web Pixel (client-side)
  • In Server CAPI (server-side)

→ Meta, GA4, and Google Ads will automatically deduplicate.


🔐 Consent Strategy (Optional but Recommended)

Add ad_storage, analytics_storage consent flags in dataLayer or server headers to comply with GDPR/CCPA.


Leave a Reply

Your email address will not be published. Required fields are marked *