'Januar','02' => 'Februar','03' => 'März','04' => 'April','05' => 'Mai','06' => 'Juni', '07' => 'Juli','08' => 'August','09' => 'September','10' => 'Oktober','11' => 'November','12' => 'Dezember', ]; $EUD_promoDateDe = $tomorrow->format('d') . '. ' . ($monateDe[$tomorrow->format('m')] ?? '') . ' ' . $tomorrow->format('Y'); /* ================== HELPERS ================== */ if (!function_exists('eud_p')) { function eud_p(string $k, $default=null){ return isset($_POST[$k]) && $_POST[$k] !== '' ? trim((string)$_POST[$k]) : $default; } } if (!function_exists('eud_g')) { function eud_g(string $k, $default=null){ return isset($_GET[$k]) && $_GET[$k] !== '' ? trim((string)$_GET[$k]) : $default; } } if (!function_exists('eud_utm')) { function eud_utm(string $k){ return eud_p($k, eud_g($k)); } } if (!function_exists('eud_ipToBinary')) { function eud_ipToBinary(?string $ip): ?string { if(!$ip) return null; $bin = @inet_pton($ip); return $bin === false ? null : $bin; } } if (!function_exists('eud_statusMap')) { function eud_statusMap(?string $raw): ?string { if ($raw === null) return null; $raw = strtolower($raw); return match($raw){ 'none' => 'pending', 'confirm','approved','ok','success' => 'approved', 'decline','reject','rejected','error','failed' => 'rejected', default => null }; } } if (!function_exists('eud_detectDevice')) { function eud_detectDevice(string $ua): string { $uaL = strtolower($ua); $isMobile = (str_contains($uaL,'mobile') || str_contains($uaL,'android') || str_contains($uaL,'iphone')); $os = (str_contains($uaL,'android')?'Android' :(str_contains($uaL,'iphone')||str_contains($uaL,'ipad')?'iOS' :(str_contains($uaL,'windows')?'Windows' :(str_contains($uaL,'mac os')?'macOS':'Other')))); $br = (str_contains($uaL,'edg')?'Edge' :(str_contains($uaL,'chrome')?'Chrome' :(str_contains($uaL,'firefox')?'Firefox' :(str_contains($uaL,'safari')?'Safari':'Browser')))); return ($isMobile?'Mobile':'Desktop') . " | {$os} | {$br}"; } } /** * ✅ Telefonnormalisierung für Deutschland nach Offer-Anforderungen: * Format: +49 und 10-11 Ziffern (lokaler Teil) * Rückgabe: * - digits: "49XXXXXXXXXX" (12-13 Ziffern) * - e164: "+49XXXXXXXXXX" */ if (!function_exists('eud_normalizePhoneDE')) { function eud_normalizePhoneDE(string $raw): ?array { $digits = preg_replace('~\D+~', '', $raw); if ($digits === '') return null; if (str_starts_with($digits, '00')) $digits = substr($digits, 2); // Erlauben wir Eingabe "49XXXXXXXXXX" oder "0XXXXXXXXXX" if (str_starts_with($digits, '49')) { $local = substr($digits, 2); } elseif (str_starts_with($digits, '0')) { $local = substr($digits, 1); } else { $local = $digits; } // Deutsche Nummern: 10-11 Ziffern im lokalen Teil if (strlen($local) < 10 || strlen($local) > 11) return null; $d = '49' . $local; return ['digits' => $d, 'e164' => '+' . $d]; } } /** * Fehlerfreie Weiterleitung */ if (!function_exists('eud_redirect')) { function eud_redirect(string $url, int $code = 302): void { if (!headers_sent()) { header('Location: ' . $url, true, $code); exit; } $safeUrl = htmlspecialchars($url, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); echo '
'; echo ''; echo ''; echo ''; exit; } } /* ================== POST-VERARBEITUNG (Lead-Formular) ================== */ $EUD_formError = null; if ($_SERVER['REQUEST_METHOD'] === 'POST' && eud_p('br_lead_form') === '1') { $name = eud_p('eud_name',''); $phone = eud_p('eud_phone',''); $sub1 = eud_p('sub1', eud_utm('sub1')); $sub2 = eud_p('sub2', eud_utm('sub2')); $sub3 = eud_p('sub3', eud_utm('sub3')); $sub4 = eud_p('sub4', eud_utm('sub4')); $sub5 = eud_p('sub5', eud_utm('sub5')); $campaign = eud_p('utm_campaign', eud_utm('utm_campaign')); $keyword = eud_p('utm_term', eud_utm('utm_term')); $matchtype = eud_p('utm_matchtype', eud_utm('utm_matchtype')); $ipStr = $_SERVER['HTTP_X_FORWARDED_FOR'] ?? $_SERVER['REMOTE_ADDR'] ?? null; if ($ipStr && str_contains($ipStr, ',')) { $ipStr = trim(explode(',', $ipStr)[0]); } $ipBin = eud_ipToBinary($ipStr); $ua = $_SERVER['HTTP_USER_AGENT'] ?? '-'; $device = eud_detectDevice($ua); $referrer = $_SERVER['HTTP_REFERER'] ?? null; // honeypot if (eud_p('website')) { eud_redirect($EUD_SUCCESS_REDIRECT); } // ✅ Deutschland: normalisieren (ideal: +49 + 10-11 Ziffern), aber immer weiterleiten $phoneNormArr = null; if ($phone !== '') $phoneNormArr = eud_normalizePhoneDE($phone); $phoneForShakes = $phoneNormArr['e164'] ?? $phone; $phoneNormDigits = $phoneNormArr['digits'] ?? null; $leadId = null; try { // 1) Schreiben in CRM (leads_tracker) try { $trackerPdo = new PDO($EUD_CRM_DSN, $EUD_CRM_USER, $EUD_CRM_PASS, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); $sqlLead = " INSERT INTO leads_tracker (created_at, campaign_name, campaign_id, keyword, matchtype, lead_name, lead_phone, payout, status) VALUES (NOW(), :campaign_name, :campaign_id, :keyword, :matchtype, :lead_name, :lead_phone, :payout, :status) "; $stmtLead = $trackerPdo->prepare($sqlLead); $stmtLead->execute([ ':campaign_name' => $campaign, ':campaign_id' => '', ':keyword' => $keyword, ':matchtype' => $matchtype, ':lead_name' => $name, ':lead_phone' => $phone, ':payout' => 0, ':status' => 'pending', ]); $leadId = (int)$trackerPdo->lastInsertId(); } catch (Throwable $dbEx) { @file_put_contents(__DIR__ . '/tracker.error.log', date('Y.m.d H:i:s') . ' DB insert error (leads_tracker): ' . $dbEx->getMessage() . PHP_EOL, FILE_APPEND ); } $sub1ForShakes = $leadId ?: $sub1; $sub2ForShakes = $campaign; $sub3ForShakes = $keyword; $sub4ForShakes = $matchtype; // 2) Log in shakes_conversions + Versand an Shakes $pdo = new PDO( "mysql:host={$EUD_DB_HOST};dbname={$EUD_DB_NAME};charset=utf8mb4", $EUD_DB_USER, $EUD_DB_PASS, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ] ); $sql = "INSERT INTO shakes_conversions (campaign, keyword, matchtype, offer_id, stream_code, name, phone, email, ip, country, sub1, sub2, sub3, sub4, device, user_agent) VALUES (:campaign, :keyword, :matchtype, :offer_id, :stream_code, :name, :phone, :email, :ip, :country, :sub1, :sub2, :sub3, :sub4, :device, :user_agent)"; $st = $pdo->prepare($sql); $st->bindValue(':campaign', $campaign); $st->bindValue(':keyword', $keyword); $st->bindValue(':matchtype', $matchtype); $st->bindValue(':offer_id', $EUD_offerId); $st->bindValue(':stream_code', $EUD_streamCode); $st->bindValue(':name', $name); $st->bindValue(':phone', $phone); $st->bindValue(':email', null, PDO::PARAM_NULL); if ($ipBin===null) $st->bindValue(':ip', null, PDO::PARAM_NULL); else $st->bindValue(':ip',$ipBin, PDO::PARAM_LOB); $st->bindValue(':country', 'DE'); $st->bindValue(':sub1', (string)$sub1ForShakes); $st->bindValue(':sub2', (string)$sub2ForShakes); $st->bindValue(':sub3', (string)$sub3ForShakes); $st->bindValue(':sub4', (string)$sub4ForShakes); $st->bindValue(':device', $device); $st->bindValue(':user_agent', $ua); $st->execute(); $localId = (int)$pdo->lastInsertId(); $shakesUrl = "http://{$EUD_SHAKES_DOMAIN}?r=/api/order/in&key={$EUD_SHAKES_API_KEY}"; $orderPayload = [ 'createdAt' => date('Y-m-d H:i:s'), 'offerId' => $EUD_offerId, 'landingUrl' => $EUD_landingUrl, 'streamCode' => $EUD_streamCode, 'ip' => $ipStr, 'referrer' => $referrer, 'userAgent' => $ua, 'name' => $name, 'phone' => $phoneForShakes, // ✅ +49XXXXXXXXXX 'countryCode' => 'DE', 'comment' => 'product=Balancio', 'sub1' => (string)$sub1ForShakes, 'sub2' => (string)$sub2ForShakes, 'sub3' => (string)$sub3ForShakes, 'sub4' => (string)$sub4ForShakes, ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $shakesUrl); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $orderPayload); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $responseBody = curl_exec($ch); $curlErr = curl_error($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); @file_put_contents(__DIR__ . '/shakes.response.log', sprintf( "[%s] Balancio DE | HTTP %s | payload=%s | body=%s | err=%s\n", date('Y-m-d H:i:s'), (string)$httpcode, json_encode($orderPayload,JSON_UNESCAPED_UNICODE), (string)$responseBody, (string)$curlErr ), FILE_APPEND); if ($responseBody !== false && $responseBody !== '') { $resp = json_decode($responseBody, true); if (is_array($resp)) { $statusRaw = $resp['status'] ?? null; $convId = $resp['id'] ?? null; $statusNorm = eud_statusMap($statusRaw); $upd = $pdo->prepare("UPDATE shakes_conversions SET conversion_id=:cid, status_raw=:sr, status=:sn WHERE id=:id"); $upd->bindValue(':cid', $convId); $upd->bindValue(':sr', (string)$statusRaw); $upd->bindValue(':sn', $statusNorm); $upd->bindValue(':id', $localId, PDO::PARAM_INT); $upd->execute(); } } // 3) Email-Benachrichtigung try { $hostForFrom = parse_url($EUD_landingUrl, PHP_URL_HOST) ?: 'balancio-de.com'; $fromEmail = 'no-reply@'.$hostForFrom; $subject = 'Neuer Lead (Balancio Deutschland) – '.$name.' / '.$phone; $lines = [ 'Neuer Lead von der Balancio-Seite (Deutschland)', '----------------------', 'Datum/Zeit: '.date('Y-m-d H:i:s'), 'Local ID (shakes_conversions.id): '.$localId, 'Lead ID (leads_tracker.id / sub1): '.($sub1ForShakes ?: '-'), 'Name: '.$name, 'Telefon (Eingabe): '.$phone, 'Telefon normalisiert digits (49+): '.($phoneNormDigits ?: '-'), 'Telefon gesendet an Shakes (E.164): '.$phoneForShakes, 'Land: DE', 'Campaign: '.$campaign, 'Keyword: '.$keyword, 'Matchtype: '.$matchtype, 'Sub2 (utm_campaign): '.$sub2ForShakes, 'Sub3 (utm_term): '.$sub3ForShakes, 'Sub4 (utm_matchtype): '.$sub4ForShakes, 'Sub5 (nur Log): '.$sub5, 'IP: '.$ipStr, 'Device: '.$device, 'UA: '.$ua, 'Referrer: '.$referrer, 'Landing: '.$EUD_landingUrl, '', 'Shakes HTTP code: '.$httpcode, 'Shakes-Antwort (raw):', (string)$responseBody, ]; $mailBody = implode("\r\n", $lines); $headers = "MIME-Version: 1.0\r\n". "Content-Type: text/plain; charset=UTF-8\r\n". "From: Balancio <{$fromEmail}>\r\n"; @mail($EUD_notifyEmail, '=?UTF-8?B?'.base64_encode($subject).'?=', $mailBody, $headers); } catch (Throwable $mailErr) { @file_put_contents(__DIR__.'/mail.error.log', date('Y.m.d H:i:s').' '.$mailErr->getMessage().PHP_EOL, FILE_APPEND); } eud_redirect($EUD_SUCCESS_REDIRECT); } catch (Throwable $e) { @file_put_contents(__DIR__.'/order.error.log', date('Y.m.d H:i:s').' '.$e->getMessage().PHP_EOL.$e->getTraceAsString().PHP_EOL, FILE_APPEND ); eud_redirect($EUD_SUCCESS_REDIRECT); } } /* ====== TEXTE (minimal + SEO) ====== */ $heroPriceNow = $heroPriceNow ?? '39€'; $heroPriceOld = $heroPriceOld ?? '78€'; $heroDiscountPill = $heroDiscountPill ?? 'HEUTE 50% SPAREN!'; $heroTopPill = $heroTopPill ?? 'OFFIZIELLE BALANCIO WEBSEITE'; $heroTitleLine1 = $heroTitleLine1 ?? 'Balancio,'; $heroTitleLine2 = $heroTitleLine2 ?? 'die wirksame Creme gegen'; $heroTitleAccent = $heroTitleAccent ?? 'Gelenkschmerzen.'; $heroSubtitle = $heroSubtitle ?? 'Balancio ist ein Gel zur Linderung von Gelenkschmerzen.