Come integrare Google Analytics 4 in un e-commerce PHP (guida pratica)

Integra Google Analytics 4 nel tuo shop PHP: eventi e-commerce, purchase, e invii server-side con Measurement Protocol.

Questa guida mostra come implementare GA4 in uno shop PHP custom con gtag.js, tracciare gli eventi e-commerce principali e, opzionalmente, inviare eventi anche server-side via Measurement Protocol. È inclusa una sezione su GDPR/consenso.

1) Prerequisiti

  • Proprietà GA4 creata e Measurement ID (formato G-XXXXXXX).
  • (Opzionale) API Secret della proprietà GA4 per il Measurement Protocol.
  • Struttura del tuo shop: header.php, footer.php, pagina prodotto, carrello, checkout e thankyou.php.

2) Inserire gtag.js nel layout PHP

Nel tuo header.php (prima di </head>) incolla:

<?php
  // config.php
  $GA_MEASUREMENT_ID = 'G-XXXXXXXXX'; // <-- Sostituisci
?>

<script async src="https://www.googletagmanager.com/gtag/js?id=<?= htmlspecialchars($GA_MEASUREMENT_ID) ?>"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){ dataLayer.push(arguments); }
  gtag('js', new Date());
  // Consent Mode base: aggiornalo dopo il consenso reale
  gtag('consent', 'default', { 'ad_storage': 'denied', 'analytics_storage': 'denied' });
  gtag('config', '<?= addslashes($GA_MEASUREMENT_ID) ?>');
</script>

3) Eventi e-commerce lato client (gtag)

3.1 view_item (pagina prodotto)

Nel controller PHP della scheda prodotto hai i dati del prodotto. Passali al front-end per l’evento:

<?php
  // Esempio dati prodotto
  $product = [
    'id' => 'SKU-123',
    'name' => 'Camicia Donna Colletto Classico',
    'brand' => 'OXO Moda',
    'category' => 'Abbigliamento > Camicie',
    'variant' => 'Verde',
    'price' => 29.90,
    'currency' => 'EUR'
  ];
?>

<script>
  gtag('event', 'view_item', {
    currency: '<?= $product['currency'] ?>',
    value: <?= number_format($product['price'], 2, '.', '') ?>,
    items: [{
      item_id: '<?= addslashes($product['id']) ?>',
      item_name: '<?= addslashes($product['name']) ?>',
      item_brand: '<?= addslashes($product['brand']) ?>',
      item_category: '<?= addslashes($product['category']) ?>',
      item_variant: '<?= addslashes($product['variant']) ?>',
      price: <?= number_format($product['price'], 2, '.', '') ?>
    }]
  });
</script>

3.2 add_to_cart (click sul bottone “Aggiungi”)

Al click, invia l’evento con i dati della riga:

<button id="btnAddToCart">Aggiungi al carrello</button>
<script>
  document.getElementById('btnAddToCart').addEventListener('click', function(){
    gtag('event', 'add_to_cart', {
      currency: '<?= $product['currency'] ?>',
      value: <?= number_format($product['price'],2,'.','') ?>,
      items: [{
        item_id: '<?= addslashes($product['id']) ?>',
        item_name: '<?= addslashes($product['name']) ?>',
        price: <?= number_format($product['price'],2,'.','') ?>,
        quantity: 1
      }]
    });
  });
</script>

3.3 begin_checkout (ingresso checkout)

Quando l’utente apre il checkout, calcola totale e elenco articoli lato PHP e stampali nello script:

<?php
  // $cartItems = [[id,name,price,qty], ...] e $currency
  $value = 0; foreach($cartItems as $it){ $value += $it['price']*$it['qty']; }
?>
<script>
  gtag('event', 'begin_checkout', {
    currency: '<?= $currency ?>',
    value: <?= number_format($value,2,'.','') ?>,
    items: [<?php
      $first = true;
      foreach($cartItems as $it){
        if(!$first) echo ','; $first=false;
        echo json_encode([
          'item_id' => $it['id'],
          'item_name' => $it['name'],
          'price'    => (float)$it['price'],
          'quantity' => (int)$it['qty']
        ]);
      }
    ?>]
  });
</script>

3.4 purchase (pagina di ringraziamento)

Su thankyou.php, dopo aver creato l’ordine in PHP, invia l’evento “purchase” con ID univoco:

<?php
  // Dati ordine confermato
  $orderId   = $order['id'];          // es. ABC123
  $currency  = $order['currency'];    // EUR
  $value     = $order['total'];       // 99.90
  $tax       = $order['tax'];         // 8.90
  $shipping  = $order['shipping'];    // 5.00
  $coupon    = $order['coupon'] ?? null;
  $items     = $order['items'];       // array con id, name, price, qty
?>

<script>
  gtag('event', 'purchase', {
    transaction_id: '<?= addslashes($orderId) ?>',
    currency: '<?= $currency ?>',
    value: <?= number_format($value,2,'.','') ?>,
    tax: <?= number_format($tax,2,'.','') ?>,
    shipping: <?= number_format($shipping,2,'.','') ?>,
    coupon: '<?= $coupon ? addslashes($coupon) : '' ?>',
    items: [<?php
      $first = true;
      foreach($items as $it){
        if(!$first) echo ','; $first=false;
        echo json_encode([
          'item_id' => $it['id'],
          'item_name' => $it['name'],
          'price'    => (float)$it['price'],
          'quantity' => (int)$it['qty']
        ]);
      }
    ?>]
  });
</script>
Importante: il transaction_id deve essere unico per evitare duplicati in GA4.

4) (Opzionale) Invio server-side con Measurement Protocol (PHP)

Utile come fallback (ad blocker) o per convalida. Richiede Measurement ID e API Secret (Admin GA4 → Data Streams → Web → Measurement Protocol API secrets).

<?php
function ga4_send_purchase_server_side($measurementId, $apiSecret, $clientId, $purchasePayload){
  $endpoint = "https://www.google-analytics.com/mp/collect?measurement_id={$measurementId}&api_secret={$apiSecret}";
  $body = json_encode([
    'client_id' => $clientId, // es. genera UUID v4 e salvalo in cookie _cid
    'events' => [[
      'name' => 'purchase',
      'params' => $purchasePayload
    ]]
  ], JSON_UNESCAPED_SLASHES);

  $ch = curl_init($endpoint);
  curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10
  ]);
  $resp = curl_exec($ch);
  $http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  curl_close($ch);
  return [$http, $resp];
}

// ESEMPIO USO dopo ordine:
$clientId = $_COOKIE['_cid'] ?? bin2hex(random_bytes(16)); // genera se manca e salva cookie
setcookie('_cid', $clientId, time()+31536000, '/', '', true, true);

$payload = [
  'transaction_id' => $order['id'],
  'currency'       => $order['currency'],
  'value'          => (float)$order['total'],
  'tax'            => (float)$order['tax'],
  'shipping'       => (float)$order['shipping'],
  'items'          => array_map(function($it){
    return [
      'item_id'   => $it['id'],
      'item_name' => $it['name'],
      'price'     => (float)$it['price'],
      'quantity'  => (int)$it['qty']
    ];
  }, $order['items'])
];

list($status,$resp) = ga4_send_purchase_server_side('G-XXXXXXX','YOUR_API_SECRET',$clientId,$payload);
// Logga $status per debug
?>
Best practice: evita doppio invio (client + server) per lo stesso ordine. Se usi entrambi, adotta una logica di de-dupe (es. flag su DB “ga4_sent”).

5) Consenso e GDPR (base)

  1. Mostra un banner cookie che consenta/nega Analytics.
  2. Se accetta, aggiorna Consent Mode:
    <script>
      // dopo consenso
      gtag('consent', 'update', { 'analytics_storage': 'granted', 'ad_storage': 'denied' });
    </script>
  3. Se nega, mantieni “denied” e non inviare eventi opzionali (o usa Consent Mode v2 con pings limitati).

6) Verifica e debug

  • GA4 → Report → In tempo reale per vedere eventi live.
  • DebugView (attiva gtag('set', 'debug_mode', true) in staging).
  • Controlla la console browser per eventuali errori JS.
  • Per server-side, logga lo status HTTP del Measurement Protocol (200 atteso).

Checklist rapida

  • gtag.js caricato su tutte le pagine.
  • Eventi: view_item, add_to_cart, begin_checkout, purchase.
  • ID transazione univoco.
  • Consent Mode e banner cookie attivi.
  • (Opzionale) Fallback server-side con de-dupe.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.