In-app browsers breken je aankoop metingen

blog artikel - in app browsers
In this article

Stel je iemand voor die op zijn telefoon door Instagram scrolt. Hij klikt op jouw advertentie. De webshop wordt niet geopend in Safari of Chrome, maar in een browservenster binnen de app zelf. Daar doorloopt hij de hele klantreis. Hij bekijkt je producten, voegt een product toe aan zijn winkelmand en gaat naar de checkout. Tot zover niets aan de hand. Alles gebeurt netjes in dat ene venster.

Dan komt het afrekenen. Deze bezoeker wordt naar zijn betaal-app gestuurd. Na de betaling stuurt die de bezoeker terug naar de bedankpagina van de webshop. Maar niet naar de in-app browser waar de reis begon. De bezoeker komt terecht in de standaardbrowser van het apparaat, volgens de instellingen van dat apparaat. De bedankpagina laadt dus in een andere browser dan waar de bestelling is geplaatst. En precies daar loopt je meting stuk.

Browser Probleem bij Aankoop

Waarom in-app browsers blijven groeien

In-app browsers zijn geen randverschijnsel meer en deze trend groeit alleen maar verder. De reden is simpel: apps willen hun bezoekers niet kwijt. Iemand naar een andere browser sturen betekent iemand wegsturen uit je eigen app. En de kans is groot dat die persoon niet terugkeert. Daarom openen apps een eigen browser binnen de app. Zo kan de bezoeker snel en makkelijk terug naar de app zelf.

Meta (Facebook en Instagram) doet dit al jaren, X (voorheen Twitter) is er recent mee begonnen en inmiddels hebben ook de grote AI apps een eigen browser. Zowel ChatGPT als Claude openen links binnen hun eigen omgeving en er komt steeds meer websiteverkeer binnen via AI chats en AI agents. Daardoor begint een steeds groter deel van je klantreizen in zo’n in-app browser. Deze ontwikkeling is al begonnen en gaat alleen nog maar verder groeien.

Je trackt geen bezoekers, maar browsers

Om te snappen waarom dit je meting sloopt, moet je weten hoe cookies werken. Een website herkent jou als persoon niet en de tracking van je website herkent je ook niet op basis van je apparaat. Wat een website wel herkent, is je browser. Dat gebeurt via cookies die in je browser zijn opgeslagen. Je identiteit in GA4 (_ga, cid, sid, sct), je keuze in de cookiebanner en je sessiegegevens staan allemaal in de cookies van die browser.

Een in-app browser heeft zijn eigen cookies, los van je standaardbrowser. Zodra de betaling de bezoeker terugstuurt naar hun standaardbrowser, zitten ze dus in een browser zonder de cookies van de eerder gemeten klantreis. Zonder de _ga-waarde, zonder gegeven cookie-consent, geen sessie-data. Voor de website ben je een nieuwe bezoeker. Daarom krijgt een bezoeker op de bedankpagina opnieuw de cookiebanner te zien op de bedankpagina.

Wat dit doet met het meten van je aankopen

Herken je dit? Je meet je aankopen met een purchase event vanuit de dataLayer op de bedankpagina. Die tag in Google Tag Manager staat netjes ingericht met Consent Mode. In de Consent Overview heb je additionele consent checks aan staan, zodat de tag alleen vuurt bij de juiste toestemming: analytics_storage voor GA4 en ad_storage voor je advertentieplatformen.

Precies daar gaat het mis. De bezoeker wordt vanuit de betaalapp naar hun standaardbrowser gestuurd, dus daar landen ze op de bedankpagina. In die browser is er nog geen toestemming in de cookiebanner gegeven, want de cookiebanner verschijnt opnieuw. Je purchase tag ziet dus geen geaccepteerde consent signalen. Wat er dan gebeurt, hangt af van je setup. De tag vuurt helemaal niet, of hij vuurt in cookieless modus zonder de signalen die je nodig hebt.

Ben je afhankelijk van de frontend van de webshop voor het meten van je aankopen, dan meet je een deel van je aankopen structureel niet goed. En dat komt bovenop de gevallen die je al kende. Namelijk de bezoekers die cookies weigeren, en de bezoekers die de bedankpagina nooit bereiken. Je aantallen kloppen niet meer.

En stel dat de aankoop wél gemeten wordt, bijvoorbeeld omdat de bezoeker op de bedankpagina opnieuw toestemming geeft. Dan heb je nog steeds een probleem. Je meet die aankoop in een browser zonder geschiedenis. Geen _ga, sid, sct, cid, geen doorlopende sessie, en geen gclid, gbraid of andere click ID’s uit de oorspronkelijke reis. Die staan namelijk in de cookies van de in app browser, niet in je standaardbrowser.

Voor GA4 is dit een losse aankoop zonder herkomst. Het kan de conversie niet koppelen aan de sessie waarin de klant via jouw campagne binnenkwam. De aankoop komt binnen als (direct) of als unassigned. Of hij start een compleet nieuwe sessie. Je hebt voor die klik betaald, maar je kunt het kanaal er niet voor belonen. Je ROAS klopt niet en je optimaliseert je campagnes op verkeerde data.

In-App Browsers - cookies probleem

Onze webhooks: meten vanaf de backend

Jaren geleden hebben we onze backend-webhooks functionaliteit opgezet om dit gat in de metingen te dichten. Niet vanaf de frontend, maar vanaf de backend. Zodra er in je webshop een order wordt aangemaakt (Shopify, Magento, WooCommerce), stuur je vanaf dat platform een webhook naar je server container. Deze webhook bevatte de marketing en ecommerce data van je order en de klantreis. Zo kan je de aankoop vastleggen: zowel de aantallen van je orders en een volledig beeld van je ecommerce data.

Zo kreeg je betrouwbare cijfers van bezoekers die de bedankpagina niet bereikten en ook betrouwbare e-commerce data van cookieweigeraars. Maar er zat een addertje onder het gras. Om deze orders naar o.a. GA4 door te sturen, moesten de gebruiker-ID’s uit de webhook en uit de klantreis gelijk zijn aan elkaar: de cid, sid en sct. Die ID’s overschreven we met ID’s uit ons eigen marketingscript. Bij goed ingerichte CMP’s ging dat prima. Maar bij slecht ingerichte consent was dit een risico. Het kon unassigned verkeer in Google Analytics veroorzaken, omdat de ID’s niet aansloten op de echte identiteit en sessie van de bezoeker in GA4.

Webhook Matching: de reis en de order weer aan elkaar knopen

Om het unassigned probleem in GA4 op te lossen en de trend van in-app browsers aan te pakken, hebben we Webhook Matching ontwikkeld.

Het werkt zo. Op het moment dat de checkout start, bewaar je tijdelijk de marketing en gebruikersinformatie uit die klantreis op je server container. Komt de order later binnen via een webhook? Dan wordt die automatisch gematcht aan het eerder gemeten event uit dezelfde reis. De marketing en ecommerce data van de klantreis en de webhook worden samengevoegd en via het GA4 Measurement Protocol doorgestuurd naar GA4 en naar je marketingplatformen.

In deze setup worden er geen gebruiker- en sessie-ID’s meer overschreven vanuit ons eigen marketingscript. We herstellen de echte context van de reis en koppelen die aan de echte order. Zo schrijf je de aankoop toe aan de juiste sessie en de juiste campagne. Ook als de bevestiging in een andere browser gebeurt. Of helemaal niet gebeurt.

Hoe het werkt in je eigen setup

Webhook Matching draait op twee plekken die je al kent: je server container in Google Tag Manager en je AdPage server container. In de Google Tag Manager server container stel je onze nieuwe tag-template tweemaal in. De eerste is de Prepare tag. Die vuurt af bij een binnenkomende ‘begin_checkout’ event. Op dat moment wordt de marketing en gebruikersinformatie van deze gebeurtenis tijdelijk in je AdPage server container bewaard. De tweede is de Trigger tag. Die vuurt af zodra de webhook vanuit de backend van je platform (Shopify, WooCommerce, Magento) binnenkomt met de order.

Beide kanten sturen dezelfde gedeelde identifier mee, de zogeheten Basket Key. Daarmee weet de server welke prepare-gebeurtenis bij welke webhook hoort. Klopt de match, dan worden de twee payloads samengevoegd tot één compleet event. Deze samengevoegde request wordt weer naar je server container teruggestuurd zodat een Measurement Protocol client in je server container deze doorgeeft aan je endpoints: GA4, maar net zo goed Google Ads, Meta, TikTok en Pinterest. In je triggers regel je dat de purchase daarna nog maar één keer vuurt, vanuit deze Measurement Protocol client, zodat je geen dubbele conversies krijgt.

Webhooks UitlegWebhook Matching Uitleg

 

Zo zet je het aan

Webhook Matching is beschikbaar voor iedereen die al een AdPage server container heeft. Ga in je AdPage server container op data.adpage.io naar je Webhook Logs. Daar vind je alles om het op te zetten.

Doe dit in twee fasen. Zet Webhook Matching eerst aan zonder de Measurement Protocol client. Prepare en Trigger draaien dan al tegen elkaar, maar er gaat nog niets naar GA4 of je advertentieplatformen. Laat dit een paar dagen tot een week lopen en volg je Matching Rate in het dashboard. Zie je een stabiel en hoog percentage? Pas dan zet je de client aan en stuur je de gematchte webhook orders door als je purchase conversie.

Waarom die volgorde? Zet je meteen alles live terwijl de matching nog niet goed staat, dan stuur je vanaf dag één onvolledige of dubbele data naar GA4, Ads en Meta. Dat is achteraf lastiger te herstellen dan vooraf te voorkomen. Doe je het in twee fasen, dan meet en schrijf je je aankopen weer volledig toe, dwars door in app browsers en cookiebanners heen.

Kom je hier zelf niet uit, of wil je liever dat wij dit voor je oppakken? Dan kan dat. Daarvoor kan je contact opnemen met partners@adpage.io voor een prijsvoorstel.