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

מדידת begin_checkout ב-WooCommerce

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

אחרי הרכישה, השלב הבא במשפך הוא תחילת הצ'קאאוט. אירוע begin_checkout מראה מי הגיע לצ'קאאוט אבל לא סיים, בדיוק המקום שבו הרבה עסקאות אובדות. נוסיף אותו ל-WooCommerce עם קוד אמיתי להעתקה, והסבר בעברית לכל שלב.

חדש כאן? מומלץ להתחיל במפת הארכיטקטורה, שמציגה את כל שכבות המדידה במבט אחד לפני שנכנסים למימוש.
חשוב לדעת: הקוד במדריך נכתב לפי ה-API הרשמי של WordPress ו-WooCommerce, ונבדק על התקנה סטנדרטית. אתרים עם Checkout Blocks, תבניות מותאמות, הרחבות מסחר או תוספי צד שלישי עשויים לדרוש התאמות. השתמשו בקוד כבסיס ליישום, לא כהבטחה שהוא יתאים לכל אתר ללא שינויים. לפני הטמעה באתר חי, בדקו בסביבת פיתוח או ב-Staging.
איפה אנחנו נמצאים במערכת · פרק 15 מתוך 20
אתרמדידהניהול לידיםאוטומציהעסקהOffline Conversionלמידת האלגוריתם
מסלול קריאה מומלץ: Data Layerרכישהצ׳קאאוט (יישום) (כאן)
רמת קושיבינוני
זמן יישוםכ-15 דקות
נבדק עםWordPress 6.x · WooCommerce 9.x · PHP 8.2+
תואםClassic Checkout בלבד
לא תואםCart & Checkout Blocks
ידע נדרשPHP בסיסי · GTM · GA4
עודכןאוגוסט 2026
בקצרה: הקוד נתלה על woocommerce_before_checkout_form, בונה ב-PHP את אירוע begin_checkout מתוך WC()->cart (value דרך get_totals, קופון, item_variant ו-event_id), ודוחף אותו ל-dataLayer. הנתונים מוכנים בשרת, אבל האירוע עצמו נשלח מהדפדפן. ל-Checkout קלאסי בלבד.

למה begin_checkout חשוב?

רוב העגלות שננטשות אף פעם לא מגיעות לשלב הרכישה. אירוע begin_checkout מאפשר לראות כמה משתמשים התחילו את תהליך התשלום, לחשב את שיעור הנטישה בין הצ'קאאוט לרכישה, ולבנות קהלי רימרקטינג של משתמשים שהיו קרובים מאוד לקנייה. בלי המדידה הזו רואים רק מי קנה, לא מי כמעט קנה.

לפני שמתחילים: דיוק, ו-Classic בלבד

זו לא באמת מדידה בצד השרת. הקוד בונה את הנתונים ב-PHP בזמן טעינת עמוד הצ'קאאוט, אבל האירוע עצמו נשלח מהדפדפן (דחיפה ל-dataLayer). מדידה server-side אמיתית שולחת את האירוע שרת-לשרת בלי תלות בדפדפן (Measurement Protocol, Server GTM, CAPI), ולזה נגיע במדריכים הבאים.

⚠️ המדריך הזה מיועד ל-Classic Checkout בלבד. Cart & Checkout Blocks אינו משתמש בתבניות ה-PHP של ה-Classic Checkout, ולכן ה-hook woocommerce_before_checkout_form אינו מופעל, והקוד לא ירוץ. ל-Blocks נדרש מימוש שונה.

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

  • Checkout קלאסי של WooCommerce (לא Blocks).
  • הושלם כבר מדידת purchaseמדריך הראשון), GTM ו-GA4 מחוברים.
  • גישה ל-functions.php של Child Theme או תוסף Code Snippets.

1הקוד: begin_checkout

הקוד נתלה על woocommerce_before_checkout_form, קורא את תוכן העגלה דרך WC()->cart, ובונה את האירוע. הוא כולל שומרים דפנסיביים (function_exists('WC'), is_admin, is_checkout), חישוב value דרך WooCommerce, ו-event_id יציב לשימוש עתידי במטא:

functions.php (Child Theme) או Code Snippet
add_action( 'woocommerce_before_checkout_form', 'doffice_ga4_begin_checkout', 20 );

/**
 * Assembles a GA4 "begin_checkout" event in PHP at checkout page load,
 * then prints an inline script that pushes it to the dataLayer.
 * The DATA is built server-side, but the EVENT itself fires in the browser.
 * This guide targets the CLASSIC checkout only (not Cart & Checkout Blocks).
 */
function doffice_ga4_begin_checkout() {
    // Bail if WooCommerce isn't active, or we're in the admin.
    if ( ! function_exists( 'WC' ) || is_admin() ) {
        return;
    }
    // Run only on the front-end checkout page.
    if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
        return;
    }
    if ( ! WC()->cart || WC()->cart->is_empty() ) {
        return;
    }

    $items = array();

    foreach ( WC()->cart->get_cart() as $cart_item ) {
        $product    = $cart_item['data'];
        $product_id = $cart_item['product_id'];
        $qty        = max( 1, (int) $cart_item['quantity'] );
        $categories = wp_get_post_terms( $product_id, 'product_cat', array( 'fields' => 'names' ) );

        // line_total is the price AFTER discounts (what the customer actually pays).
        $line_total = (float) $cart_item['line_total'];

        $item = array(
            'item_id'       => $product->get_sku() ? $product->get_sku() : (string) $product_id,
            'item_name'     => $product->get_name(),
            'item_category' => ! empty( $categories ) ? $categories[0] : '',
            // GA4 expects the PER-UNIT price (before multiplying by quantity).
            'price'         => round( $line_total / $qty, 2 ),
            'quantity'      => $qty,
        );

        // item_variant is sent ONLY for variable products.
        if ( $product->is_type( 'variation' ) ) {
            $item['item_variant'] = wc_get_formatted_variation( $product, true );
        }

        // item_brand (OPTIONAL). "product_brand" is NOT built into WooCommerce; it
        // comes from a brands plugin (WooCommerce Brands / Perfect Brands / YITH...).
        // Change the taxonomy name below if your store uses a different one.
        $brands = wp_get_post_terms( $product_id, 'product_brand', array( 'fields' => 'names' ) );
        if ( ! is_wp_error( $brands ) && ! empty( $brands ) ) {
            $item['item_brand'] = $brands[0];
        }

        $items[] = $item;
    }

    // Let WooCommerce compute the total. It already handles tax, shipping, fees,
    // coupons, compound tax and currency switchers, so we don't add them by hand.
    $totals = WC()->cart->get_totals();

    $ecommerce = array(
        'currency' => get_woocommerce_currency(),   // store currency, ISO 4217 (e.g. "ILS")
        'value'    => round( (float) $totals['total'], 2 ),
        'items'    => $items,
    );

    // Applied coupon(s), if any.
    $coupons = WC()->cart->get_applied_coupons();
    if ( ! empty( $coupons ) ) {
        $ecommerce['coupon'] = implode( ', ', $coupons );
    }

    // Stable event_id for later Meta Pixel + CAPI deduplication (GA4 ignores it).
    // Tied to the customer + cart state, so it stays stable while the cart is unchanged.
    $event_id = 'checkout_' . md5( WC()->session->get_customer_id() . WC()->cart->get_cart_hash() );

    $datalayer = array(
        'event'     => 'begin_checkout',
        'event_id'  => $event_id,
        'ecommerce' => $ecommerce,
    );

    echo '<script>';
    echo 'window.dataLayer = window.dataLayer || [];';
    echo 'window.dataLayer.push({ ecommerce: null });';
    echo 'window.dataLayer.push(' . wp_json_encode( $datalayer ) . ');';
    echo '</script>';
}

שימו לב לכמה דיוקים: value מגיע מ-get_totals()['total'], כלומר WooCommerce מחשב את הסכום הסופי (כולל מס, משלוח, עמלות, קופונים ומס מורכב) במקום חישוב ידני שעלול לסטות בשקל; price של כל פריט הוא המחיר ליחידה אחרי הנחות (line_total חלקי הכמות, מעוגל ל-2 ספרות); ו-item_variant נשלח רק עבור מוצרים משתנים, דרך הפונקציה הרשמית wc_get_formatted_variation.

item_brand הוא אופציונלי. הטקסונומיה product_brand בקוד היא דוגמה, היא אינה חלק מובנה של WooCommerce אלא מגיעה מתוסף מותגים (WooCommerce Brands, Perfect Brands, YITH ואחרים). אם החנות משתמשת בטקסונומיית מותג אחרת, התאימו את השם בקוד.

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

2לחבר את זה ב-GTM

אותה שיטה כמו ברכישה: טריגר Custom Event בשם begin_checkout, ותגית GA4 Event עם אותו שם, Send Ecommerce data מ-Data Layer, מחוברת לטריגר. אם כבר יש משתנה ecommerce ממדריך הרכישה, הוא משמש גם כאן. שומרים ו-Publish.

3אימות ו-Debug

נכנסים לעמוד הצ'קאאוט, ובקונסול מסננים את האירוע:

Console, בעמוד הצ'קאאוט
window.dataLayer.filter(e => e.event === "begin_checkout")

// Expected on the checkout page:
[
  {
    event: "begin_checkout",
    event_id: "checkout_9f8e7d6c5b4a...",
    ecommerce: {
      currency: "ILS",
      value: 712.40,
      coupon: "WELCOME10",
      items: [
        { item_id: "SKU-1", item_name: "...", price: 349.90, quantity: 2, item_variant: "Color: Blue, Size: L" }
      ]
    }
  }
]

ואז מוודאים ב-GA4 DebugView שהאירוע נכנס עם items, value ו-currency תקינים.

מלכודות נפוצות

  • Cart & Checkout Blocks, שבהם ה-hook לא מופעל והקוד לא ירוץ.
  • line_subtotal במקום line_total למחיר הפריט, שמתעלם מקופונים.
  • חישוב value ידני שמפספס עמלות, מס מורכב או Currency Switcher, במקום get_totals().
  • מטבע כסימן (₪) במקום קוד ISO (ILS).

איפה זה במסלול, ומה הלאה

begin_checkout הוא החוליה האמצעית במשפך המסחר:

add_to_cart
begin_checkout
purchase

add_to_cart יקבל מדריך נפרד ומעמיק, כי הוא האירוע שהכי משתנה בין חנויות: יש עשרות דרכים להוסיף מוצר לעגלה (עמוד קטגוריה, עמוד מוצר, Quick View, AJAX, Checkout Blocks, Elementor ובילדרים אחרים, תבנית מותאמת), וכל אחת דורשת מימוש אחר. הצגה של דרך אחת בלבד הייתה מטעה. בהמשך נוסיף גם view_item, ואת חיבור Meta Pixel + CAPI עם ה-event_id שכבר הכנו כאן.

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

begin_checkoutdataLayerwoocommerce_before_checkout_formWC()->cart->get_totals()Classic CheckoutCart & Checkout Blocksline_totalitem_variantitem_brandcouponevent_idGA4 DebugView
שאלות נפוצות

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

למה בכלל למדוד begin_checkout?
רוב העגלות שננטשות אף פעם לא מגיעות לרכישה. האירוע מאפשר לראות כמה משתמשים התחילו את התשלום, לחשב את שיעור הנטישה בין הצ'קאאוט לרכישה, ולבנות קהלי רימרקטינג של מי שהיה קרוב מאוד לקנייה.
זה באמת מדידה בצד השרת?
לא לגמרי. הנתונים נבנים ב-PHP בזמן טעינת עמוד הצ'קאאוט, אבל האירוע עצמו נשלח מהדפדפן (דחיפה ל-dataLayer). מדידה server-side אמיתית שולחת את האירוע שרת-לשרת בלי תלות בדפדפן (Measurement Protocol, Server GTM, CAPI).
האם זה עובד עם Cart & Checkout Blocks?
לא עם הקוד הזה. Checkout Blocks דורש מימוש שונה (הוא לא משתמש בתבניות ה-PHP של ה-Classic Checkout, ולכן ה-hook לא מופעל), ולכן המדריך הזה מתמקד ב-Classic Checkout בלבד.
איך מחושב ה-value?
דרך WC()->cart->get_totals()['total'], כך ש-WooCommerce מחשב את הסכום הסופי (מס, משלוח, עמלות, קופונים, מס מורכב) במקום חישוב ידני שעלול לסטות.
למה line_total ולא line_subtotal?
line_subtotal הוא לפני קופונים. line_total הוא אחרי, וזה המחיר שהלקוח באמת משלם, שאותו GA4 מצפה לקבל.
מאיפה מגיע item_brand?
מטקסונומיית מותג של תוסף (WooCommerce Brands / Perfect Brands / YITH ואחרים). product_brand בקוד היא דוגמה, לא חלק מובנה של WooCommerce, התאימו לשם הטקסונומיה שלכם.
למה יש event_id אם GA4 מתעלם ממנו?
כדי שבהמשך, כשנחבר את אותו אירוע ל-Meta Pixel ול-CAPI, יהיה מזהה יציב משותף לדדופליקציה. הוא מבוסס על מזהה הלקוח ומצב העגלה, כך שנשאר יציב כל עוד העגלה לא השתנתה. הפרטים במדריך Meta CAPI.
הפרק הבא · פרק 16 מתוך 20add_to_cart (Woo)למדוד הוספה לעגלה בכל ההקשרים

רוצים משפך מסחר מלא ומדויק?

נחבר את כל אירועי המסחר, מהוספה לעגלה ועד הרכישה, ל-GA4 ולמטא, בהתאמה לחנות שלכם (כולל Checkout Blocks), כדי שתראו בדיוק היכן הלקוחות נופלים.

בואו נדבר
כולל add_to_cart, begin_checkout ו-purchase, GTM, GA4, ו-Meta Pixel + CAPI עם Event ID.