防止 WooCommerce 优惠券堆叠在购物车和结帐页面上

Prevent WooCommerce coupon stacking on cart and checkout page

我需要防止两个特定的优惠券一起使用。我成功地实现了这段代码,它可以防止将这些优惠券堆叠在 购物车 页面上:

add_action( 'woocommerce_before_cart', 'check_coupon_stack' );
function check_coupon_stack() {
    $coupon_code_1 = 'mycode1';
    $coupon_code_2 = 'mycode2';
    if ( WC()->cart->has_discount( $coupon_code1 ) && WC()->cart->has_discount( $coupon_code2) ) {
        WC()->cart->remove_coupon( $coupon_code2 );
        $notice_text = 'Discount code '.$coupon_code1.' cannot be combined with code '.$coupon_code2.'. Code '.$coupon_code2.' removed.';
        wc_print_notice( $notice_text, 'error' );
        wc_clear_notices();
    }
}

但是,这不会阻止在 结帐 页面上堆叠,该页面位于 购物车 页面之后。

我试过简单地添加:

add_action( 'woocommerce_before_checkout_form', 'check_coupon_stack' );

但这并不能使 结帐 页面上的这项工作。还需要什么?

WooCommerce 包含多个适用于优惠券的挂钩,woocommerce_applied_coupon 是其中之一,非常适合您的问题。

此外,您当前的代码仅适用于一个方向,即使用 $coupon_code_1 时,删除 $coupon_code_2 。但是,当您在问题中指出要防止两个特定优惠券一起使用时,这不会反向应用。

我的回答中考虑到了这一点,因此您得到:

function action_woocommerce_applied_coupon( $coupon_code ) {
    // Settings
    $coupon_code_1 = 'coupon1';
    $coupon_code_2 = 'coupon2';

    // Initialize
    $combined = array( $coupon_code_1, $coupon_code_2 );

    // Checks if coupon code exists in an array
    if ( in_array( $coupon_code, $combined ) ) {
        // Get applied coupons
        $applied_coupons = WC()->cart->get_applied_coupons();

        // Computes the difference of arrays
        $difference = array_diff( $combined, $applied_coupons );

        // When empty
        if ( empty( $difference ) ) {
            // Shorthand if/else - Get correct coupon to remove
            $remove_coupon = $coupon_code == $coupon_code_1 ? $remove_coupon = $coupon_code_2 : $remove_coupon = $coupon_code_1;

            // Remove coupon
            WC()->cart->remove_coupon( $remove_coupon );

            // Clear Notices
            wc_clear_notices();

            // Error message
            $error = sprintf( __( 'Discount code "%1$s" cannot be combined with code "%2$s". Code "%2$s" removed.', 'woocommerce' ), $coupon_code, $remove_coupon );

            // Show error
            wc_print_notice( $error, 'error' );
        }
    }
}
add_action( 'woocommerce_applied_coupon', 'action_woocommerce_applied_coupon', 10, 1 );