در پروژه‌های فروشگاهی، هیچ‌جا به‌اندازهٔ ووکامرس به هوک نیاز پیدا نمی‌کنید. اولین باری که برای یک مشتری خواستم متن «افزودن به سبد خرید» را عوض کنم، مستقیم رفتم سراغ فایل‌های قالب ووکامرس در پوشهٔ woocommerce/. نتیجه‌اش را در آپدیت بعدی دیدم: تمام تغییرات ناپدید شد و سایت به‌هم ریخت. از آن روز، قاعدهٔ شخصی‌ام این شد: هر تغییری در فروشگاه، اگر با هوک ممکن باشد، با هوک انجام می‌شود. هوک‌های وردپرس برای ووکامرس ستون فقرات سفارشی‌سازی فروشگاه‌اند و در عمل، تفاوت بین یک فروشگاه قابل نگهداری و یک فروشگاه شکننده را می‌سازند. اگر با مفهوم پایهٔ هوک آشنایی ندارید، پیش از ادامه هوک‌های وردپرس چیستند و چگونه کار می‌کنند را بخوانید. همچنین پیشنهاد می‌کنم پیش از این مقاله، ووکامرس چیست و چگونه فروشگاه اینترنتی بسازیم را یک نگاه بیندازید تا نقشهٔ کلی روشن باشد.

چرا هوک، تنها راه درست سفارشی‌سازی ووکامرس است

ووکامرس، خودش یک افزونهٔ وردپرس است که روی معماری هوک بنا شده. این یعنی ووکامرس در نقاط مختلف چرخهٔ خرید، Action و Filter در اختیار شما می‌گذارد و هر سفارشی‌سازی جدی، از همین نقاط عبور می‌کند. سه دلیل این رویکرد را در پروژه‌های فروشگاهی خودم تجربه کرده‌ام:

یک، مقاومت در برابر آپدیت. فایل‌های قالب ووکامرس در پوشهٔ woocommerce/ قالب شما، در هر آپدیت بازنویسی می‌شوند. اگر آن‌جا تغییر داده باشید، ناپدید می‌شود. هوک‌ها این مشکل را از میان برمی‌دارند؛ چون کد شما در چایلد تم یا افزونهٔ اختصاصی زندگی می‌کند، نه در فایل‌های خود ووکامرس.

دو، همکاری با اکوسیستم. هزاران افزونهٔ ووکامرس روی همین هوک‌ها ساخته شده‌اند. اگر شما هم استاندارد کار کنید، فروشگاه شما با آن‌ها گفت‌وگو می‌کند؛ اگر نه، هر افزونهٔ جدید می‌تواند با کد شما تعارض پیدا کند. شرح تفصیلی این الگو در تفاوت Action و Filter در وردپرس چیست آمده است.

سه، توسعه‌پذیری برای آیندهٔ فروشگاه. فروشگاهی که امروز راه می‌افتد، فردا نیاز به تغییر خواهد داشت — اضافه‌کردن فیلد سفارشی به سفارش، تغییر پیام تسویه‌حساب، همگام‌سازی با CRM. اگر پایهٔ کار با هوک ساخته شده باشد، این تغییرات بدون شکستن چیزی ممکن است. اگر نه، هر تغییر یک ریسک است.

فروشگاه ووکامرسی بدون هوک، مثل مغازه‌ای است که قفسه‌هایش به دیوار میخ شده؛ هر تغییر در چیدمان، یعنی تخریب دیوار. هوک‌ها، یعنی قفسه‌های ریلی که با یک دست جابه‌جا می‌شوند.

هوک‌های صفحهٔ محصول: woocommerce_before_single_product و هم‌خانواده‌ها

صفحهٔ محصول، قلب هر فروشگاه است و ووکامرس به‌طور مشخص، بیش از بیست هوک Action و Filter برای آن در اختیار شما گذاشته. پرکاربردترین‌های این حوزه را در قالب یک جدول جمع کرده‌ام:

هوکنوعکاربرد
woocommerce_before_single_productActionپیش از شروع نمایش کامل صفحهٔ محصول
woocommerce_before_single_product_summaryActionپیش از بخش تصویر و خلاصهٔ محصول
woocommerce_single_product_summaryActionافزودن محتوا به خلاصهٔ محصول (عنوان، قیمت، توضیح کوتاه)
woocommerce_after_single_product_summaryActionبعد از بخش خلاصه، برای افزودن تب‌ها یا محصولات مرتبط
woocommerce_product_meta_startActionدر بخش متای محصول (دسته، برچسب)
woocommerce_product_tabsFilterافزودن، حذف یا تغییر ترتیب تب‌های محصول

نمونهٔ زیر، یک بلوک «زمان ارسال تخمینی» را به خلاصهٔ محصول اضافه می‌کند؛ کاری که در فروشگاه‌های صنایع دستی و سفارشی‌سازی بسیار پرکاربرد است:

add_action( 'woocommerce_single_product_summary', 'wphk_product_shipping_estimate', 25 );

function wphk_product_shipping_estimate() {
    global $product;
    if ( ! $product instanceof WC_Product ) {
        return;
    }
    if ( ! $product->is_in_stock() ) {
        return;
    }
    echo '<p class="wphk-ship-note">ارسال این محصول بین ۲ تا ۴ روز کاری انجام می‌شود.</p>';
}

دو نکتهٔ کلیدی در این تکه. اول، اولویت ۲۵ انتخاب شده؛ چون بخش خلاصهٔ محصول به‌طور پیش‌فرض از اولویت ۱۰ تا ۴۰ چیده شده و اولویت ۲۵، جای مناسب بین قیمت (۱۰) و دکمهٔ افزودن به سبد خرید (۳۰) است. دوم، بررسی instanceof WC_Product جلوی خطا در موقعیت‌هایی که $product به‌درستی مقداردهی نشده را می‌گیرد. برای درک عمیق‌تر این ترتیب، Priority در هوک‌های وردپرس چیست را ببینید.

نمونهٔ دیگری که در پروژه‌های زیادی به‌کارم آمده، افزودن یک تب سفارشی به صفحهٔ محصول برای نمایش جدول مشخصات فنی:

add_filter( 'woocommerce_product_tabs', 'wphk_add_specs_tab' );

function wphk_add_specs_tab( $tabs ) {
    $tabs['wphk_specs'] = array(
        'title'    => 'مشخصات فنی',
        'priority' => 15,
        'callback' => 'wphk_render_specs_tab',
    );
    return $tabs;
}

function wphk_render_specs_tab() {
    global $product;
    $specs = get_post_meta( $product->get_id(), '_wphk_specs', true );
    if ( ! $specs ) {
        echo '<p>مشخصات فنی این محصول ثبت نشده است.</p>';
        return;
    }
    echo wp_kses_post( wpautop( $specs ) );
}

اگر فروشگاه شما تب‌های زیادی دارد و می‌خواهید ساختار را بهتر مدیریت کنید، پیشنهاد می‌کنم مقالهٔ سفارشی‌سازی صفحه محصول در ووکامرس را یک بار مرور کنید؛ آن‌جا الگوهای مکمل این کار را آورده‌ام.

هوک‌های حلقهٔ محصولات و آرشیو فروشگاه

آرشیو فروشگاه و دسته‌بندی‌های محصول، نقاط دیگری هستند که با هوک قابل سفارشی‌سازی‌اند. این‌ها در عمل، فضای نمایش برچسب تخفیف، نشان «جدید»، امتیاز، یا حتی ترتیب فیلدهای لیست محصولات را تحت کنترل شما می‌گذارند. پرکاربردترین‌های این حوزه:

  • woocommerce_before_shop_loop — پیش از شروع لیست محصولات در آرشیو.
  • woocommerce_before_shop_loop_item_title — پیش از عنوان محصول در هر کارت.
  • woocommerce_after_shop_loop_item_title — بعد از عنوان؛ جای مناسب برای افزودن نشان یا قیمت اضافه.
  • woocommerce_after_shop_loop_item — بعد از هر کارت، برای دکمه‌های اضافی.
  • woocommerce_after_shop_loop — بعد از کل لیست، برای پیام یا بنر انتهایی.

نمونهٔ زیر، یک نشان «پرفروش» را روی کارت محصولاتی که برچسب «bestseller» دارند اضافه می‌کند:

add_action( 'woocommerce_after_shop_loop_item_title', 'wphk_bestseller_badge', 5 );

function wphk_bestseller_badge() {
    global $product;
    if ( ! $product instanceof WC_Product ) {
        return;
    }
    if ( ! has_term( 'bestseller', 'product_tag', $product->get_id() ) ) {
        return;
    }
    echo '<span class="wphk-badge wphk-badge--best">پرفروش</span>';
}

این الگو در پروژه‌های فروشگاهی بسیار مؤثر است؛ چون به‌جای دست‌زدن به فایل قالب، یک لایهٔ تازه به کارت محصول اضافه می‌کند و می‌توان آن را از طریق چایلد تم به‌سادگی استایل داد. اگر با چایلد تم آشنایی ندارید، قالب وردپرس چایلد چیست و چه زمانی به آن نیاز داریم مسیر را روشن می‌کند.

هوک‌های سبد خرید: افزودن، حذف، محاسبهٔ جمع

سبد خرید، بخش حساسی از فروشگاه است؛ چون هر تغییر در آن، روی قیمت و در نهایت روی درآمد اثر می‌گذارد. ووکامرس در این ناحیه هم هوک‌های قدرتمندی دارد که اجازه می‌دهد بدون دست‌زدن به منطق هسته، رفتار سبد را سفارشی کنید:

  • woocommerce_add_to_cart — هنگام افزودن محصول به سبد؛ مناسب برای ثبت لاگ یا کاهش موجودی جانبی.
  • woocommerce_before_calculate_totals — پیش از محاسبهٔ جمع نهایی؛ نقطهٔ کلیدی برای تخفیف سفارشی براساس قواعد کسب‌وکار.
  • woocommerce_cart_calculate_fees — افزودن هزینهٔ اضافه (مثلاً مالیات پیک یا هزینهٔ بسته‌بندی).
  • woocommerce_cart_item_removed — هنگام حذف یک محصول از سبد.
  • woocommerce_cart_collaterals — جای قرارگیری جعبهٔ کوپن و دکمهٔ تسویه‌حساب.

یک نمونهٔ کاربردی از تجربهٔ واقعی خودم: فروشگاهی داشتیم که برای سفارش‌های بالای مبلغ مشخص، هزینهٔ ارسال را حذف می‌کرد. پیاده‌سازی این کار با woocommerce_cart_calculate_fees بسیار تمیزتر از دست‌زدن به کوپن‌های ووکامرس بود:

add_action( 'woocommerce_cart_calculate_fees', 'wphk_free_shipping_fee' );

function wphk_free_shipping_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }
    $threshold = 2000000; // دو میلیون تومان
    if ( $cart->get_subtotal() >= $threshold ) {
        // این‌جا می‌توان هزینهٔ قبلی را حذف یا اعتبار اضافه کرد
        // بسته به منطق فروشگاه، عملیات مناسب انجام می‌شود
    }
}

یک نکتهٔ امنیتی مهم: این هوک در برخی از درخواست‌های پیشخوان هم اجرا می‌شود. شرط ابتدایی is_admin() && ! defined("DOING_AJAX") از تغییر ناخواستهٔ محاسبات در پنل مدیریت جلوگیری می‌کند. برای توضیح بهتر ساختار فرم و سبد خرید، سفارشی‌سازی سبد خرید و تسویه‌حساب ووکامرس را ببینید.

هوک‌های تسویه‌حساب و فیلدهای سفارشی

تسویه‌حساب، آخرین مرحلهٔ خرید است و هر بهبود کوچک در تجربهٔ آن، مستقیماً روی نرخ تبدیل اثر می‌گذارد. ووکامرس در این مسیر، مجموعهٔ کاملی از هوک‌ها برای افزودن فیلد، تغییر ساختار فرم و پردازش داده در اختیار شما می‌گذارد:

add_filter( 'woocommerce_checkout_fields', 'wphk_add_checkout_field' );

function wphk_add_checkout_field( $fields ) {
    $fields['billing']['billing_national_id'] = array(
        'type'        => 'text',
        'label'       => 'کد ملی',
        'required'    => true,
        'class'       => array( 'form-row-wide' ),
        'priority'    => 25,
    );
    return $fields;
}

پس از افزودن فیلد، باید در ذخیره‌سازی سفارش هم آن را مدیریت کنید. هوک woocommerce_checkout_update_order_meta نقطهٔ درست این کار است:

add_action( 'woocommerce_checkout_update_order_meta', 'wphk_save_national_id' );

function wphk_save_national_id( $order_id ) {
    if ( ! empty( $_POST['billing_national_id'] ) ) {
        $value = sanitize_text_field( wp_unslash( $_POST['billing_national_id'] ) );
        update_post_meta( $order_id, '_billing_national_id', $value );
    }
}

اگر می‌خواهید پس از ثبت سفارش، منطق کسب‌وکار خاصی (مثلاً ارسال به سیستم انبار یا ثبت در CRM) اجرا شود، هوک woocommerce_checkout_order_processed در اختیار شماست:

add_action( 'woocommerce_checkout_order_processed', 'wphk_after_order_created', 20, 3 );

function wphk_after_order_created( $order_id, $posted_data, $order ) {
    if ( ! $order instanceof WC_Order ) {
        return;
    }
    // همگام‌سازی با سیستم بیرونی، اجرای منطق پاداش و...
}

دو نکته از تجربه: اول، همیشه sanitize روی دادهٔ ورودی؛ بدون آن، هر نوع دادهٔ آلوده وارد دیتابیس می‌شود. دوم، در woocommerce_checkout_order_processed هیچ‌وقت کار سنگین یا ارسال ایمیل مستقیم انجام ندهید؛ اگر ارسال ایمیل کند باشد، ثبت سفارش کند می‌شود و کاربر ممکن است دکمهٔ پرداخت را دوباره بزند. برای مدیریت این نوع فرآیندها، الگوی صف پس‌زمینه یا cron را در رفع مشکلات کرون در وردپرس توضیح داده‌ام. همچنین اگر به دنبال بهبود سرعت کل فروشگاه هستید، افزایش سرعت فروشگاه ووکامرس مکمل این مقاله است.

هوک‌های سفارش: ایجاد، تغییر وضعیت، به‌روزرسانی

پس از ثبت سفارش، بخش بزرگی از منطق فروشگاه روی تغییر وضعیت سفارش متمرکز می‌شود. سه هوک کلیدی در این حوزه:

  • woocommerce_new_order — هنگام ایجاد یک سفارش جدید؛ پیش از ذخیرهٔ کامل.
  • woocommerce_order_status_changed — هنگام تغییر وضعیت سفارش (pending به processing، processing به completed).
  • woocommerce_order_status_{status} — نسخهٔ اختصاصی برای وضعیت خاص.

پرکاربردترین سناریو: ارسال پیام تشکر به مشتری وقتی سفارش به وضعیت «تکمیل‌شده» می‌رود:

add_action( 'woocommerce_order_status_completed', 'wphk_send_thank_you', 10, 1 );

function wphk_send_thank_you( $order_id ) {
    $order = wc_get_order( $order_id );
    if ( ! $order ) {
        return;
    }
    // ثبت یک یادداشت داخلی روی سفارش
    $order->add_order_note( 'تشکر از خرید؛ پیام ارسال شد.' );
}

و نسخهٔ جامع‌تر با هوک کلی woocommerce_order_status_changed که هر تغییر وضعیت را می‌گیرد:

add_action( 'woocommerce_order_status_changed', 'wphk_on_status_change', 10, 4 );

function wphk_on_status_change( $order_id, $from, $to, $order ) {
    if ( 'completed' === $to && 'completed' !== $from ) {
        // اجرای منطق پس از تکمیل سفارش
        error_log( sprintf( 'Order #%d completed.', $order_id ) );
    }
}

این پارامترها را در پروژه‌های زیادی دیده‌ام که توسعه‌دهنده فراموش می‌کند $from و $to را چک کند و منطق را برای هر تغییر وضعیت اجرا می‌کند؛ نتیجه، رفتارهای تکراری و آزاردهنده است. برای شناخت دقیق پارامترهای این نوع هوک‌ها، چگونه پارامترهای هوک وردپرس را بشناسیم راهنمای خوبی است. برای مطالعهٔ جامع‌تر مدیریت سفارش، مدیریت سفارش‌ها در ووکامرس مرجع کاملی است.

وضعیت سفارش، نبض فروشگاه است. هر تغییری در آن، فرصتی است برای تعامل با مشتری — یا آزار او. تفاوت این دو، در دقت هوک و منطق شماست.

هوک‌های ایمیل و اعلان‌های سفارش

ایمیل‌های سفارش، اولین چیز بعد از پایان خرید است که مشتری می‌بیند. ووکامرس در این حوزه هوک‌های اختصاصی دارد که اجازه می‌دهد هر بخش آن را تغییر دهید:

  • woocommerce_email_header — بالای هر ایمیل ووکامرس؛ برای افزودن لوگو یا متن برند.
  • woocommerce_email_footer — پایین هر ایمیل؛ برای افزودن امضا یا لینک شبکه‌های اجتماعی.
  • woocommerce_email_order_meta — بخش متای سفارش در ایمیل؛ جای مناسب برای فیلدهای سفارشی.
  • woocommerce_email_before_order_table و woocommerce_email_after_order_table — افزودن محتوا پیش و پس از جدول سفارش.
add_action( 'woocommerce_email_before_order_table', 'wphk_email_custom_note', 10, 4 );

function wphk_email_custom_note( $order, $sent_to_admin, $plain_text, $email ) {
    if ( $sent_to_admin ) {
        return;
    }
    if ( 'customer_processing_order' !== $email->id ) {
        return;
    }
    echo '<p>از خرید شما سپاسگزاریم. سفارش شما در حال آماده‌سازی است.</p>';
}

نکتهٔ ظریف: همیشه شرط $sent_to_admin را بررسی کنید. بدون این شرط، پیام شما به ایمیل مدیر هم اضافه می‌شود که معمولاً مطلوب نیست. اگر می‌خواهید ساختار ایمیل‌های ووکامرس را از پایه سفارشی کنید، با فایل‌های قالب emails/ هم کار دارید؛ ولی همیشه از هوک شروع کنید و فقط در مواقع ضروری به بازنویسی قالب رو بیاورید. اگر فروشگاه شما با ایمیل‌های ووکامرس مشکل دارد، مسیر رفع را در رفع خطاهای رایج ووکامرس آورده‌ام.

هوک‌های درگاه پرداخت

ووکامرس برای درگاه‌های پرداخت، معماری کلاس درگاه با متدهای اختصاصی دارد. ولی در کنار آن، چند هوک عمومی هم وجود دارد که در همهٔ درگاه‌ها کار می‌کنند و اجازه می‌دهند منطق سفارشی به فرآیند پرداخت اضافه کنید:

  • woocommerce_available_payment_gateways — فیلتر درگاه‌های موجود؛ مناسب برای مخفی‌کردن درگاه براساس شرایط.
  • woocommerce_receipt_{gateway_id} — صفحهٔ رسید پس از پرداخت برای درگاه خاص.
  • woocommerce_payment_complete — پس از تکمیل موفق پرداخت.
  • woocommerce_payment_complete_order_status — تغییر وضعیت پیش‌فرض پس از پرداخت موفق.

نمونهٔ زیر، درگاه پرداخت آنلاین را برای سفارش‌های زیر مبلغ مشخص، غیرفعال می‌کند (سناریوی رایج برای سفارش‌های کوچک):

add_filter( 'woocommerce_available_payment_gateways', 'wphk_filter_payment_gateways' );

function wphk_filter_payment_gateways( $gateways ) {
    if ( ! is_admin() && WC()->cart ) {
        $subtotal = WC()->cart->get_subtotal();
        if ( $subtotal < 100000 ) {
            unset( $gateways['wphk_online_gateway'] );
        }
    }
    return $gateways;
}

اگر در مسیر پرداخت با خطا مواجه شدید، پیش از دست‌زدن به کد درگاه، پیشنهاد می‌کنم اتصال ووکامرس به درگاه‌های پرداخت را بخوانید؛ چون بسیاری از مشکلات، از تنظیمات درگاه ناشی می‌شود نه از کد. اگر هم می‌خواهید فروشگاه را به سرویس‌های بیرونی (حسابداری، انبار، CRM) وصل کنید، اتصال ووکامرس به سرویس‌های خارجی با API مسیر عملی را نشان می‌دهد.

سفارشی‌سازی پیشخوان سفارش‌ها

پیشخوان سفارش‌ها در ووکامرس، پرمصرف‌ترین بخش برای تیم پشتیبانی است. با چند هوک Filter و Action می‌توانید اطلاعات کلیدی را در یک نگاه نمایش دهید:

  • manage_edit-shop_order_columns — افزودن ستون سفارشی به فهرست سفارش‌ها.
  • manage_shop_order_posts_custom_column — مقداردهی ستون‌های سفارشی.
  • woocommerce_admin_order_data_after_billing_address — افزودن اطلاعات سفارشی به صفحهٔ جزئیات سفارش.
add_action( 'woocommerce_admin_order_data_after_billing_address', 'wphk_show_national_id_admin' );

function wphk_show_national_id_admin( $order ) {
    $national_id = get_post_meta( $order->get_id(), '_billing_national_id', true );
    if ( ! $national_id ) {
        return;
    }
    echo '<p><strong>کد ملی:</strong> ' . esc_html( $national_id ) . '</p>';
}

این نوع سفارشی‌سازی، بهره‌وری تیم پشتیبانی را محسوس بالا می‌برد؛ چون به‌جای رفت‌وبرگشت بین سیستم‌ها، همهٔ اطلاعات ضروری در یک صفحه دیده می‌شود. برای مطالعهٔ مسیر کامل مدیریت سفارش، مدیریت سفارش‌ها در ووکامرس مرجع خوبی است.

ترتیب اجرا و مدیریت اولویت

در فروشگاه‌های واقعی، چندین افزونه روی یک هوک مشترک کار می‌کنند. اولویت اجرای هر تابع، تفاوت بین خروجی درست و خروجی معیوب است. مقدار پیش‌فرض ۱۰ است و اجرا به‌ترتیب صعودی انجام می‌شود. مثلاً در بخش woocommerce_single_product_summary، قیمت اولویت ۱۰، دکمهٔ افزودن به سبد ۳۰، و توضیح کوتاه اولویت ۲۰ دارند. توضیح کامل در Priority در هوک‌های وردپرس چیست آمده است. اگر در فروشگاهی با تعارض افزونه‌ها روبه‌رو هستید، چگونه ترتیب اجرای هوک‌ها را مدیریت کنیم راهنمای عملی خوبی است.

یک توصیهٔ عملی: در پروژه‌های خودم، فهرست هوک‌های فعال و اولویت‌شان را در یک فایل مستندات نگه می‌دارم. این مستند، در دیباگ سریع مشکلات و در پیوند دادن افزونه‌های جدید، چند برابر وقت ذخیره می‌کند.

امنیت و دادهٔ کاربر در هوک‌های فروشگاهی

هوک‌های فروشگاهی چون با دادهٔ کاربر (نام، آدرس، کد ملی، شمارهٔ تماس) و دادهٔ مالی (سفارش، پرداخت، تخفیف) کار می‌کنند، سطح حساسیت بالاتری دارند. سه اصل که در همهٔ hook handlerها رعایت می‌کنم:

  1. پاک‌سازی ورودی با sanitize_*. هر دادهٔ $_POST و $_GET پیش از ذخیره، باید پاک‌سازی شود.
  2. خروج امن با esc_html، esc_attr، esc_url. در قالب ادمین و front، خروج دادهٔ سفارشی باید پاک‌سازی شود.
  3. بررسی دسترسی و nonce. در فرم‌ها و AJAX handlerها، همیشه wp_verify_nonce و current_user_can را چک کنید.

یک نکتهٔ ویژهٔ ووکامرس: متدهای WC_Order مثل get_billing_email و get_formatted_billing_address به‌طور پیش‌فرض خروجی امن می‌دهند؛ اما وقتی به get_meta یا get_post_meta مستقیم دسترسی پیدا می‌کنید، مسئولیت پاک‌سازی خروجی روی دوش شماست. راهنمای جامع این حوزه در هوک‌های وردپرس و افزایش امنیت کد آمده است. برای جلوگیری از آسیب‌های امنیتی گسترده‌تر در فروشگاه، امنیت فروشگاه ووکامرس را هم یک بار مرور کنید.

هر هوکی که روی دادهٔ کاربر اجرا می‌شود، یک قرارداد امنیتی است. اگر این قرارداد را جدی نگیرید، روزی که داده لو برود، همه‌چیز از دست می‌رود.

اشتباهات رایج در پیاده‌سازی هوک‌های ووکامرس

در بازبینی فروشگاه‌های مختلف، شش الگوی تکراری بیشترین آسیب را ساخته‌اند:

اشتباهپیامد واقعیاصلاح
ویرایش مستقیم فایل‌های woocommerce/ در قالبناپدیدشدن تغییرات در آپدیتاستفاده از هوک در چایلد تم یا افزونهٔ اختصاصی
نبود شرط is_admin() در هوک‌های محاسبهتغییر ناخواسته در پیشخوانبررسی محیط اجرا در ابتدای تابع
اجرای کوئری سنگین در woocommerce_before_calculate_totalsکندی صفحهٔ سبد خرید و تسویه‌حسابکش، ترنزینت یا انتقال به هوک مناسب‌تر
ذخیرهٔ داده بدون sanitize_text_fieldورود دادهٔ آلوده به دیتابیسپاک‌سازی در همهٔ ورودی‌ها
ارسال ایمیل مستقیم در مسیر تسویه‌حسابکندی فرآیند پرداخت و تایم‌اوتانتقال به cron یا صف
نادیده‌گرفتن پارامترهای $from و $to در تغییر وضعیت سفارشاجرای منطق در هر تغییر، نه فقط در وضعیت هدفبررسی صریح مقصد تغییر

هرکدام از این موارد را در پروژه‌ای دیده‌ام. شرح مفصل‌تر اشتباهات مشترک هوک‌ها در اشتباهات رایج هنگام استفاده از هوک‌ها آمده است؛ پیش از هر انتشار، این مقاله را یک بار مرور می‌کنم. همچنین اگر در فروشگاه با خطاهای خاص روبه‌رو شده‌اید، رفع خطاهای رایج ووکامرس را ببینید؛ بسیاری از آن خطاها ریشه در همان اشتباهات هوکی دارند.

نگاه معماری به هوک‌های فروشگاهی

وقتی فروشگاه شما از چند سفارش در روز به چند صد سفارش می‌رسد، هوک‌های ووکامرس از «ابزار سفارشی‌سازی» به «ستون معماری» تبدیل می‌شوند. سه اصل که در پروژه‌های بزرگ فروشگاهی به‌کارم آمده، در این مقیاس تفاوت واقعی می‌سازند:

یک، جداسازی لایه‌ها. کد سفارشی شما باید در سه فایل جدا زندگی کند: یک فایل برای لایهٔ نمایش (افزودن محتوا به صفحات)، یک فایل برای منطق کسب‌وکار (محاسبات تخفیف، پاداش، اعتبار)، و یک فایل برای اتصال به سرویس‌های بیرونی (CRM، انبار، حسابداری). همهٔ این‌ها به هوک‌های ووکامرس وصل می‌شوند، ولی مرزبندی فایل‌ها، بازبینی و اشکال‌زدایی را چند برابر سریع‌تر می‌کند.

دو، Idempotency در منطق سفارش. هر hook handler که روی سفارش کار می‌کند، باید در اجرای مکرر نتیجهٔ یکسان بدهد. مثلاً اگر تخفیفی براساس شرایط اعمال می‌کنید، دوبار اجرا نباید تخفیف را دو برابر کند. ساده‌ترین راه این اطمینان، ثبت وضعیت در متای سفارش با یک کلید مثل _wphk_discount_applied است.

سه، حذف کارهای سنگین از مسیر کاربر. صفحهٔ محصول، سبد خرید، تسویه‌حساب و صفحهٔ تشکر، همه مسیرهای کاربرند. اگر در این مسیرها کوئری به سرویس بیرونی، ارسال ایمیل مستقیم یا محاسبهٔ پیچیده انجام دهید، کاربر منتظر می‌ماند. بهترین الگو این است که این کارها به یک صف پس‌زمینه یا cron سپرده شوند و کاربر در همان لحظه پاسخ سریع بگیرد. توضیح فنی این الگو را در راهنمای حرفه‌ای کار با هوک‌های وردپرس آورده‌ام.

و یک نکتهٔ دیگر از جنس تجربهٔ تیمی: در فروشگاه‌هایی که چند توسعه‌دهنده روی آن کار می‌کنند، فهرست هوک‌های فعال و مسئولیت هرکدام را در یک مستند کوتاه نگه دارید. این مستند در تحلیل تعارض افزونه‌ها، در مهاجرت به قالب جدید، و در پیوند دادن سرویس‌های جدید، ارزش ساعت‌ها کار را دارد. قالب وردپرس چایلد چیست و چه زمانی به آن نیاز داریم را برای لایه‌بندی درست این کار ببینید.

مسیر پیشنهادی و گام بعدی

هوک‌های وردپرس برای ووکامرس، از صفحهٔ محصول تا سبد خرید، از تسویه‌حساب تا سفارش، از ایمیل تا درگاه پرداخت، ابزار کامل سفارشی‌سازی فروشگاه را در اختیار شما می‌گذارند. کلید استفاده از این ابزارها سه چیز است: انتخاب هوک دقیق برای هر کار، رعایت اولویت و ترتیب اجرا، و پاک‌سازی ورودی و خروجی در هر مرحله. با رعایت این سه اصل، می‌توانید فروشگاهی بسازید که در برابر آپدیت مقاوم باشد، با افزونه‌های دیگر همکاری کند، و به‌سادگی قابل نگهداری بماند.

گام بعدی عملی که پیشنهاد می‌کنم: در فروشگاه خودتان، یک فیلد سفارشی (مثل کد ملی یا کد پیگیری) به فرم تسویه‌حساب اضافه کنید، آن را در پیشخوان سفارش‌ها نمایش دهید، و یک ایمیل سفارشی برای وضعیت «تکمیل‌شده» پیاده کنید. این سه تمرین کوچک، شما را با پرکاربردترین هوک‌های ووکامرس درگیر می‌کند و مسیر را برای سفارشی‌سازی‌های بزرگ‌تر باز می‌کند. اگر در پروژه‌ای با تعارض بین یک هوک ووکامرس و افزونهٔ دیگری روبه‌رو شده‌اید، برای من جالب است بدانید کدام هوک بود و چگونه حلش کردید — تجربهٔ خودتان را در دیدگاه‌ها بنویسید؛ به‌ویژه اگر روشی پیدا کرده‌اید که در عین سادگی، اولویت‌ها را تمیز نگه می‌دارد. 🛒