How to create custom discount for the cart in wooc

2019-04-28 13:41发布

I'm creating a Plugin in WooCommerce and have a small issue with adding custom discounts to the CART / CHECKOUT page.

How can I apply custom discount to the cart without creating coupons? Say I want to give some discount of 5 dollars on the cart page. How can I do that?

Below is my code from the plugin file where I have used a coupon to apply discount, but I want to add another custom discount without the use of coupon.

Action Hook in the plugin file :

add_action('woocommerce_calculate_totals',array(&$this,'cart_order_total_action'));

and its function in the plugin file is :

public function cart_order_total_action(){
    if ( is_user_logged_in() ){
        global $woocommerce;
        global $current_user;
        global $wpdb;
        $u_id = $current_user->ID;
        $table_name = $wpdb->prefix."woocommerce_customer_reward_ms";
        $thetable2  = $wpdb->prefix . "woocommerce_customer_reward_cart_ms";
        $table_name3 = $wpdb->prefix."woocommerce_customer_reward_points_log_ms";
        $data       = $wpdb->get_row("SELECT * from $table_name where id=$u_id");
        $data2      = $wpdb->get_row("SELECT * from $thetable2");
        /* Order Id goes here */
        $orders=array();//order ids
        $args = array(
            'numberposts'     => -1,
            'meta_key'        => '_customer_user',
            'meta_value'      => $current_user->ID,
            'post_type'       => 'shop_order',
            'post_status'     => 'publish',
            'tax_query'=>array(
                    array(
                        'taxonomy'  =>'shop_order_status',
                        'field'     => 'slug',
                        'terms'     =>'on-hold'
                        )
            )  
        );
        $posts=get_posts($args);
        $orders=wp_list_pluck( $posts, 'ID' );
        $order = $orders[0];
        /* Order Id ends here */
        if($data){
            $user_points = $data->points;
            $points_set  = $data2->woo_pts_set;
            $coupon_code = 'wooreward_discount';
            if($user_points>=$points_set){
                // this following Code is optional and can be removed......as there is no need of if statement here
                if ( $woocommerce->cart->has_discount( $coupon_code ) ) {
                    /*$woocommerce->add_error( __('Coupon Code Already Applied.!!','woocommerce'));*/
                    return false;
                }else{
                    $woocommerce->cart->add_discount(sanitize_text_field($coupon_code));
                    $woocommerce->add_message( __('Taxco925 Reward Discount Applied.!!','woocommerce'));
                }
            }else{
                $woocommerce->add_error( __('Not Enough Taxco925 Points.!!','woocommerce'));
            }
        }else{
            $woocommerce->add_error( __('You have have not earned any Taxco925 Points yet.!!','woocommerce'));
        }
    }
}

As you can see this line $woocommerce->cart->add_discount(sanitize_text_field($coupon_code)); adds my discount to the cart. But it uses coupon in the background to do so . Is there any way I can add a custom discount without the use of coupon.

4条回答
虎瘦雄心在
2楼-- · 2019-04-28 14:26
add_action('woocommerce_checkout_order_processed','custom_disount',10,1);
function custom_disount($order_id){
    $order = wc_get_order($order_id);
    $order_items = $order->get_items();
    foreach ($order_items as $order_item_key => $order_item) {
        $product = new WC_Product((int) $order_item['product_id']);
        $quantity = (int) $order_item['qty'];
        $discount=($product->regular_price*30)/100;  //30% disount.
        wc_update_order_item_meta($order_item_key,'_line_total',($product->regular_price*$quantity)-($discount*$quantity));
    }
}
查看更多
冷血范
3楼-- · 2019-04-28 14:27

You can add discount to each and every product in the cart using "woocommerce_get_discounted_price" hook. For Eg.:

function filter_woocommerce_get_discounted_price( $price, $values, $instance ) { 
//$price represents the current product price without discount
//$values represents the product object
//$instance represent the cart object 
$discount = 300;    // add custom discount rule , This is just an example
return ($price - $discount); 
}; 
 add_filter('woocommerce_get_discounted_price','filter_woocommerce_get_discounted_price', 10, 3 ); 
查看更多
太酷不给撩
4楼-- · 2019-04-28 14:29

Maybe too late, but If someone have another solution tell me.

I use something like:

$discount = floatval(10);
if(!empty($discount) || $discount != 0){
    $discount *= -1; // convert positive to negative fees
    $woocommerce->cart->add_fee('discount', $discount, true, '' ); // add negative fees
}

If you use paypal standard payment, you got an error because you can't submit a product with negative pricing.

You just need to edit the paypal woocommerce plugin to pass this value.

But other Payment method is ok!

Best Regards,

查看更多
Bombasti
5楼-- · 2019-04-28 14:36

Add fee with negative value will not produce the right total fee. Tax is added on the fee amount resulting in higher total fee than expected.

You need to create a "coupon" and apply it to the cart before you create the order from the cart (it will not calculate right if you apply it on $order directly). Then recalculate the cart->total and finally create an order from the cart, after you have saved the order you can remove the "dynamic" created "coupon" if you want. You can create dynamic coupons with any dynamic $value and of any type (fixed, percent etc etc).

This is the only way to add discounts in woo3+. Fee is doing it wrong when it comes to discounts. Also woo say about fee "Not use negative values here!".

I guessed you wanted some example?

here....

<?php 

// this code inside wordpress and with woo3+ of course......
// you have to figure out the rest yourself, how to implement it. but here it is...

$order_data = array (
  'status' => 'on-hold' // or whatever order staus
  // can have more data if need here... 
);

// below creates a coupon with discount_type = fixed_cart, default.
$coupon = array (
  'post_title'    => 'coupon_discount',
  'post_status'   => 'publish',
  'post_type'     => 'shop_coupon'
);
// can be modified with update_post_meta discount_type = percent and so on....

$dynamic_discount = 20; // yes, just a number can be from another dynamic input source....

$new_coupon_id = wp_insert_post( $coupon ); // add the coupon to the cart
add_post_meta( $new_coupon_id , 'coupon_amount' , $dynamic_discount , true ); // add the "discount" value ($dynamic_discount)..... depends on discount_type... in this case fixed_cart

WC()->cart->add_to_cart( 2122 , 2 ); // add products, product_id , quantity ..... can be in a loop.
WC()->cart->add_discount( 'coupon_discount' ); // APPLY THE COUPON WITH DISCOUNT -> This is the trick....
WC()->cart->calculate_totals(); // do some math on the "cart"
WC()->checkout(); // yes, checkout the "cart", now with the discount....
$order_id = WC()->checkout()->create_order( $order_data ); // basic order data, see the top in this script.. get new created order_id.
$order = wc_get_order( $order_id ); // get the order...
// can do more with $order here if want, but NOT any coupons... it just not work in $order as is...
$order->calculate_totals(); // math
WC()->cart->empty_cart(); // empty cart....
$order->save(); // save the order...

wp_delete_post( $new_coupon_id , true ); // IF you  want to delete the "dynamic" coupon created above... up 2 u, if not you will end up with a lot of coupons

// sorry, a bad example, uggly code, but at least it work.... :)
// btw, i like Pattaya, send bitcoins :)

// Again, sorry for uggly code...
?>
查看更多
登录 后发表回答