WooCommerce中如何通过代码复用购物车验证逻辑,判断优惠券对订阅用户是否有效
复用WooCommerce内置优惠券验证逻辑实现订阅优惠券应用
当然可以直接复用WooCommerce内置的优惠券验证逻辑!你手动写检查确实容易遗漏场景,毕竟WooCommerce的优惠券规则其实挺复杂的——比如有效期、用户限用次数、商品分类限制、是否针对新用户等等,官方已经把这些验证都封装好了,咱们直接调用就行。
核心思路
WC_Coupon类自带的is_valid()方法已经包含了绝大多数核心验证,但默认它是针对购物车场景的,所以我们需要额外补充订阅相关的上下文验证(比如优惠券是否适用于订阅内的商品、是否允许当前订阅用户使用),再结合is_valid()完成全量检查。
改进后的完整代码
// 获取订阅对象并验证权限 $subscription_id = absint( $_REQUEST['sub_id'] ); $subscription = new WC_Subscription( $subscription_id ); // 验证当前用户是否有权限修改该订阅(关键安全检查) if ( ! current_user_can( 'edit_shop_subscription', $subscription_id ) ) { wp_send_json_error( array( 'message' => '你没有权限修改该订阅' ) ); } // 处理用户输入的优惠券代码 $coupon_code = sanitize_text_field( $_REQUEST['voucher_code'] ); $coupon = new WC_Coupon( $coupon_code ); // 清理优惠券对象的历史错误状态,确保本次验证干净 $coupon->clear_errors(); // 验证1:优惠券是否允许当前订阅用户使用 $user_id = $subscription->get_user_id(); if ( ! $coupon->is_valid_for_user( $user_id ) ) { $error_msg = $coupon->get_error_message() ?: '该优惠券仅对特定用户开放'; wp_send_json_error( array( 'message' => $error_msg ) ); } // 验证2:优惠券是否适用于订阅中的所有商品 $valid_for_all_items = true; foreach ( $subscription->get_items() as $item ) { $product = $item->get_product(); if ( ! $coupon->is_valid_for_product( $product, $item, false ) ) { $valid_for_all_items = false; break; } } if ( ! $valid_for_all_items ) { wp_send_json_error( array( 'message' => '该优惠券不适用于订阅中的商品' ) ); } // 验证3:调用官方核心验证逻辑(包含剩余使用次数、有效期、是否已作废等) if ( $coupon->is_valid() ) { // 先移除订阅中已存在的同优惠券,避免重复应用 foreach ( $subscription->get_coupons() as $existing_coupon ) { if ( strtolower( $existing_coupon->get_code() ) === strtolower( $coupon_code ) ) { $subscription->remove_coupon( $existing_coupon->get_code() ); break; } } // 应用优惠券并更新订阅 $subscription->apply_coupon( $coupon_code ); $subscription->add_order_note( sprintf( '优惠券 %s 已成功应用到订阅', $coupon_code ) ); $subscription->calculate_totals(); wp_send_json_success( array( 'message' => '优惠券应用成功' ) ); } else { // 获取官方验证失败的具体原因 $error_msg = $coupon->get_error_message() ?: '优惠券无效,请检查优惠券代码或使用规则'; wp_send_json_error( array( 'message' => $error_msg ) ); }
代码说明
- 安全检查:先验证当前用户是否有权限修改目标订阅,避免越权操作;同时用
sanitize_text_field()处理用户输入,防止注入风险。 - 用户适用性验证:
is_valid_for_user()会检查优惠券是否限制了特定用户、用户角色,或者是否仅针对新用户使用。 - 商品适用性验证:
is_valid_for_product()会检查优惠券是否适用于订阅内的商品(比如是否限制分类、商品ID、是否排除特定商品等)。 - 核心验证:
is_valid()会自动完成以下检查:- 优惠券是否存在且处于发布状态
- 优惠券是否在有效期内
- 优惠券的总使用次数是否已达上限
- 优惠券的单用户使用次数是否已达上限
- 优惠券是否被标记为无效
这样实现的好处是完全复用WooCommerce官方的验证逻辑,后续WooCommerce版本更新时,验证规则会自动同步,不用你手动维护,也不会遗漏任何边缘场景。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

