WooCommerce活动票务站如何实现单订单限购1件、单用户终身限购
需求1:全产品永久生效「单订单仅允许购买1件商品」
代码实现方案
直接删除原有代码中限制特定产品ID的判断逻辑即可,修改后代码如下:
add_filter( 'woocommerce_add_to_cart_validation', 'wc_limit_one_per_order_all_products', 10, 2 ); function wc_limit_one_per_order_all_products( $passed_validation, $product_id ) { // 移除产品ID判断,所有商品均触发限制 if ( WC()->cart->get_cart_contents_count() >= 1 ) { wc_add_notice( __( '每笔订单仅允许购买1件商品,请先清空购物车后再添加新商品。', 'woocommerce' ), 'error' ); return false; } return $passed_validation; }
如果你仅需要对票务类商品生效、不需要限制普通商品,可以通过判断产品是否关联The Events Calendar活动的逻辑做过滤,不需要手动维护ID列表。
内置设置/插件替代方案
- WooCommerce原生自带「单独销售」功能:在单个产品编辑页的【库存】选项卡中勾选「单独销售 - 允许单个订单中只能购买一个此商品」即可,批量设置可以在产品列表页用批量编辑功能批量开启。
- 也可使用WooCommerce Min/Max Quantities插件实现更灵活的数量、订单限制,无需写代码。
需求2:限制每个用户账号终身仅可购买1次对应SKU的商品
基于你已经设置必须登录才能购票的前提,可以通过加购校验+下单双重校验实现,代码示例如下:
// 加购时校验是否已购买过该商品 add_filter( 'woocommerce_add_to_cart_validation', 'wc_limit_one_per_user_lifetime', 10, 3 ); function wc_limit_one_per_user_lifetime( $passed, $product_id, $quantity ) { $user_id = get_current_user_id(); if ( ! $user_id ) return $passed; // 未登录用户你已限制无法购买,可根据需求调整提示 // 如需仅对指定商品生效,可打开下方注释替换ID,不需要全量限制的话可以保留 // $limit_product_ids = [31,32,33]; // if ( !in_array( $product_id, $limit_product_ids ) ) return $passed; // 查询当前用户的有效订单中是否已购买过该商品 $args = [ 'customer_id' => $user_id, 'status' => ['completed', 'processing', 'on-hold'], // 仅统计有效订单,排除取消、退款订单 'limit' => -1, 'return' => 'ids', ]; $orders = wc_get_orders( $args ); foreach ( $orders as $order_id ) { $order = wc_get_order( $order_id ); foreach ( $order->get_items() as $item ) { if ( $item->get_product_id() == $product_id ) { wc_add_notice( __( '您已购买过该活动票务,不可重复购买。', 'woocommerce' ), 'error' ); return false; } } } return $passed; } // 下单时二次校验,避免绕过加购限制的情况 add_action( 'woocommerce_checkout_process', 'wc_check_duplicate_purchase_on_checkout' ); function wc_check_duplicate_purchase_on_checkout() { $user_id = get_current_user_id(); if ( ! $user_id ) return; foreach ( WC()->cart->get_cart() as $cart_item ) { $product_id = $cart_item['product_id']; // 如需仅限制指定商品,这里和上方加购逻辑保持一致加ID判断即可 $args = [ 'customer_id' => $user_id, 'status' => ['completed', 'processing', 'on-hold'], 'limit' => -1, 'return' => 'ids', ]; $orders = wc_get_orders( $args ); foreach ( $orders as $order_id ) { $order = wc_get_order( $order_id ); foreach ( $order->get_items() as $item ) { if ( $item->get_product_id() == $product_id ) { wc_add_notice( sprintf( __( '您已购买过%s,不可重复购买。', 'woocommerce' ), get_the_title( $product_id ) ), 'error' ); return; } } } } }
如果需要按SKU粒度限制,只需要把判断逻辑里的get_product_id()替换为get_variation_id()即可。
如果需要更灵活的配置,可以给产品新增一个自定义字段开关,勾选后才触发终身限购,不需要手动维护产品ID列表。
内容的提问来源于stack exchange,提问作者Æthelstan
相关产品推荐
相关产品推荐

