← Zurück zu Insights

Magento 2: OpenAI Ads Pixel und CAPI für Magento 2 (Adobe Commerce): Vollständige Einrichtung

Implementieren Sie OpenAI Ads Pixel und CAPI auf Magento 2 mit benutzerdefinierten Observern, GraphQL-Checkout-Ereignissen und Deduplizierung.

2026-10-02 • Leitfaden

Anyone who runs enterprise stores on Magento 2 (Adobe Commerce) knows how easily frontend tracking falls apart. You have Varnish Full Page Cache (FPC) aggressively caching static templates, complex single-page checkouts, and external payment gateways (like Adyen, Cybersource, or PayPal) that redirect customers across domains. If a customer pays on PayPal and never clicks "Return to Merchant", your checkout_onepage_success block never renders.

The order exists in Magento, but OpenAI Ads Manager never hears about it.

In high-volume B2B or consumer stores, missing 15% of your conversions skews bidding models and inflates reported customer acquisition cost (CAC). To capture every dollar, Magento requires a split setup: layout XML or Hyvä components for storefront browsing, and an asynchronous backend observer on sales_order_place_after that sends purchase data directly to OpenAI's Conversions API (CAPI).


1. Event Mapping Architecture for Adobe Commerce

Customer Funnel ActionMagento 2 Event / LayoutOpenAI Ads EventDelivery Method
Catalog Category Viewcatalog_category_viewpage_viewedBrowser Pixel
Product Details Pagecatalog_product_viewcontents_viewedBrowser Pixel
Add to Cart ActionCustomer Data Section (cart)items_addedBrowser Pixel
Initiate OnePage Checkoutcheckout_index_indexcheckout_startedBrowser Pixel
Order Confirmation Screencheckout_onepage_successorder_createdBrowser Pixel
Order Created in Databasesales_order_place_afterorder_createdServer CAPI (Queue Worker)

2. Front-End Pixel Installation (Luma & Hyvä)

A. Layout XML Injection (default_head_blocks.xml)

Inject the base pixel asynchronously in your custom theme's Magento_Theme/layout/default_head_blocks.xml:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <script src="https://bzrcdn.openai.com/pixel.js" src_type="url"/>
        <link src="Comercio_OpenAiAds::js/pixel-init.js"/>
    </head>
</page>

In pixel-init.js:

!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', 'YOUR_OPENAI_PIXEL_ID');
oaiq('event', 'page_viewed');

B. Success Page Browser Tracking

In your checkout success block template (checkout_onepage_success.phtml), output the order confirmation with the order's increment ID as the deduplication key:

<?php
/** @var \Magento\Checkout\Block\Onepage\Success $block */
$order = $block->getOrder();
if ($order && $order->getId()):
    $incrementId = $order->getIncrementId();
    $amountCents = (int)round(((float)$order->getBaseGrandTotal()) * 100);
    $currency = $order->getBaseCurrencyCode();
    $dedupKey = 'magento_order_' . $incrementId;
?>
<script>
    if (window.oaiq) {
        window.oaiq('event', 'order_created', {
            order_id: '<?= $block->escapeJs($incrementId); ?>',
            amount: <?= $amountCents; ?>,
            currency: '<?= $block->escapeJs($currency); ?>',
            event_id: '<?= $block->escapeJs($dedupKey); ?>'
        });
    }
</script>
<?php endif; ?>

3. Server-Side CAPI Observer on sales_order_place_after

Do not dispatch synchronous HTTP requests directly inside your checkout controller. If OpenAI's API latency spikes, your customer's checkout will freeze. Instead, use an event observer to stage the payload, or dispatch it via Magento's asynchronous Message Queue (RabbitMQ or DB-backed queues).

A. Register the Observer (etc/events.xml)

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_place_after">
        <observer name="comercio_openai_capi_order" instance="Comercio\OpenAiAds\Observer\OrderPlaceAfterObserver" />
    </event>
</config>

B. Observer Implementation (OrderPlaceAfterObserver.php)

<?php
namespace Comercio\OpenAiAds\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\HTTP\Client\Curl;
use Psr\Log\LoggerInterface;

class OrderPlaceAfterObserver implements ObserverInterface
{
    private Curl $curl;
    private LoggerInterface $logger;

    public function __construct(Curl $curl, LoggerInterface $logger)
    {
        $this->curl = $curl;
        $this->logger = $logger;
    }

    public function execute(Observer $observer)
    {
        /** @var \Magento\Sales\Model\Order $order */
        $order = $observer->getEvent()->getOrder();
        if (!$order) return;

        try {
            $pixelId = 'YOUR_OPENAI_PIXEL_ID';
            $capiKey = 'YOUR_OPENAI_CAPI_KEY';
            $endpoint = "https://bzr.openai.com/v1/events?pid=" . $pixelId;

            $incrementId = $order->getIncrementId();
            $amountCents = (int)round(((float)$order->getBaseGrandTotal()) * 100);
            $billingAddress = $order->getBillingAddress();
            
            $email = strtolower(trim((string)$order->getCustomerEmail()));
            $phone = preg_replace('/\D/', '', (string)$billingAddress->getTelephone());
            $dedupKey = 'magento_order_' . $incrementId; // Matches browser event_id

            $payload = [
                'validate_only' => false,
                'events' => [
                    [
                        'id' => 'srv_magento_' . $incrementId . '_' . time(),
                        'type' => 'order_created',
                        'timestamp_ms' => (int)round(microtime(true) * 1000),
                        'action_source' => 'website',
                        'event_id' => $dedupKey,
                        'user_data' => [
                            'em' => hash('sha256', $email),
                            'ph' => !empty($phone) ? hash('sha256', $phone) : null,
                            'client_ip_address' => $order->getRemoteIp(),
                            'country' => strtolower((string)$billingAddress->getCountryId())
                        ],
                        'data' => [
                            'amount' => $amountCents,
                            'currency' => $order->getBaseCurrencyCode(),
                            'order_id' => (string)$incrementId
                        ]
                    ]
                ]
            ];

            $this->curl->setHeaders([
                'Authorization' => 'Bearer ' . $capiKey,
                'Content-Type' => 'application/json'
            ]);
            $this->curl->setTimeout(4);
            $this->curl->post($endpoint, json_encode($payload));

        } catch (\Exception $e) {
            $this->logger->error('OpenAI CAPI Error: ' . $e->getMessage());
        }
    }
}

4. Deduplication Logic

Deduplication keeps your accounting clean when both frontend and backend report the order.

By using magento_order_ followed by the increment ID (e.g., magento_order_100004521), both pipelines supply identical event_id strings. When OpenAI processes both records, it combines the browser's ad click history with the server's validated order amount. If the browser tag fails to fire because of an ad blocker or gateway redirect, your server observer ensures zero revenue drop.

Looking to audit your enterprise Adobe Commerce tracking pipeline? Explore our Done-For-You Ecommerce Tracking service.