PrestaShop: Pixel i CAPI OpenAI Ads dla PrestaShop: Kompletna konfiguracja
Techniczny przewodnik wdrożenia Pixela i CAPI w PrestaShop: hooki Smarty, zdarzenie actionValidateOrder i serwerowy przekaźnik CAPI.
PrestaShop powers thousands of fast-growing stores across Europe and Latin America. But running paid campaigns on ChatGPT from a PrestaShop store brings an immediate challenge: European shoppers use ad blockers at rates exceeding 30% to 40%, and strict cookie consent banners frequently block tracking scripts before a user ever clicks "Accept".
If you rely only on a browser-side snippet in your theme header, over a third of your sales vanish into thin air.
Your ads generate orders, your warehouse ships product, but your ad reporting shows a fraction of your actual revenue.
To fix this, you need a dual-channel setup in PrestaShop. Use the displayHeader hook for storefront visits, and use the backend hook actionValidateOrder to fire an asynchronous server-side Conversions API (CAPI) call the instant an order is validated in your database. Here is the complete code and hook structure for PrestaShop 1.7 and 8.x.
1. PrestaShop Event Mapping Table
| PrestaShop User Action | PrestaShop Hook | OpenAI Ads Event | Delivery Method |
|---|---|---|---|
| Storefront Page Load | displayHeader | page_viewed | Browser Pixel |
| Product Details View | displayFooterProduct | contents_viewed | Browser Pixel |
| Cart Addition | actionCartSave (AJAX) | items_added | Browser Pixel |
| Checkout Start | displayPersonalInformationTop | checkout_started | Browser Pixel |
| Order Confirmation Screen | displayOrderConfirmation | order_created | Browser Pixel |
| Order Validated in DB | actionValidateOrder | order_created | Server CAPI (cURL) |
2. Front-End Pixel Setup via displayHeader
In your custom PrestaShop module (or child theme templates/_partials/head.tpl), inject the OpenAI Ads measurement pixel:
// In your custom module's hookDisplayHeader method
public function hookDisplayHeader($params)
{
$pixelId = Configuration::get('COMERCIO_OPENAI_PIXEL_ID');
if (!$pixelId) return '';
return '
<script>
!function(w,d,e,v,n,t,s){if(w.oaiq)return;n=w.oaiq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!w._oaiq)w._oaiq=n;
n.push=n;n.loaded=!0;n.version="1.0";n.queue=[];t=d.createElement(e);t.async=!0;
t.src=v;s=d.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}
(window,document,"script","https://bzrcdn.openai.com/pixel.js");
oaiq("init", "' . pSQL($pixelId) . '");
oaiq("event", "page_viewed");
</script>';
}
3. Order Confirmation Browser Tracking (displayOrderConfirmation)
When a customer lands on the final order confirmation screen, fire the client-side order_created event:
public function hookDisplayOrderConfirmation($params)
{
$order = isset($params['order']) ? $params['order'] : null;
if (!$order) return '';
$orderId = (int)$order->id;
$amountCents = (int)round(((float)$order->total_paid_tax_incl) * 100);
$currency = new Currency((int)$order->id_currency);
$currencyIso = $currency->iso_code;
$dedupKey = 'ps_order_' . $orderId;
return '
<script>
if (window.oaiq) {
window.oaiq("event", "order_created", {
order_id: "' . (string)$orderId . '",
amount: ' . $amountCents . ',
currency: "' . pSQL($currencyIso) . '",
event_id: "' . pSQL($dedupKey) . '"
});
}
</script>';
}
4. Server-Side CAPI Implementation via actionValidateOrder
Why is actionValidateOrder the best hook for CAPI in PrestaShop?
Because it fires whenever an order status transitions to validated in your database, regardless of payment method. If a customer pays with an external banking gateway (like iDEAL, Sofort, or Redsys) and never returns to your store, this hook still fires on your server:
public function hookActionValidateOrder($params)
{
$order = $params['order'];
$customer = $params['customer'];
if (!$order || !$customer) return;
$orderId = (int)$order->id;
$pixelId = Configuration::get('COMERCIO_OPENAI_PIXEL_ID');
$capiKey = Configuration::get('COMERCIO_OPENAI_CAPI_KEY');
if (!$pixelId || !$capiKey) return;
$amountCents = (int)round(((float)$order->total_paid_tax_incl) * 100);
$currency = new Currency((int)$order->id_currency);
$email = strtolower(trim((string)$customer->email));
$dedupKey = 'ps_order_' . $orderId; // Matches browser event_id
$payload = [
'validate_only' => false,
'events' => [
[
'id' => 'srv_ps_' . $orderId . '_' . time(),
'type' => 'order_created',
'timestamp_ms' => (int)round(microtime(true) * 1000),
'action_source' => 'website',
'event_id' => $dedupKey,
'user_data' => [
'em' => hash('sha256', $email),
'client_ip_address' => Tools::getRemoteAddr()
],
'data' => [
'amount' => $amountCents,
'currency' => $currency->iso_code,
'order_id' => (string)$orderId
]
]
]
];
$endpoint = 'https://bzr.openai.com/v1/events?pid=' . $pixelId;
$ch = curl_init($endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_TIMEOUT, 4);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $capiKey,
'Content-Type: application/json'
]);
curl_exec($ch);
curl_close($ch);
}
5. Deduplication and Verification
Deduplication protects your store metrics from double-counted orders.
Both your displayOrderConfirmation template script and your backend actionValidateOrder hook pass event_id: "ps_order_" . $orderId. When OpenAI's system receives both events within a 48-hour window, it merges the client click data with the verified server-side total and records a single conversion.
If the browser tag is blocked by an ad blocker, the server CAPI call ensures the conversion is never lost.
Need professional assistance implementing OpenAI Ads tracking on PrestaShop? Review our Done-For-You Ecommerce Tracking service.