Skip to content

Instantly share code, notes, and snippets.

@it-can
Last active May 26, 2026 14:40
Show Gist options
  • Select an option

  • Save it-can/188acc89637160d21ab9a37e1bbf0b2c to your computer and use it in GitHub Desktop.

Select an option

Save it-can/188acc89637160d21ab9a37e1bbf0b2c to your computer and use it in GitHub Desktop.
Cloudflare Zaraz Google Ads conversion tracking with "enhanced conversions"
<script>
var user_data_info = {
sha256_email_address: '{{ normalizeAndHashEmailAddress($invoice->email) }}',
sha256_phone_number: '{{ normalizeAndHash(formatPhoneE164($invoice->billing_telephone)) }}',
address: {
sha256_first_name: '{{ normalizeAndHash($firstname ?? '') }}',
sha256_last_name: '{{ normalizeAndHash($lastname ?? '') }}',
sha256_street: '{{ normalizeAndHash($invoice->billing_address . ' ' . $invoice->billing_address_nr) }}',
postal_code: '{{ $invoice->billing_zipcode }}',
city: '{{ $invoice->billing_city }}',
country: '{{ $invoice->billing_country }}',
new_customer: {{ $new_customer ? 'true' : 'false' }}
}
};
// Google Ads conversion tracking
zaraz.track("conversion", {
transaction_id: "ORDER ID",
value: AMOUNT
currency: 'EUR',
user_data: JSON.stringify(user_data_info)
});
</script>
<?php
if (! function_exists('formatPhoneE164')) {
/**
* Format phonenumber to E164 (i use this library https://github.com/Propaganistas/Laravel-Phone)
*
*
* @return mixed|string
*/
function formatPhoneE164($value)
{
$value = Str::lower(trim($value));
try {
return (new PhoneNumber($value, 'NL'))
->formatE164();
} catch (Exception $e) {
}
return $value;
}
}
if (! function_exists('normalizeAndHash')) {
function normalizeAndHash(string $value, bool $trimIntermediateSpaces = false): string
{
// Normalizes by first converting all characters to lowercase, then trimming spaces.
$normalized = strtolower($value);
if ($trimIntermediateSpaces) {
// Removes leading, trailing, and intermediate spaces.
$normalized = str_replace(' ', '', $normalized);
} else {
// Removes only leading and trailing spaces.
$normalized = trim($normalized);
}
return hash('sha256', strtolower(trim($normalized)));
}
}
if (! function_exists('normalizeAndHashEmailAddress')) {
function normalizeAndHashEmailAddress(string $emailAddress): string
{
$normalizedEmail = strtolower($emailAddress);
$emailParts = explode('@', $normalizedEmail);
if (count($emailParts) > 1 && preg_match('/^(gmail|googlemail)\.com\s*/', $emailParts[1])) {
// Removes any '.' characters from the portion of the email address before the domain
// if the domain is gmail.com or googlemail.com.
$emailParts[0] = str_replace('.', '', $emailParts[0]);
$normalizedEmail = sprintf('%s@%s', $emailParts[0], $emailParts[1]);
}
return normalizeAndHash($normalizedEmail, true);
}
}
@JohJohan

Copy link
Copy Markdown

I was finally able to get it working by adding the hashed keys before my values see:

$userData = [
            'em'                             => 'tv.1~em.'.$this->hashedEmailAddress,
            'sha256_email_address'           => 'tv.1~em.'.$this->hashedEmailAddress,
            'user_data.sha256_email_address' => 'tv.1~em.'.$this->hashedEmailAddress,
        ];

        if (null !== $this->hashedFirstName) {
            $userData['fn']                                  = 'tv.1~fn.'.$this->hashedFirstName;
            $userData['address.sha256_first_name']           = 'tv.1~fn.'.$this->hashedFirstName;
            $userData['user_data.address.sha256_first_name'] = 'tv.1~fn.'.$this->hashedFirstName;
        }

        if (null !== $this->hashedLastName) {
            $userData['ln']                                 = 'tv.1~ln.'.$this->hashedLastName;
            $userData['address.sha256_last_name']           = 'tv.1~ln.'.$this->hashedLastName;
            $userData['user_data.address.sha256_last_name'] = 'tv.1~ln.'.$this->hashedLastName;
        }

        if (null !== $this->hashedPhoneNumber) {
            $userData['pn']                            = 'tv.1~pn.'.$this->hashedPhoneNumber;
            $userData['sha256_phone_number']           = 'tv.1~pn.'.$this->hashedPhoneNumber;
            $userData['user_data.sha256_phone_number'] = 'tv.1~pn.'.$this->hashedPhoneNumber;
        }

In the end i dont know which key makes it work found the info here: https://www.semetis.com/en/resources/articles/how-to-debug-google-enhanced-conversions-implementation#:~:text=If%20the%20em%20parameter%20is%20present%20but%20looks%20like%20%E2%80%9Ctv.1~em.%E2%80%9D%20then%20you%E2%80%99re%20sending%20the%20enhanced%20conversion%20parameter%20but%20it%E2%80%99s%20empty. goodluck!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment