Woocommerce custom coupon type with custom discount always return 0;

ε祈祈猫儿з 提交于 2021-02-18 18:13:10

问题


what I am trying to do is creating custom coupon type with custom programmatically discount in woocommerce using hooks. This what my code looks like

//add new coupon type called "custom_discount"
function custom_discount_type( $discount_types ) {
    $discount_types['custom_discount'] =__( 'custom discount', 'woocommerce' );
    return $discount_types;
    }

// add the hooks
add_filter( 'woocommerce_coupon_discount_types', 'custom_discount_type',10, 1);

//function to get coupon amount for "custom_discount"
function woocommerce_coupon_get_discount_amount($discount, $discounting_amount, $cart_item, $single, $coupon) {
        if ($coupon->type == 'custom_discount'){ //if $coupon->type == 'fixed_cart' or 'percent' or 'fixed_product' or 'percent_product' The code Works
            $discount = 85;
            return $discount;
            } else {
             return $discount;
            }
        }
//add hook to coupon amount hook
add_filter('woocommerce_coupon_get_discount_amount', 'woocommerce_coupon_get_discount_amount', 10, 5);

the coupon always return with 0(Zero) discount amount. Am I missing something. Thanks for helping =)


回答1:


Ok so this topic lead me on the road to making my own coupon type so I thought I should answer it to help others.

I tried out your code and was wondering why any normal coupon showed "-£xx" before the remove button, but the custom coupon type just was lank, no minus, no pound sign jut empty. Turns out it's an issue with how WooCommerce validates the coupon on cart products. It will become active if the coupon is valid regardless if the item in the cart are.

Your coupon needs to be either valid and valid for a product, or valid for the entire cart. However when Woocommerce checks to see if your product is valid for the product it ONLY checks if the coupon type is fixed_product or 'percent_product'. If it's anything else it runs the woocommerce_coupon_is_valid_for_product hook with the existing data but defaulting to false, so your woocommerce_coupon_get_discount_amount hook will not fire.

So you need to hook into woocommerce_coupon_is_valid_for_product and validate the product to make sure it's valid. In my case I just copied the default valid function and changes $this to $coupon.

// Check if coupon is valid for product
add_filter('woocommerce_coupon_is_valid_for_product', 'woocommerce_coupon_is_valid_for_product', 10, 4);

function woocommerce_coupon_is_valid_for_product($valid, $product, $coupon, $values){
    if ( ! $coupon->is_type( array( 'bogof' ) ) ) {
        return $valid;
    }

    $product_cats = wp_get_post_terms( $product->id, 'product_cat', array( "fields" => "ids" ) );

    var_dump( $coupon->product_ids );

    // Specific products get the discount
    if ( sizeof( $coupon->product_ids ) > 0 ) {
        if ( in_array( $product->id, $coupon->product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $coupon->product_ids ) ) || in_array( $product->get_parent(), $coupon->product_ids ) ) {
            $valid = true;
        }
    }

    // Category discounts
    if ( sizeof( $coupon->product_categories ) > 0 ) {
        if ( sizeof( array_intersect( $product_cats, $coupon->product_categories ) ) > 0 ) {
            $valid = true;
        }
    }

    if ( ! sizeof( $coupon->product_ids ) && ! sizeof( $coupon->product_categories ) ) {
        // No product ids - all items discounted
        $valid = true;
    }

    // Specific product ID's excluded from the discount
    if ( sizeof( $coupon->exclude_product_ids ) > 0 ) {
        if ( in_array( $product->id, $coupon->exclude_product_ids ) || ( isset( $product->variation_id ) && in_array( $product->variation_id, $coupon->exclude_product_ids ) ) || in_array( $product->get_parent(), $coupon->exclude_product_ids ) ) {
            $valid = false;
        }
    }

    // Specific categories excluded from the discount
    if ( sizeof( $coupon->exclude_product_categories ) > 0 ) {
        if ( sizeof( array_intersect( $product_cats, $coupon->exclude_product_categories ) ) > 0 ) {
            $valid = false;
        }
    }

    // Sale Items excluded from discount
    if ( $coupon->exclude_sale_items == 'yes' ) {
        $product_ids_on_sale = wc_get_product_ids_on_sale();

        if ( isset( $product->variation_id ) ) {
            if ( in_array( $product->variation_id, $product_ids_on_sale, true ) ) {
                $valid = false;
            }
        } elseif ( in_array( $product->id, $product_ids_on_sale, true ) ) {
            $valid = false;
        }
    }

    return $valid;
}



回答2:


This question may be a little old, but there are two main coupon types, and you should add another filter based on the coupon you're adding. The filter for woocommerce_cart_coupon_types is for cart discounts, while woocommerce_product_coupon_types is for product discounts.

What you want to use is the second one woocommerce_product_coupon_types when you want WooCommerce to automatically validate the product/category_in and product/category_exclude fields etc.

You can still use the answer submitted by Chris for any manual validation, without using the above filters as required, however, please note that there are two validation functions to use/filter: $coupon->is_valid_for_cart() and $coupon->is_valid_for_product().



来源:https://stackoverflow.com/questions/32109396/woocommerce-custom-coupon-type-with-custom-discount-always-return-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!