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
- Set up a subdomain like:
gtm.yoursite.com
- Point DNS to GTM server IP or use App Engine/Cloud Run
- Deploy GTM Server Container
- Enable GA4 and Google Ads built-in clients
- 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.