This guide refers to the Shopware extension Google Tag Manager / GA4 / Server-Side Tracking by Bui Hinsche GmbH. The goal is to create alogin event along with relevant customer data to the Google Tag Manager data layer.

Define login route

  • Administration → Settings → Google Tag Manager → Routes & DataLayer
  • Create new route:frontend.account.home.page (Page after successful login)

Deposit DataLayer payload

These variables should be configured in the Login module, as well as for all other page types / modules that are not the Finish Page.

  • Off-Canvas Cart
  • Cart Page
  • Confirm Page
  • Add To Cart
  • Remove From Cart
  • Checkout Register Page
  • Listing (ajax)
  • Product Detail
  • Home Page
  • Login
{
"event": "GA4_EVENTNAME",
"user_data": {
  "email": {{ context.customer.email }}
},
"user_roperties": {
  "customer_group": {{ context.currentCustomerGroup.name }},
},
"user": {
  "id": {{ context.customer.id }},
  "number": {{ context.customer.customerNumber }},
  "group": {{ context.currentCustomerGroup.name }},
  "token": {{ context.token }},
  "email": {{ context.customer.email }}
  }  
}

Of course, these variables only work for logged-in customers. This data is not available for customers who are not logged in.

However, anyone looking for a session-wide identity in the data layer can create it using the shopping cart token. This token is accessible via the variable{{ context.token }} reachable.

{
"user": {
  "token": "{{ context.token }}
  }
}

DataLayer Payload for the Purchase Event

The data from the order can be used in the finish event. This also works reliably for guests.

{
"event": "purchase",
  "ecommerce": {
  "transaction_id": "{{ page.order.orderNumber }}",
  "value": "{{ page.order.price.netPrice }}",
  "currency": "{{ context.currency.isoCode }}"
  },
"user_data": {
  "email": {{ page.order.orderCustomer.email }}
},
"user_roperties": {
  "customer_group": {{ context.currentCustomerGroup.name }},
},
"user": {
  "id": "{{ context.customer.id }}",
  "number": "{{ page.order.orderCustomer.customerNumber }}",
  "group": "{{ context.currentCustomerGroup.name }}",
  "token": "{{ context.token }}"
  "email_sha256": "{{ page.order.orderCustomer.email }}",
  }
}

What is worth highlighting in the code is the change of the ecommerce.value = {{page.order.positionPrice}} recorded at the net value of the order.

If you want to use the net waiting value , you have to use a little more code:

{# Net subtotal only item #}
{%set itemsNetSubtotal = 0%}
{% for item in page.order.lineItems %}
  {% set itemTax = 0 %}
  {% for t in item.price.calculatedTaxes %}
  {% set itemTax = itemTax + t.tax %}
  {% endfor %}
  {% set itemNet = item.price.totalPrice - itemTax %}
  {% set itemsNetSubtotal = itemsNetSubtotal + itemNet %}
{% endfor %}

{{ itemsNetSubtotal|number_format(2, '.', '') }}

With these small changes, you can significantly improve the identification of users in the online shop with the help of server-side tracking.

Bernhard prange webmeisterei

SEA-Experte: Bernhard Prange

Bernhard Prange ist Google Ads Freelancer und Tracking-Spezialist mit über 10 Jahren Erfahrung im Performance-Marketing. Sein Fokus liegt auf datengetriebenem Arbeiten: von Google Shopping über Conversion-Tracking bis hin zu serverseitigen Lösungen mit Matomo und BigQuery.

Als Ansprechpartner für Agenturen, E-Commerce-Unternehmen und B2B-Dienstleister verbindet er technisches Know-how mit strategischem Blick auf Marketing und Geschäftsmodelle.

Beiträge, die dich auch interessieren könnten…

  • Better data, better decisions: Data enrichment in Server-Side Tracking

    Lesen
  • Google Ads DemandGen: The Complete Practical Guide

    Lesen
  • Claude MCP: 30+ Integrations for WordPress, Google Ads & SEO

    Lesen
  • Track User Reading Behavior with Google Tag Manager

    Lesen