Tracking OpenCart checkout events accurately is critical for ad attribution, conversion optimization, and remarketing. By routing checkout data server-side using Server-Side Google Tag Manager (ssGTM), you gain resilient, ad-block-proof, and privacy-compliant tracking for platforms like GA4, Google Ads, Meta, and others.
โ Why Send Checkout Events Server-Side?
Benefit | Description |
---|---|
Ad Blocker Resilience | Bypasses client-side tag blockers |
Accurate Attribution | Ensures gclid/fbp match and timestamp |
Privacy Control | Filters/cleans data before reaching vendors |
Enhanced Matching | Passes hashed emails and first-party identifiers |
Conversion Deduplication | Server-side logic avoids double firing |
๐งฐ Requirements
- OpenCart store (v3.x or v4.x)
- Server-Side GTM container deployed (e.g. via Stape or GCP)
- Web GTM container already installed
- GA4 and Google Ads accounts with conversion actions configured
๐ Step-by-Step Implementation
๐น Step 1: Capture Checkout Event in OpenCart (PHP)
Edit: catalog/controller/checkout/success.php
After successful order creation, extract transaction data:
$order_id = $this->session->data['order_id'];
$order_info = $this->model_checkout_order->getOrder($order_id);
$products = $this->model_checkout_order->getOrderProducts($order_id);
$items = [];
foreach ($products as $product) {
$items[] = [
'item_id' => $product['model'],
'item_name' => $product['name'],
'price' => $product['price'],
'quantity' => $product['quantity']
];
}
$checkout_event = [
'event' => 'purchase',
'ecommerce' => [
'transaction_id' => $order_info['order_id'],
'value' => $order_info['total'],
'currency' => $order_info['currency_code'],
'items' => $items
],
'user_data' => [
'email' => $order_info['email'],
'phone' => $order_info['telephone']
]
];
Then pass to Twig for frontend use:
$data['gtm_purchase'] = json_encode($checkout_event);
๐น Step 2: Push Checkout Event to Data Layer (Client Side)
In success.twig
:
{% if gtm_purchase %}
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({{ gtm_purchase|raw }});
</script>
{% endif %}
๐น Step 3: Send Checkout Event to Server GTM (via Web GTM)
In Web GTM, create:
GA4 Purchase Event Tag:
- Event Name:
purchase
- Event Parameters:
transaction_id
,value
,currency
,items
- Under Fields to Set, add:
Field Name | Value |
---|---|
transport_url | https://gtm.yoursite.com |
โ This sends event to your Server GTM endpoint.
๐น Step 4: Server GTM โ Create GA4 Tag
In Server GTM Container:
- Tag Type: Google Analytics: GA4
- Trigger: Event Name equals
purchase
- Parameters: Map from
Event Data
:transaction_id
,value
,currency
,items
This delivers the event to GA4 via measurement protocol.
๐น Step 5: Server GTM โ Create Google Ads Conversion Tag
In Server GTM:
- Tag Type: Google Ads Conversion
- Conversion ID/Label: From Google Ads UI
- Event Parameters:
transaction_id
:{{Event Data โ ecommerce.transaction_id}}
value
:{{Event Data โ ecommerce.value}}
currency
:{{Event Data โ ecommerce.currency}}
- Trigger: When
Event Name = purchase
โ This ensures conversion is sent server-side, even if user blocks JS.
๐น Step 6: Optional โ Enhance with User Matching
In user_data
, include hashed values (email, phone) to improve match rates:
PHP Hashing:
$email_hashed = hash('sha256', strtolower(trim($order_info['email'])));
$phone_hashed = hash('sha256', preg_replace('/\D/', '', $order_info['telephone']));
Pass this in the user_data
block:
'user_data' => [
'email' => $email_hashed,
'phone' => $phone_hashed
]
Then access in Server GTM via Event Data variables for Meta CAPI or Google Ads Enhanced Conversions.
๐น Step 7: Deduplicate Conversions with event_id
Add a unique ID in PHP:
'event_id' => uniqid('oc_', true)
Send this to both:
- Client-side GA4 tag (in GTM)
- Server-side GA4/Google Ads tag (in Server GTM)
โ Prevents duplicate counting of the same conversion.
๐งช QA Checklist
Step | Validation |
---|---|
purchase event in success.twig |
โ |
GA4 tag uses transport_url |
โ |
Server GTM receives event | โ |
GA4 DebugView shows event | โ |
Google Ads receives conversion | โ |
Values (revenue, ID, currency) match | โ |
event_id deduplication logic present | โ |
๐ง Pro Tips
Tip | Benefit |
---|---|
Use first-party subdomain (e.g., gtm.yoursite.com ) |
Improves cookie lifespan |
Send user_id if available | Enables cross-device GA4 tracking |
Track refunds similarly | Close the loop for revenue reporting |
Log events server-side | Debug attribution gaps |
Enable consent mode for GDPR regions | Ensures legal compliance |
๐ฆ Summary Flow
[OpenCart Checkout Success]
โ
[PHP โ JS dataLayer โ Web GTM]
โ โ
[GA4 Client Tag] [Server Request to gtm.yoursite.com]
โ
[Server GTM Container]
โ โ
[GA4] [Google Ads]