בית › מרכז הידע › מדידה › מדריכי יישום
מדריך יישום · קודמתקדם

Meta Pixel + Conversions API

כך שולחים כל המרה פעמיים, וסופרים אותה פעם אחת

מדריך יישום · לקהל טכני · 14 דקות

שני ערוצי מדידה עדיפים על אחד, אבל רק אם Meta יודעת שמדובר באותה המרה. המדריך הזה מחבר את הפיקסל בדפדפן ואת ה-Conversions API בשרת דרך event_id משותף, כך שכל רכישה נשלחת פעמיים ונספרת פעם אחת. זה השלב שבו כל אירועי המסחר מתחברים למדידה מלאה, בדפדפן ובשרת.

חדש כאן? מומלץ להתחיל במפת הארכיטקטורה, שמציגה את כל שכבות המדידה במבט אחד לפני שנכנסים למימוש.
חשוב לדעת: הקוד במדריך נכתב לפי ה-API הרשמי של Meta ו-WooCommerce, ונבדק על התקנה סטנדרטית. גרסת ה-Graph API מתעדכנת מעת לעת, וכללי הנרמול וה-hashing של Meta מדויקים מאוד (רווח או אות גדולה שוברים התאמה). השתמשו בקוד כבסיס ליישום, לא כהבטחה שהוא יתאים לכל אתר ללא שינויים. לפני הטמעה באתר חי, בדקו ב-Test Events ובסביבת פיתוח.
איפה אנחנו נמצאים במערכת · פרק 17 מתוך 20
אתרמדידהניהול לידיםאוטומציהעסקהOffline Conversionלמידת האלגוריתם
מסלול קריאה מומלץ: Server-Side GTMCAPIMeta CAPI (יישום) (כאן)
רמת קושימתקדם
זמן יישוםכ-40 דקות
נבדק עםWooCommerce 9.x · PHP 8.2+ · Graph API v21.0
תואםPixel + CAPI עם event_id משותף
לא תואםevent_id שונה בין הערוצים (שובר דדופליקציה)
ידע נדרשPHP · Meta Events Manager · GTM
עודכןאוגוסט 2026
בקצרה: מריצים Meta Pixel בדפדפן ו-Conversions API בשרת במקביל. שניהם שולחים את אותו אירוע (Purchase) עם אותו event_id (מבוסס מזהה ההזמנה). Meta מזהה את ההתאמה תוך 48 שעות ומדדפת, כך שמקבלים את החוסן של השרת בלי ספירה כפולה, ומקבלים תמונה מלאה יותר של ההמרות שאבדו במדידת הדפדפן בלבד.

למה Pixel לבד לא מספיק, ומה CAPI פותר

הפיקסל של Meta רץ בדפדפן, ולכן הוא הדבר הראשון שנשבר: חוסמי פרסומות, הגבלות iOS, וסירוב לעוגיות משאירים חלק מההמרות בחוץ. Conversions API (CAPI) שולח את אותן המרות מהשרת, במסלול שלא נחסם. הרעיון של 2026 הוא להריץ את שניהם יחד, ולדדפ ביניהם.

אבל אם שולחים את אותה רכישה גם מהדפדפן וגם מהשרת, Meta עלולה לספור אותה פעמיים. הפתרון הוא event_id משותף:

Meta Pixel · דפדפן
אירוע: Purchase
event_id = order_123
Conversions API · שרת
אירוע: Purchase
event_id = order_123
Meta מזהה שמדובר באותה רכישהevent_name + event_id זהים
ההמרה נספרת פעם אחת
שימו לב: בכל אחד ממדריכי המסחר יצרנו event_id יציב. עכשיו אפשר לראות למה, אותו מזהה עובר עם האירוע לאורך כל הדרך, ומאפשר לחבר בין הדפדפן לשרת בלי כפילויות. להעמקה בתפיסה: Facebook CAPI לעומק.

לפני שמתחילים

דרישות מקדימות

  • Dataset ID (מזהה הפיקסל) מ-Events Manager.
  • Access Token ל-CAPI עם הרשאת events_management (Events Manager ← Settings ← Conversions API ← Generate Access Token).
  • מדריך הרכישה מיושם, כך שקיים event_id בפורמט order_<id>.
  • מזהי הקליק (fbclid) נקלטים בנחיתה ל-_fbc, ו-_fbp נוצר על ידי הפיקסל.

1החלק בדפדפן: Pixel עם eventID

הפיקסל כבר שולח Purchase. הדבר היחיד שמוסיפים הוא eventID זהה למזהה ההזמנה, כדי ש-Meta תוכל לזהות אותו מול אירוע השרת:

בדפדפן, בעמוד אישור ההזמנה
<!-- בדפדפן, בעמוד אישור ההזמנה (Order Received). -->
<!-- ה-eventID חייב להיות זהה ל-event_id שהשרת שולח: 'order_' + מזהה ההזמנה. -->
<script>
  fbq('track', 'Purchase', {
    value: 349.90,
    currency: 'ILS',
    content_type: 'product',
    contents: [{ id: 'SKU-1', quantity: 1 }]
  }, { eventID: 'order_123' });
</script>

בהגדרת GTM, ה-eventID נלקח מה-dataLayer: order_ ועוד ה-transaction_id שמדריך הרכישה כבר דוחף. כך אין צורך לקודד מזהה ידנית.

2החלק בשרת: CAPI מ-PHP

עכשיו שולחים את אותה רכישה מהשרת, עם אותו event_id בדיוק. הכלל פשוט: מידע שמזהה אדם עובר גיבוב (hashed), ומידע טכני שמזהה את הביקור לא. לכן האימייל והטלפון מגובבים, ואילו fbp ו-fbc נשלחים גלמיים:

functions.php (Child Theme) או Code Snippet
/**
 * Send the same Purchase to Meta from the SERVER (Conversions API),
 * with the SAME event_id as the browser Pixel, so Meta deduplicates.
 */
add_action( 'woocommerce_thankyou', 'doffice_meta_capi_purchase', 20, 1 );

function doffice_meta_capi_purchase( $order_id ) {
    if ( ! $order_id ) {
        return;
    }
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }
    // Send once per order (guards against page refresh / duplicate hooks).
    if ( $order->get_meta( '_doffice_capi_sent' ) ) {
        return;
    }

    $dataset_id   = 'YOUR_DATASET_ID';         // = the Pixel ID
    $access_token = 'YOUR_CAPI_ACCESS_TOKEN';  // token with events_management permission
    $api_version  = 'v21.0';

    // SAME id as the browser Pixel and the purchase guide: order-based, unique per sale.
    $event_id = 'order_' . $order->get_id();

    // ---- user_data: HASH the PII (SHA-256, after normalizing); keep fbp/fbc/ip/ua RAW ----
    $user_data = array();

    if ( $order->get_billing_email() ) {
        $email = strtolower( trim( $order->get_billing_email() ) );      // normalize first
        $user_data['em'] = array( hash( 'sha256', $email ) );
    }
    if ( $order->get_billing_phone() ) {
        $phone = preg_replace( '/\D/', '', $order->get_billing_phone() ); // digits only, incl. country code
        $user_data['ph'] = array( hash( 'sha256', $phone ) );
    }
    // fbp / fbc come from cookies set on landing. NEVER hash them.
    if ( ! empty( $_COOKIE['_fbp'] ) ) {
        $user_data['fbp'] = sanitize_text_field( wp_unslash( $_COOKIE['_fbp'] ) );
    }
    if ( ! empty( $_COOKIE['_fbc'] ) ) {
        $user_data['fbc'] = sanitize_text_field( wp_unslash( $_COOKIE['_fbc'] ) );
    }
    $user_data['client_ip_address'] = $order->get_customer_ip_address();
    $user_data['client_user_agent'] = $order->get_customer_user_agent();

    // ---- custom_data ----
    $custom_data = array(
        'currency' => $order->get_currency(),
        'value'    => (float) $order->get_total(),
        'order_id' => (string) $order->get_id(),
    );

    // ---- the event ----
    $payload = array(
        'data' => array(
            array(
                'event_name'       => 'Purchase', // MUST match the Pixel event name exactly
                'event_time'       => time(),
                'event_id'         => $event_id,  // MUST match the Pixel eventID exactly
                'action_source'    => 'website',
                'event_source_url' => $order->get_checkout_order_received_url(),
                'user_data'        => $user_data,
                'custom_data'      => $custom_data,
            ),
        ),
    );

    $url = "https://graph.facebook.com/{$api_version}/{$dataset_id}/events?access_token={$access_token}";

    $response = wp_remote_post( $url, array(
        'headers' => array( 'Content-Type' => 'application/json' ),
        'body'    => wp_json_encode( $payload ),
        'timeout' => 10,
    ) );

    if ( is_wp_error( $response ) ) {
        error_log( 'D-Office CAPI error: ' . $response->get_error_message() );
        return;
    }
    if ( 200 === wp_remote_retrieve_response_code( $response ) ) {
        $order->update_meta_data( '_doffice_capi_sent', 1 );
        $order->save();
    } else {
        error_log( 'D-Office CAPI response: ' . wp_remote_retrieve_body( $response ) );
    }
}
חשוב: woocommerce_thankyou הוא פתרון מצוין ללמידה, אבל בחנות אמיתית עדיף לשלוח את האירוע מנקודת אישור התשלום (Webhook של שער הסליקה או שינוי Order Status), כדי לא להיות תלויים בכך שהלקוח יחזור לעמוד התודה. לקוח שסוגר את הדפדפן מיד אחרי התשלום לא תמיד יגיע לשם, ואירוע הדפדפן יאבד, וזו בדיוק ההמרה היקרה ביותר. כך זה נעשה בחנויות גדולות: האירוע מחובר לאישור התשלום עצמו, לא לעמוד התודה.

3לבדוק שהדדופליקציה עובדת

ב-Events Manager פותחים את Test Events, ומוסיפים זמנית את קוד הבדיקה ל-payload של השרת:

בדיקה בלבד
// While testing: add your Test Events code to the payload,
// then watch Events Manager -> Test Events in real time.
$payload['test_event_code'] = 'TESTXXXXX';

// A correctly deduplicated Purchase appears ONCE,
// marked as received from two sources: Browser and Server.

מבצעים רכישת בדיקה. אם הכל תקין, הרכישה מופיעה פעם אחת, מסומנת כמתקבלת משני מקורות: Browser ו-Server. אם היא מופיעה פעמיים, ה-event_id או ה-event_name לא זהים בין הערוצים.

גבולות ומלכודות

  • נרמול לפני גיבוב. אימייל באותיות קטנות ובלי רווחים, טלפון ספרות בלבד עם קידומת מדינה. אות גדולה או רווח אחד ישברו את ההתאמה בשקט, בלי שגיאה.
  • לא לגבב את fbp/fbc/IP/User-Agent. הם נשלחים גלמיים. גיבוב שלהם הורס את ההתאמה.
  • event_name זהה בדיוק. Purchase בדפדפן חייב להיות Purchase בשרת, כולל אותיות רישיות.
  • לא לעגן ב-woocommerce_thankyou בלבד אם חלק מהלקוחות לא חוזרים לאתר. עדיף אירוע צד-שרת מנקודת אישור התשלום.
  • לנעוץ גרסת API. Graph API מתעדכן; לבדוק את הגרסה מעת לעת ולעדכן את $api_version.
  • הסכמה. לשלוח את האירוע רק אם ניתנה הסכמה למדידה, בהתאם ל-Consent Mode ולבאנר העוגיות.

מה הלאה

אותו דפוס בדיוק עובד לכל אירועי המסחר, עם ה-event_id הייעודי של כל אחד:

Purchase
InitiateCheckout
AddToCart

ל-begin_checkout שולחים InitiateCheckout עם ה-event_id מבוסס-העגלה, ול-add_to_cart שולחים AddToCart, כל אחד עם ה-event_id שלו.

איפה אנחנו עכשיו: בנינו את שכבת המדידה למסחר אלקטרוני, מקצה לקצה. האירועים נשלחים ל-GA4, נשלחים גם ל-Meta, ומדווחים פעם אחת בלבד. הצעד המשלים הוא Enhanced Conversions ל-Google Ads, שיסגור את אותו מעגל מול גוגל בדיוק כמו מול Meta. מכאן ואילך העבודה היא בשיפור איכות הנתונים (EMQ, Consent Mode, ומדידה בצד השרת עם Server GTM), לא בהוספת אירועים נוספים.

מושגים שהוזכרו במדריך

Meta PixelConversions API (CAPI)event_idevent_nameדדופליקציהfbpfbcEMQ (Event Match Quality)SHA-256action_sourceDataset IDGraph API
שאלות נפוצות

שאלות ותשובות על היישום

למה בכלל צריך גם Pixel וגם CAPI?
הפיקסל בדפדפן נחסם לעיתים (חוסמי פרסומות, הגבלות iOS, סירוב עוגיות). CAPI נשלח מהשרת ולא נחסם. שילוב של שניהם, עם דדופליקציה, מחזיר חלק משמעותי מההמרות שאבדו במדידת הדפדפן בלבד, בלי לספור פעמיים.
איך הדדופליקציה עובדת בפועל?
Meta מקבלת את אותה המרה משני ערוצים. אם שני האירועים חולקים בדיוק אותו event_name (למשל Purchase) ואותו event_id, ומגיעים בתוך 48 שעות, Meta שומרת אחד ומשמיטה את הכפילות.
מה חייב להיות ה-event_id?
מזהה ייחודי לאותה המרה, לא למשתמש. לרכישה, מזהה ההזמנה מושלם (יציב, קיים בשני הצדדים). את אותו מזהה בדיוק שולחים גם מהפיקסל וגם מה-CAPI. אסור לייצר מזהים אקראיים שונים בכל ערוץ.
מה יקרה אם ה-event_id לא יהיה זהה בין הערוצים?
Meta תראה את שני האירועים כשתי המרות נפרדות, ותספור את אותה רכישה פעמיים. זו אחת הטעויות הנפוצות ביישום, ולכן ה-event_id חייב להיות זהה לחלוטין בפיקסל וב-CAPI.
מה מגבבים ומה לא?
מגבבים (SHA-256, אחרי נרמול) את הפרטים המזהים: אימייל, טלפון. לא מגבבים את fbp, fbc, כתובת IP ו-user agent, הם נשלחים גלמיים. רווח מיותר או אות גדולה לפני גיבוב ישברו את ההתאמה בשקט.
מאיפה מגיעים fbp ו-fbc?
הפיקסל יוצר את עוגיית _fbp, ואת _fbc הוא בונה ממזהה הקליק fbclid בפורמט fb.1.. בנחיתה מהמודעה. השרת קורא אותם מהעוגיות ושולח כפי שהם. ככל שיש יותר מזהים, ה-EMQ עולה.
אפשר לתת ל-Meta להקים את זה לבד?
למטא יש היום אפשרות של CAPI בלחיצה אחת, שמקימה את צד השרת ומסנכרנת event_id אוטומטית. זה נוח, אבל נותן פחות שליטה על הנתונים ועל האיכות. המדריך מראה את המימוש הידני, שנותן שליטה מלאה.
הפרק הבא · פרק 18 מתוך 20המרות משופרות בגוגללהטמיע Enhanced Conversions נכון

רוצים מדידה שלמה, בלי ספירה כפולה?

נחבר לכם את הפיקסל וה-CAPI עם דדופליקציה נכונה, נחזק את איכות ההתאמה (EMQ), ונוודא שכל המרה נספרת פעם אחת, בדפדפן ובשרת גם יחד.

בואו נדבר
כולל Pixel, CAPI, event_id משותף, fbp/fbc, ו-GTM/Server-Side.