You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce HPOS后台手动创建订单时强制设置账单邮编与商品

问题描述

我正在使用搭载HPOS的最新版WooCommerce。为避免后台手动创建的订单出现无商品、无账单邮编的情况,我编写了一个函数,意图在账单邮编为空或未添加商品时阻止订单创建。以下是我的代码尝试:

// During Order creation in the admin area - force to set at least one procduct and billing postalcode to avoid issues on the order overview screen and more
function avoid_orders_wout_b_postalcode_a_wout_products_9sadfM324($post_id, $post) {

    // Get the order object
    $order = wc_get_order($post_id);
    
    // Check if the order has products
    $items = $order->get_items();
    if (empty($items)) {
        // Add an error message to WooCommerce admin notices
        WC_Admin_Notices::add_custom_notice('no_products_added_error', 'ERROR YCNC0084 - ' . __('You cannot create an order without adding any products', 'nm-framework'));
        // Redirect to the edit order screen
        wp_redirect(admin_url('post.php?post=' . $post_id . '&action=edit'));
        exit;
    }

    // Check for postal code in billing and shipping address
    $billing_postcode = $order->get_billing_postcode();
    // $shipping_postcode = $order->get_shipping_postcode();

    // if (empty($billing_postcode) && empty($shipping_postcode)) {
     if ( empty($billing_postcode) ) {
        // Add an error message to WooCommerce admin notices
        WC_Admin_Notices::add_custom_notice('no_billing_postalcode_error', 'ERROR YCNC0024 - ' . __('You cannot create an order without a billing postal code', 'nm-framework'));   
        // Redirect to the edit order screen
        wp_redirect(admin_url('post.php?post=' . $post_id . '&action=edit'));
        exit;
    }
}
add_action('woocommerce_process_shop_order_meta', 'avoid_orders_wout_b_postalcode_a_wout_products_9sadfM324', 99, 2); 
// must higher then 40 according to stackoverflow answer

目前问题是:仅填写账单邮编就能保存/创建订单(即未添加商品但填了邮编时,订单仍能被创建),实际需要同时满足有商品、有账单邮编两个条件才能创建订单,请问该如何修复?

修复方案

问题根源

  1. 钩子不兼容HPOS:启用HPOS后,订单不再作为WordPress的post类型存储,原钩子woocommerce_process_shop_order_meta仅针对传统post类型订单生效,无法触发HPOS订单的验证逻辑。
  2. 错误处理逻辑缺陷:原代码遇到单个错误就直接exit,无法同时验证两个条件,且wp_redirect在HPOS场景下可能无法正确拦截订单创建。

修正后的代码

// 后台创建/编辑订单时,强制验证商品和账单邮编
function validate_admin_order_requirements($order) {
    $errors = [];

    // 检查订单是否有商品
    if (empty($order->get_items())) {
        $errors[] = 'ERROR YCNC0084 - ' . __('You cannot create an order without adding any products', 'nm-framework');
    }

    // 检查账单邮编是否为空
    if (empty($order->get_billing_postcode())) {
        $errors[] = 'ERROR YCNC0024 - ' . __('You cannot create an order without a billing postal code', 'nm-framework');
    }

    // 如果存在错误,阻止订单保存并显示通知
    if (!empty($errors)) {
        foreach ($errors as $error_msg) {
            WC_Admin_Notices::add_custom_notice('order_validation_error', $error_msg);
        }
        // 通过抛出异常阻止订单保存(HPOS兼容方式)
        throw new Exception(implode(' ', $errors));
    }
}
add_action('woocommerce_admin_process_order', 'validate_admin_order_requirements', 10, 1);

关键说明

  • HPOS兼容钩子:使用woocommerce_admin_process_order钩子,该钩子是WooCommerce为HPOS场景提供的官方订单处理钩子,参数直接传入$order对象,无需通过post_id获取。
  • 统一错误收集:先收集所有不符合条件的错误,再一次性抛出,用户能同时看到所有未满足的要求。
  • 异常拦截保存:通过抛出Exception来阻止订单保存,这是HPOS下可靠的拦截方式,替代原代码的wp_redirect+exit,避免订单被提前创建。

内容的提问来源于stack exchange,提问作者eva last

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:03:10