Commerce-Setup
Beaconry bindet die echten Action-Hooks deines Shops und feuert den Shop-Funnel server-seitig: Produktansichten, Warenkorb-Änderungen, Checkout, Kauf und Erstattung, jedes Event mit dem vollständigen GA4-items[]-Array und dem Meta-content_*-Katalogblock, damit Dynamic Product Ads ohne Extra-Konfiguration matchen. Drei Plattformen sind heute am Start: WooCommerce, Easy Digital Downloads und SureCart. Plugin aktivieren, den Schalter im Commerce-Tab umlegen, fertig. Es gibt kein JavaScript-Snippet, das du in ein Template einfügen musst.
Die drei Plattformen auf einen Blick
Jede Plattform bekommt einen eigenen Adapter, der sich nur registriert, wenn ihr Host-Plugin geladen ist und du ihren Schalter aktiviert hast. Eine Installation mit nur WooCommerce trägt nie EDD- oder SureCart-Code-Pfade. Wie viel vom Funnel eine Plattform abdeckt, hängt komplett davon ab, welche Hooks diese Plattform server-seitig feuert, und hier unterscheiden sich die drei stark.
| Plattform | Server-seitige Funnel-Abdeckung | Wie der Funnel bezogen wird |
|---|---|---|
| WooCommerce | Voller 10-Event-Funnel | Native WooCommerce-Action-Hooks, Classic- und Block-Checkout beide abgedeckt. |
| Easy Digital Downloads | 8 Events (kein search, kein add_payment_info) | Native EDD-Action-Hooks, render-pfad-agnostisch über template_redirect und EDD-Conditional-Tags. |
| SureCart | purchase und refund server-seitig, der Rest des Funnels über die Browser-Bridge | SureCarts Warenkorb-UI ist eine JavaScript-Web-Component, die keine PHP-Action emittiert, daher wird der Warenkorb-Funnel im Browser erfasst und über denselben Server-Endpoint zurückgeleitet. |
Die Form jedes Events ist über alle drei identisch: ein GA4-items[]-Array (item_id, item_name, item_brand, item_category, item_variant, price, quantity) und ein Meta-CAPI-Content-Block (content_ids[], content_type, content_name, content_category, num_items). Genau diese eine kanonische Form ist es, die einen einzelnen Kauf auf zehn Kanäle ausfächern lässt und trotzdem den Produktkatalog jeder Plattform matchen lässt. Die Währung kommt direkt aus dem Shop (WooCommerce-Shop-Währung, EDD-Shop-Währung, die Währung jeder einzelnen SureCart-Order), und Multi-Currency normalisiert sie automatisch, sobald du das aktivierst.
Commerce-Tracking aktivieren
Der Commerce-Tab erscheint im Beaconry-Menü nur, wenn ein unterstütztes Shop-Plugin aktiv ist, du starrst also nie auf einen leeren Tab. Öffne wp-admin, Beaconry, Commerce. Jede erkannte Plattform hat ihre eigene Karte mit einem einzigen Master-Schalter und einer ausklappbaren "Welche Events werden getrackt?"-Liste. Schalter umlegen, speichern, und diese Plattform feuert sofort los. Speichern in diesem Tab schreibt nur die drei Commerce-Schalter, deine Einstellungen im Forms-Tab werden nie angefasst.
Service-Pills oben im Tab zeigen jede aktive Plattform auf einen Blick als an oder aus und scrollen dich zu ihrer Karte. Das ist das gesamte Setup. Die Customer-Matching-Felder (E-Mail, Telefon, Name, Stadt, PLZ) werden automatisch aus der Order gezogen und pro Kanal mit SHA-256 gehasht, bevor irgendetwas deinen Server verlässt, du bekommst also gute Match-Qualität ohne Extra-Aufwand.
WooCommerce: der volle 10-Event-Funnel
WooCommerce ist die tiefste Integration, weil es das reichhaltigste Set an server-seitigen Hooks feuert. Alle zehn Standard-Commerce-Events sind abgedeckt:
view_item: ein Besucher öffnet eine Produktseite. Das Kern-Event fürs Katalog-Matching bei Meta Dynamic Product Ads.view_item_list: ein Besucher öffnet den Shop, eine Kategorie oder ein Tag-Archiv. Auf 24 Produkte gedeckelt, damit eine große Archiv-Ansicht ein begrenztes Payload bleibt.view_cart: ein Besucher öffnet die Warenkorb-Seite.add_to_cart: ein Besucher fügt ein Produkt hinzu. Deckt alle drei Hinzufüge-Pfade ab: Classic-Page-Reload, AJAX-Inline-Buttons auf Archiven und das Block- / Store-API-Add-to-Cart.remove_from_cart: ein Besucher entfernt eine Line-Item-Position.search: ein Besucher durchsucht den Shop, inklusive der eigenständigen Produktsuche-Ergebnis-URL, die keine Shop- oder Kategorie-Seite ist.begin_checkout: ein Besucher betritt den Checkout. Feuert sowohl beim Classic-Shortcode-Checkout als auch beim Checkout-Block.add_payment_info: die Order wird platziert und eine Zahlungsmethode festgelegt. Feuert sowohl bei der Classic- als auch bei der Store-API-(Block-)Order-Verarbeitung.purchase: die Order ist eingegangen, mit allen Line Items, Versand, Steuer und Gutschein-Codes.refund: die Order wird erstattet. Wird als Negativ-Wert-Event gesendet, damit Reports korrekt netto rechnen (siehe "Erstattungen" unten).
Classic- und Block-Checkout
Das ist der Teil, den die meisten Server-Side-Setups falsch machen, daher lohnt es sich, explizit zu sein. Der Block-basierte Checkout hat keinen server-seitigen "Checkout-Formular gerendert"-Hook, eine naive Integration feuert begin_checkout auf Block-Checkouts also still nie. Beaconry behandelt den Checkout render-pfad-agnostisch: es setzt bei is_checkout() an template_redirect an (ein Page-ID-Match, keine URL und kein Render-Pfad), sodass der Classic-Shortcode, der Gutenberg-Checkout-Block und Page-Builder-Checkouts alle ein begin_checkout feuern. Die Classic-Hooks woocommerce_before_checkout_form und der offizielle Block-Hook woocommerce_blocks_checkout_enqueue_data bleiben als doppelte Absicherung verdrahtet, und ein Per-Request-Guard reduziert den jeweils zuerst feuernden auf einen einzigen Dispatch. Dieselbe doppelte Abdeckung gilt für add_payment_info, das sowohl auf woocommerce_checkout_order_processed (Classic) als auch auf woocommerce_store_api_checkout_order_processed (Block) lauscht.
Eine Konsequenz von Block- und AJAX-Kontexten: diese Hooks feuern innerhalb eines REST- oder admin-ajax-Requests, wo die Request-URL der Endpoint ist, nicht die Seite, auf der der Kunde war. Beaconry erkennt Async-Kontexte über WordPress-API-Flags (REST_REQUEST, wp_doing_ajax()) und löst die kundenseitige Seiten-URL aus dem Referer oder dem konfigurierten Checkout-Seiten-Permalink auf. Es parst oder slug-matcht nie URLs, eine umbenannte Warenkorb- oder Checkout-Seite kann das Tracking also nicht brechen.
Die per-Order-event_id
Purchase-Events nutzen eine deterministische event_id, die aus der Order abgeleitet wird: bcnr_purchase_<order_id>. Ein Refresh der Danke-Seite feuert den WooCommerce-Hook woocommerce_thankyou erneut, aber die stabile ID plus ein Order-Meta-Marker sorgen dafür, dass der Kauf immer nur einmal gezählt wird. Genau dieselbe ID ist auch das, was die Deduplizierung im Hybrid-Modus funktionieren lässt: wenn du zusätzlich ein Browser-Pixel betreibst, übergibt Beaconry die identische event_id an das browser-seitige Purchase-Event, sodass der Vendor die Browser- und Server-Kopien auf seiner Seite dedupliziert. View-Events ohne natürlichen Unique-Key (view_item_list, view_cart, begin_checkout) nutzen eine gefensterte deterministische ID, sodass ein Prefetch- oder Redirect-Doppel-Request auf eine Conversion kollabiert, während eine echte Wiederholungsansicht Minuten später trotzdem zählt.
Katalog-Match: items[] und content_*
Jedes WooCommerce-Event trägt beide Repräsentationen der beteiligten Produkte. item_id und content_ids[] bevorzugen die Produkt-SKU und fallen auf die WooCommerce-Produkt-ID zurück, sodass sie zu deinen Google-Merchant-Center- und Meta-Catalog-Feeds passen. item_brand wird aus dem Attribut pa_brand oder einer product_brand-Taxonomie gelesen, item_category aus der ersten zugewiesenen Produktkategorie und item_variant aus den Variations-Attributen bei variablen Produkten. Der Meta-Block setzt content_type auf product_group, wenn mehr als ein Produkt vorhanden ist, und sonst auf product. Nichts davon braucht Konfiguration, es wird aus deinen bestehenden Produktdaten abgeleitet.
Easy Digital Downloads: 8 Events
EDD ist der Standard für digitale Güter (Plugins, Themes, eBooks, Musik) und viele Beaconry-Kunden nutzen es statt WooCommerce, weil es für reine Digitalverkäufe schlanker ist. EDD feuert server-seitige Hooks für den größten Teil des Funnels, daher trackt Beaconry acht Events:
view_item: ein Besucher öffnet eine Download-(Produkt-)Seite.view_item_list: ein Besucher öffnet das Shop-Archiv, eine Download-Kategorie oder ein Tag. Erfasst auf dem nativen CPT-Archiv, dem[downloads]-Shortcode und demedd/downloads-Gutenberg-Block.view_cart: ein Besucher öffnet den Checkout mit Artikeln im Warenkorb.add_to_cart: ein Besucher fügt einen Download zum Warenkorb hinzu.remove_from_cart: ein Besucher entfernt einen Download.begin_checkout: ein Besucher betritt den EDD-Checkout.purchase: eine Zahlung wird abgeschlossen, mit allen Downloads, Steuer und Summen.refund: eine Zahlung wird erstattet, als Negativ-Wert-Event gesendet.
Zwei Events aus der WooCommerce-Liste fehlen bewusst, weil EDD sie nicht server-seitig bereitstellt. Es gibt kein search-Event (EDD hat keinen Shop-Such-Hook, an den Beaconry binden könnte) und kein add_payment_info-Event (EDDs Zahlungsmethoden-Schritt wird vom Theme gerendert und nicht als Action verfügbar gemacht). Die acht Events oben sind alles, was EDD ab Werk mitbringt.
Wie bei WooCommerce sind die View- und Checkout-Events render-pfad-agnostisch. Sie setzen an is_singular('download') und edd_is_checkout() bei template_redirect an statt an den alten the_content-basierten Template-Hooks, sodass sie auch dann korrekt feuern, wenn ein Page-Builder (Elementor Theme Builder, Divi, Bricks) das Single-Download- oder Checkout-Template rendert und the_content umgeht. Purchase-Events dedupen auf einer stabilen per-Payment-ID, bcnr_edd_purchase_<payment_id>, sodass ein Refresh der Danke-Seite nie doppelt zählt.
SureCart: Server-Purchase plus die Browser-Bridge
SureCart ist der neuere, SaaS-artige Commerce-Player, stark bei Subscriptions und zunehmend beliebt bei den performance-marketing-orientierten Shops, die Beaconrys Kernpublikum sind. Seine Architektur braucht einen anderen Ansatz. SureCarts Warenkorb- und Checkout-UI ist eine JavaScript-Web-Component (sc-line-item-list und Verwandte), die keine PHP-Action für Warenkorb-Events emittiert, es gibt also nichts, woran ein server-seitiger Hook für add_to_cart, view_cart, begin_checkout und den Rest binden könnte.
Beaconry teilt die Abdeckung auf, um dieser Realität gerecht zu werden:
- Server-seitig, autoritativ: der PHP-Adapter feuert
purchaseauf der Actionsurecart/checkout_confirmedundrefundauf SureCarts Refund-Model-Event. Das sind die Conversions, die niemals verpasst werden dürfen, und sie in PHP zu binden bedeutet, dass sie auch bei Orders gezählt werden, die nie das Browser-Warenkorb-UI berühren, wie E-Mail- oder Manuell-Charge-Orders. Der Kauf dedupliziert auf einer stabilen per-Order-ID,bcnr_sc_purchase_<order_id>. - Browser-Bridge, für den Warenkorb-Funnel: die Upper-Funnel-JavaScript-Events, die SureCart im Browser dispatcht (Produktansicht, Listenansicht, Add-to-Cart, Remove, Warenkorb-Ansicht, Begin-Checkout, Zahlungs- und Versandinfo, Suche), werden von der SureCart-Bridge innerhalb von Beaconrys Browser-Engine erfasst und über exakt denselben Same-Origin-REST-Endpoint und denselben server-seitigen Forwarder zurückgeleitet. Diese Events werden also weiterhin getrackt und sind aus Sicht des Vendors weiterhin server-seitig, sie betreten die Pipeline nur vom Browser statt von einem PHP-Hook.
Das praktische Ergebnis: SureCart bekommt den vollen Funnel, aber die beiden Events, die über Umsatz entscheiden, purchase und refund, haben eine harte server-seitige Garantie unabhängig von jedem Browser-JavaScript, während die Warenkorb-Funnel-Events auf der Bridge reiten. Beträge werden für Null-Dezimal-Währungen (JPY, KRW und der Rest) korrekt behandelt, wo der SureCart-Betrag bereits in Haupt-Einheiten statt in Cent vorliegt.
Erstattungen: nur GA4, mit Absicht
Das Routing von Erstattungen ist der eine Punkt, an dem Commerce-Tracking eine Meinung haben muss, und Beaconry hat eine. Wenn eine Order auf einer der drei Plattformen erstattet wird, wird die Erstattung nur an GA4 gesendet. Jeder Ad-Kanal wird bewusst übersprungen. Der Grund ist simpel und verständlich:
- GA4 hat ein echtes
refund-Event, das den erstatteten Umsatz gegen den Original-Kauf netto rechnet, sodass dein GA4-Umsatz-Reporting ohne Tabellenkalkulation korrekt bleibt. Beaconry sendet die Erstattung dorthin als Negativ-Wert-Event, das an dieselbe Transaktions-ID gebunden ist. - Kein Ad-Kanal hat ein echtes Refund-Event. Meta CAPI, TikTok, Pinterest, Snapchat, Reddit und der Rest haben entweder gar kein Refund-Event oder nur ein Custom-Event, das ein toter Zähler ist, unsichtbar für Smart Bidding und nie gegen die Conversion verrechnet. Schlimmer noch, auf manchen Kanälen (Snapchat zum Beispiel) würde ein erzwungenes Custom-Refund-Event mit dem für Lead-Conversions reservierten Slot kollidieren und dein Conversion-Reporting verschmutzen. Eine Fake-Erstattung an eine Ad-Plattform zu senden fügt Rauschen hinzu und bringt null Optimierungs-Wert, deshalb tut Beaconry das nicht.
Diese Aufteilung wird zentral im Forwarder durchgesetzt, nicht pro Plattform, sodass alle drei Commerce-Adapter identisches Refund-Verhalten bekommen und ein künftiger Kanal die Regel automatisch erbt. Wenn du Erstattungen im Reporting einer Ad-Plattform reflektiert brauchst, ist das ein manueller Export gegen die eigene Order-Management- oder Offline-Conversion-Adjustment-API der Plattform, eine andere Schnittstelle als die Conversions API, die Beaconry ansteuert.
Per-Kanal-Event-Abdeckung
Nicht jedes Funnel-Event lässt sich sauber auf das Standard-Event-Vokabular jedes Ad-Kanals abbilden. Beaconry sendet ein Event nur dann an einen Kanal, wenn dieser Kanal ein sinnvolles Standard-Event dafür hat, sonst wird es im Forwarder übersprungen, damit du keine Doppelzählungen oder Junk-Custom-Events bekommst, die den Conversion-Manager eines Kanals aufblähen. GA4 erhält den kompletten Funnel. Die Tabelle unten zeigt, wo jedes WooCommerce- oder EDD-Event landet (SureCarts server-seitige Events sind purchase und refund; seine gebridgeten Warenkorb-Events folgen denselben Per-Kanal-Regeln wie die Zeilen unten).
| Funnel-Event | GA4 | Meta CAPI | TikTok | Snapchat | ||
|---|---|---|---|---|---|---|
view_item | Ja | ViewContent | ViewContent | view_content | VIEW_CONTENT | VIEW_CONTENT |
view_item_list | Ja | Übersprungen | Übersprungen | view_category | Übersprungen | Übersprungen |
view_cart | Ja | Custom (ViewCart) | Übersprungen | Übersprungen | Übersprungen | Übersprungen |
add_to_cart | Ja | AddToCart | AddToCart | add_to_cart | ADD_CART | ADD_TO_CART |
remove_from_cart | Ja | Custom (RemoveFromCart) | Übersprungen | Übersprungen | Übersprungen | Übersprungen |
search | Ja | Search | Search | search | SEARCH | SEARCH |
begin_checkout | Ja | InitiateCheckout | InitiateCheckout | initiate_checkout | START_CHECKOUT | Custom |
add_payment_info | Ja | AddPaymentInfo | AddPaymentInfo | add_payment_info | ADD_BILLING | Custom |
purchase | Ja | Purchase | Purchase | checkout | PURCHASE | PURCHASE |
refund | Ja | Übersprungen | Übersprungen | Übersprungen | Übersprungen | Übersprungen |
Warum "Übersprungen" so oft in den Upper-Funnel- und Refund-Zeilen auftaucht: die meisten Ad-Kanäle bilden view_item_list und view_cart auf dasselbe ViewContent-artige Event ab wie view_item, sodass das Senden aller drei eine einzelne Seitenansicht im Reporting dieses Kanals verdoppeln oder verdreifachen würde, ohne Smart Bidding ein neues Signal zu geben. Diese Kanäle optimieren auf Produktdetail- und Conversion-Signale (ViewContent, AddToCart, Purchase), nicht auf Listen- oder Warenkorb-Ansichten, daher sendet Beaconry das sinnvolle und überspringt die Duplikate. remove_from_cart und refund haben auf diesen Kanälen überhaupt keinen Standard-Slot. Pinterest ist die Ausnahme, die view_item_list behält, weil es ein eigenes view_category-Event hat. Reddits Standard-Vokabular hat kein Checkout-Stage-Event, daher landen begin_checkout und add_payment_info dort als Custom-Events statt als Standard-Conversions, während Snapchat native START_CHECKOUT- und ADD_BILLING-Slots hat.
Die vier Conversion-Slot-Kanäle (Google Ads, Microsoft Ads, LinkedIn, X Ads) werden nicht als Spalten gezeigt, weil sie anders funktionieren: jeder feuert nur die Events, die du explizit auf eine Conversion-Action, ein Goal, eine Rule oder einen Slot im Setup dieses Kanals gemappt hast. Mappe purchase auf eine Google-Ads-Conversion-Action und ein Kauf feuert dort; lass ein Funnel-Event ungemappt und es dispatcht schlicht nicht an diesen Kanal. Sie erhalten den vollen Funnel-Feed, deine Slot-Konfiguration entscheidet, welche Events zu Conversions werden. Siehe die Per-Kanal-Guides unter Channel-Setup für das Slot-Mapping bei jedem.
Consent und Admin-Traffic
Commerce-Events gehen durch dasselbe zentrale Consent-Gate wie jedes andere Beaconry-Event: ohne im nl_pref-Cookie gespeicherte Besucher-Einwilligung wird nichts dispatcht. Weil ein Kauf oder eine Erstattung eine abgeschlossene server-seitige Action ist, wird Consent einmal im Dispatcher durchgesetzt statt bei jedem Hook erneut geprüft. Eingeloggte Admins sind standardmäßig vom Frontend-Tracking ausgeschlossen, mit einer bewussten Ausnahme: wenn ein Admin eine SureCart-Order als bezahlt markiert oder eine Erstattung aus dem Dashboard verarbeitet, gehört diese Conversion dem Kunden, der gekauft hat, nicht dem Admin, der den Button klickt, daher umgehen diese spezifischen Server-Events das Admin-Gate und werden trotzdem gezählt.
Troubleshooting
- "begin_checkout feuert nie auf meinem Block-Checkout": stelle sicher, dass der WooCommerce-Schalter unter Beaconry, Commerce aktiv ist und dass du nicht als Admin eingeloggt bist (Frontend-Tracking überspringt Admins standardmäßig). Der Block-Checkout ist über
is_checkout()beitemplate_redirectabgedeckt, eine umbenannte Checkout-Seite ist also nicht die Ursache. Beobachte, wie das Event in der GA4-Echtzeit-Ansicht oder im Live-Dashboard ankommt. - "Meine SureCart-Add-to-Cart-Events fehlen": die reiten auf der Browser-Bridge, nicht auf einem PHP-Hook, daher feuern sie erst, nachdem der Besucher Consent akzeptiert (die Bridge ist consent-gated wie alle Browser-Events).
purchaseundrefundsind server-seitig und unabhängig von der Bridge, wenn also Käufe ankommen, aber Warenkorb-Events nicht, prüfe, ob das Consent-Banner akzeptiert wird. - "EDD zeigt keine Search- oder Payment-Info-Events": erwartet. EDD stellt für keines der beiden server-seitige Hooks bereit, diese zwei Events sind also nicht Teil des EDD-Funnels. Die anderen acht schon.
- "Erstattungen tauchen nicht in Meta / Google Ads auf": ebenfalls erwartet und mit Absicht. Erstattungen werden nur an GA4 geleitet, weil kein Ad-Kanal ein echtes Refund-Event hat. Prüfe das GA4-
refund-Event, wo der Negativ-Wert gegen den Kauf netto rechnet. - "Ein Refresh der Danke-Seite hat den Kauf doppelt gezählt": sollte nicht passieren, die per-Order-event_id plus ein Order-Meta-Marker verhindern es. Wenn du ein echtes Duplikat siehst, prüfe, dass du nicht zusätzlich einen zweiten Kauf aus einem separaten Browser-Pixel feuerst, ohne ihm Beaconrys event_id zu übergeben (der Hybrid-Modus verkabelt das für dich).