wordpress_woocommerce_deep_guides 29/03/2026 4 דק׳ קריאה

איך להוסיף שדות לעמוד לתשלום בווקומרס

פבלו רותם · 0 תגובות

איך להוסיף שדות לעמוד לתשלום בווקומרס

איך להוסיף שדות לעמוד לתשלום בווקומרס

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

קודם תחליט למה השדה קיים ומהו סוג הנתון

טעות של הרבה מפתחים היא להתחיל מ-snippet לפני שמבינים מה הנתון. האם אתה מבקש מספר ח.פ.? תאריך אספקה? הערת גישה לשליח? בחירת אריזה? מזהה לקוח חיצוני? כל אחד מהשדות האלו דורש מבנה אחר: text, select, checkbox, date או textarea. ככל שתהיה מדויק יותר בהגדרת הנתון, כך גם האימות, השמירה וה-UX יהיו טובים יותר.

אני ממליץ לכתוב לעצמך specification קצר: שם השדה, מזהה פנימי, חובה או רשות, כללי אימות, מיקום ב-checkout, והאם צריך להציג אותו במיילים או בממשק המנהל. ככה אתה מפתח כמו איש מוצר ולא כמו מי שזורק snippet חד-פעמי.

הוספת שדה חדש בדרך הקלאסית

הדרך הקלאסית להוסיף שדה checkout היא דרך הפילטר woocommerce_checkout_fields. זו עדיין דרך יעילה מאוד כאשר האתר שלך משתמש ב-legacy checkout. הנה דוגמה מסודרת:

<?php
/**
 * הוספת שדה מותאם לעמוד התשלום בווקומרס.
 *
 * Author: pablo rotem
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * מוסיף שדה מספר ח.פ. לאזור billing.
 *
 * @author pablo rotem
 */
function pablo_rotem_add_checkout_fields( array $fields ): array {
    $fields['billing']['billing_company_id'] = array(
        'type'        => 'text',
        'label'       => 'מספר ח.פ.',
        'placeholder' => 'לדוגמה: 512345678',
        'required'    => false,
        'class'       => array( 'form-row-wide' ),
        'priority'    => 130,
        'clear'       => true,
    );

    return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'pablo_rotem_add_checkout_fields' );

שים לב שאני בוחר מזהה ברור לשדה, label אנושי, placeholder עדין, ו-priority שממקם אותו נכון. אל תתן לשדות מזהים אקראיים; שמות ברורים יקלו מאוד על שמירה, מיילים, API ותחזוקה עתידית.

אימות ושמירה: זה החלק שמבדיל קוד רציני מ-snippet חצי אפוי

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

<?php
/**
 * אימות לשדה custom checkout.
 *
 * Author: pablo rotem
 */

function pablo_rotem_validate_company_id(): void {
    $company_id = isset( $_POST['billing_company_id'] )
        ? wc_clean( wp_unslash( $_POST['billing_company_id'] ) )
        : '';

    if ( '' === $company_id ) {
        return;
    }

    if ( ! preg_match( '/^[0-9]{8,9}$/', $company_id ) ) {
        wc_add_notice( 'מספר ח.פ. חייב להכיל 8 או 9 ספרות.', 'error' );
    }
}
add_action( 'woocommerce_checkout_process', 'pablo_rotem_validate_company_id' );
<?php
/**
 * שמירת הערך במטא של ההזמנה.
 *
 * Author: pablo rotem
 */

function pablo_rotem_save_company_id_to_order( $order, array $data ): void {
    if ( empty( $_POST['billing_company_id'] ) ) {
        return;
    }

    $company_id = wc_clean( wp_unslash( $_POST['billing_company_id'] ) );
    $order->update_meta_data( '_billing_company_id', $company_id );
}
add_action( 'woocommerce_checkout_create_order', 'pablo_rotem_save_company_id_to_order', 10, 2 );

שים לב לשני דברים חשובים: אני משתמש ב-wp_unslash() וב-wc_clean(), ואני שומר את הערך במפתח מטא ברור שמתחיל ב-underscore. זה משאיר את בסיס הקוד שלך נקי ועקבי.

להציג את הנתון במקום הנכון אחרי ההזמנה

אחרי ששמרת את השדה, שאל את עצמך מי צריך לראות אותו. מנהל החנות? רואה חשבון? מחלקת משלוחים? לרוב תרצה להציג אותו גם במסך ההזמנה וגם במיילים המתאימים. הנה שתי דוגמאות שימושיות:

<?php
/**
 * הצגת השדה באזור הניהול של ההזמנה.
 *
 * Author: pablo rotem
 */

function pablo_rotem_show_company_id_in_admin( $order ): void {
    $company_id = $order->get_meta( '_billing_company_id' );

    if ( '' === $company_id ) {
        return;
    }

    echo '<p><strong>מספר ח.פ.:</strong> ' . esc_html( $company_id ) . '</p>';
}
add_action( 'woocommerce_admin_order_data_after_billing_address', 'pablo_rotem_show_company_id_in_admin' );
<?php
/**
 * הוספת השדה למיילים.
 *
 * Author: pablo rotem
 */

function pablo_rotem_add_company_id_to_emails( array $fields, bool $sent_to_admin, $order ): array {
    $company_id = $order->get_meta( '_billing_company_id' );

    if ( '' !== $company_id ) {
        $fields['billing_company_id'] = array(
            'label' => 'מספר ח.פ.',
            'value' => $company_id,
        );
    }

    return $fields;
}
add_filter( 'woocommerce_email_order_meta_fields', 'pablo_rotem_add_company_id_to_emails', 10, 3 );

העיקרון כאן פשוט: אל תאסוף נתון שאתה לא עושה איתו כלום. אם שדה קיים, צריך להיות לו מסלול עבודה ברור.

ומה לגבי Checkout Blocks

אם החנות שלך עברה ל-Cart and Checkout Blocks, חשוב להבין שלא כל קוד legacy יעבוד אחד לאחד. WooCommerce מוסיפה תשתית נוספת לשדות checkout בבלוקים, כולל hooks ו-APIs ייעודיים להוספת שדות, אימות ושמירה. לכן לפני פיתוח אני תמיד בודק: האם הקופה באתר היא legacy shortcode או block-based checkout.

זה חשוב כי אין דבר יותר מתסכל מלכתוב snippet מושלם, ורק אז לגלות שהאתר בכלל עובד על ארכיטקטורה אחרת. אם אתה על blocks, קרא קודם את מסמכי Additional Checkout Fields ו-Cart או Checkout Blocks לפני כתיבת קוד מותאם.

איך לארוז את זה כמו מפתח תוספים ולא כמו קובץ snippets

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

<?php
/**
 * עטיפה מסודרת לתוסף קטן עם שדות checkout.
 *
 * Author: pablo rotem
 */

final class Pablo_Rotem_Checkout_Fields {
    public function __construct() {
        add_filter( 'woocommerce_checkout_fields', array( $this, 'register_fields' ) );
        add_action( 'woocommerce_checkout_process', array( $this, 'validate_fields' ) );
        add_action( 'woocommerce_checkout_create_order', array( $this, 'save_fields' ), 10, 2 );
    }

    public function register_fields( array $fields ): array {
        $fields['billing']['billing_delivery_code'] = array(
            'type'     => 'text',
            'label'    => 'קוד גישה לשליח',
            'required' => false,
            'class'    => array( 'form-row-wide' ),
            'priority' => 145,
        );

        return $fields;
    }

    public function validate_fields(): void {
        // כאן אפשר להוסיף בדיקות לפי הצורך.
    }

    public function save_fields( $order, array $data ): void {
        if ( isset( $_POST['billing_delivery_code'] ) ) {
            $value = wc_clean( wp_unslash( $_POST['billing_delivery_code'] ) );
            $order->update_meta_data( '_billing_delivery_code', $value );
        }
    }
}

new Pablo_Rotem_Checkout_Fields();

זו גם צורה הרבה יותר בריאה לפרויקטים של לקוחות, במיוחד אם בעתיד תרצה להוסיף REST API, export לחשבוניות, או סנכרון עם CRM.

טעויות נפוצות ותהליך QA אמיתי

הטעות הראשונה היא להשתמש במזהה שדה לא עקבי. השנייה היא לשמור נתון ללא אימות. השלישית היא להציג שדה ב-checkout אבל לשכוח לשים אותו במיילים או במסך מנהל. עוד טעות נפוצה היא להניח שהכול רץ על legacy checkout בזמן שבפועל האתר משתמש ב-blocks.

  1. בדוק checkout כאורח וכמשתמש מחובר.
  2. בדוק שגיאה מכוונת כדי לראות שהוולידציה עובדת.
  3. בדוק שהנתון נשמר ב-order meta.
  4. בדוק שהנתון מוצג במקום שבו העסק באמת צריך אותו.
  5. בדוק cache, תוספי checkout, ותוספים צד שלישי שמבצעים override.

כשאתה בודק ככה, אתה לא רק מוסיף שדה – אתה בונה תהליך איסוף נתונים מסודר בתוך WooCommerce.

סיכום

הוספת שדות checkout ב-WooCommerce הופכת לפשוטה ובריאה הרבה יותר כשחושבים על כל מחזור החיים של השדה: הגדרה, מיקום, אימות, שמירה, הצגה ותחזוקה. זה בדיוק ההבדל בין snippet מקרי לבין קוד מסחרי שניתן לחיות איתו לאורך זמן.

קישורים רשמיים להמשך עבודה

  https://developer.woocommerce.com/docs/code-snippets/customising-checkout-fields/ | https://developer.woocommerce.com/docs/block-development/extensible-blocks/cart-and-checkout-blocks/additional-checkout-fields/ | https://developer.wordpress.org/apis/security/sanitizing/ | https://woocommerce.com/document/introduction-to-hooks-actions-and-filters/ | https://www.php.net/manual/en/