I would like to ask how to add a custom fee to the woocommerce subscription recurring total?
Found this on the web:
function woo_add_cart_fee() {
global $woocommerce;
$woocommerce->cart->add_fee( __('Custom', 'woocommerce'), 5 );
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
However that certain function is just for the regular product. NOT SUBSCRIPTION — it doesn't add the fee to the recurring totals.
As of right now, WooCommerce subscriptions doesn't support adding fees to recurring totals.
This may be too late to be of any use to you, but you might find this useful: https://docs.woocommerce.com/document/subscriptions/develop/recurring-cart-fees/
I believe this example would be relevant to your question:
In some cases, you may require the fee to only apply to the on-going
recurring payment for any subscriptions. To achieve this, you need to ... add a condition to check whether
the cart being passed into your callback is a recurring cart, or the
standard WooCommerce cart.
Recurring carts have a $recurring_cart_key property we can use to
determine if the cart is a recurring cart.
add_filter( 'woocommerce_cart_calculate_fees', 'add_recurring_postage_fees', 10, 1 );
function add_recurring_postage_fees( $cart ) {
// Check to see if the recurring_cart_key is set
if ( ! empty( $cart->recurring_cart_key ) ) {
$cart->add_fee( 'Postage', 5 );
}
}
If someone comes by this question, you can solve it in the following way:
add_filter( 'woocommerce_subscriptions_is_recurring_fee', '__return_true' );
add_filter( 'woocommerce_cart_calculate_fees', 'add_fees', 10 );
function add_fees($cart) {
$total_fee = $cart->get_subtotal();
WC()->cart->add_fee( 'Fee', $total_fee * 0.2 );
}
or
add_filter( 'woocommerce_subscriptions_is_recurring_fee', '__return_true' );
add_filter( 'woocommerce_cart_calculate_fees', 'add_fees', 10 );
function add_fees($cart) {
WC()->cart->add_fee( 'Fee', '10' );
}
Related
I am using Woocommerce and need to apply a coupon to the cart automatically when the user has selected a checkbox. I have this code
add_action( 'woocommerce_before_cart', 'apply_coupon' );
function apply_coupon() {
$coupon_code = 'sale';
if ( WC()->cart->has_discount( $coupon_code ) ) return;
WC()->cart->apply_coupon( $coupon_code );
wc_print_notices();
}
But this adds the coupon ALL THE TIME. How can I add a checkbox and make the coupon only applied when the checkbox is selected?
In order to do that, i'm using the free plugin Yith WooCommerce Deals : https://yithemes.com/themes/plugins/yith-woocommerce-deals/
In WooCommerce, I need all my orders to go immediately to "processing" status to have the order-processing email sent directly when the order is processed.
By default, this behavior exist for Paypal and COD orders, but not for BACS and Cheque where the default status is on-hold.
I tried several snippets like this one:
add_action( 'woocommerce_thankyou', 'custom_woocommerce_auto_process_order' );
function custom_woocommerce_auto_process_order( $order_id ) {
if ( ! $order_id ) {
return;
}
$order = wc_get_order( $order_id );
$order->update_status( 'processing' );
}
But this doesn't work, the order still shows up in "on-hold" status and the processing email notification is not sent. Now I just found a this snippet:
add_filter( 'woocommerce_bacs_process_payment_order_status', function( $status = 'on_hold', $order = null ) {
return 'processing';
}, 10, 2 );
And it works, but only for "BACS". How can I adapt it to also work for "Cheque" orders?
The filter hook woocommerce_cheque_process_payment_order_status is not yet implemented in Woocommerce 3.5.7 … if you look to the file located in your woocommerce plugin under: includes > gateways > cheque > class-wc-gateway-cheque.php, the hook is missing (line 122):
$order->update_status( 'on-hold', _x( 'Awaiting check payment', 'Check payment method', 'woocommerce' ) );
But on Github WC version 3.5.7 for class-wc-gateway-cheque.php file, the hook exist (line 122):
$order->update_status( apply_filters( 'woocommerce_cheque_process_payment_order_status', 'on-hold', $order ), _x( 'Awaiting check payment', 'Check payment method', 'woocommerce' ) );
The hook will is planed to be available next WooCommerce 3.6 release, see the file change on Woocommerce Github. It's tagged 3.6.0-rc.2 and 3.6.0-beta.1
So it will be possible to change the default order status to "processing" for "bacs" and "cheque" payment methods, using the following:
add_filter( 'woocommerce_bacs_process_payment_order_status','filter_process_payment_order_status_callback', 10, 2 );
add_filter( 'woocommerce_cheque_process_payment_order_status','filter_process_payment_order_status_callback', 10, 2 );
function filter_process_payment_order_status_callback( $status, $order ) {
return 'processing';
}
Code goes in functions.php file of your active child theme (or active theme).
You're almost there. Right now you are adding a filter for the BACS hook. There is a similar hook for Cheque payment method.
Simply add the following code:
add_filter(
'woocommerce_cheque_process_payment_order_status',
function( $status = 'on_hold', $order = null ) {
return 'processing';
}, 10, 2
);
It does the exact same, but just for the Cheque orders.
I've tried researching an answer for this problem now for the last 4 hours and I haven't managed to find an answer.
I have a custom fee added to my woocommerce checkout page. this is due to complicated delivery calculations which woocommerce shipping was unable to provide.
I now need to create a coupon to set this custom fee to zero if the coupon is entered.
This is setting my my custom fee
WC()->cart->add_fee( __('Shipping', 'woocommerce'), $shipping_price );
This is what I need to achieve.
if($coupon_code == "this-string"){
$shipping_price = 0;
}
I need a way to check if the coupon code submitted is equal to "this-string" and if it is I need to set $shipping Fee to zero.
Please all help will be appreciated.
You can call WC()->cart->get_applied_coupons() to get all the coupons applied to the cart. Then you can check if your coupon code is in that array. Something like this:
if(in_array($coupon_code, WC()->cart->get_applied_coupons())) {
// Do something
}
Untested, but I think you would want to do something when the code is applied, so the woocommerce_applied_coupon hook is relevant.
function so_46429329_applied_coupon( $coupon_code ) {
if( $coupon_code == "this-string" ){
$shipping_price = 0;
WC()->cart->add_fee( __('Shipping', 'woocommerce'), $shipping_price );
}
}
add_action( 'woocommerce_applied_coupon', 'so_46429329_applied_coupon' );
The part that I haven't tested is whether this overrides an existing 'Shipping Fee' or if you need to find a way to remove that first.
the below Function will add a shipping fee to your woo-commerce Cart which adds to the checkout price afterwards.
// ADD SHIPPING COST
function woo_add_cart_fee() {
WC()->cart->add_fee( __('Shipping', 'woocommerce'), 100 );
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
If you want to apply a custom coupon to the shipping fee you could do something along the lines of this
// ADD SHIPPING COST
function woo_add_cart_fee() {
$custom_coupon = $_GET["coupon_name"];
if ($custom_coupon = 'discount_code_half') {
WC()->cart->add_fee( __('Shipping', 'woocommerce'), 100 );
}elseif ($custom_coupon = 'discount_code_more_than_half') {
WC()->cart->add_fee( __('Shipping', 'woocommerce'), 50 );
}elseif ($custom_coupon = 'discount_code_free') {
WC()->cart->add_fee( __('Shipping', 'woocommerce'), 0 );
}else ( ! $custom_coupon) {
WC()->cart->add_fee( __('Shipping', 'woocommerce'), 200 );
}
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
For this method to work you will need to have a coupon button to submit a coupon name to the cart page.
Either from the previous page or you could just have it submit to the same page it is on. Either way your page will have to refresh so you can use the
$custom_coupon = $_GET["coupon_name"];
Hope this answer helps. :)
I've set up a woocommerce store with multiple users (B2C & B2B). Some of them will automatically be exempt from tax and just have tax disappear from the cart/checkout. I've used a dynamic pricing plugin to provide different prices to different roles but there is no options for tax variations.
I found this answer and tried to put it in place Role based taxes in woocommerce but as #Jplus2 is telling, #dryan144 solution is not good because it is only applied during the checkout and not on the cart. I tried to figure out the way to do it but I still do have to refresh my 'cart' page to display taxes to 0 (as they are included in the price for "guest" or "customer", any help to launch the action when my cart page is called?
I did the following:
add_filter( 'woocommerce_before_cart_contents', 'prevent_wholesaler_taxes' );
add_filter( 'woocommerce_before_shipping_calculator', 'prevent_wholesaler_taxes' );
add_filter( 'woocommerce_before_checkout_billing_form', 'prevent_wholesaler_taxes' );
function prevent_wholesaler_taxes() {
global $woocommerce;
if ( is_user_logged_in() && !(current_user_can('customer'))){
$woocommerce->customer->set_is_vat_exempt(false);
} else {
$woocommerce->customer->set_is_vat_exempt(true);
}
} //end prevent_wholesaler_taxes
It's working straight away sometimes but most of the time it's only after working after a refresh of my cart which is not good.
Try to add https://eshoes.com.au/product/test-shoes08/ to the cart then -> View your basket
Any help would be greately appreciated ;)
Cheers
This solution works perfectly, instead of using set_is_vat_exempt() I simply used $tax)class = 'Zero Rate':
add_filter( 'woocommerce_before_cart_contents', 'wc_diff_rate_for_user', 1, 2 );
add_filter( 'woocommerce_before_shipping_calculator', 'wc_diff_rate_for_user', 1, 2);
add_filter( 'woocommerce_before_checkout_billing_form', 'wc_diff_rate_for_user', 1, 2 );
add_filter( 'woocommerce_product_tax_class', 'wc_diff_rate_for_user', 1, 2 );
function wc_diff_rate_for_user( $tax_class ) {
if ( !is_user_logged_in() || current_user_can( 'customer' ) ) {
$tax_class = 'Zero Rate';
}
return $tax_class;
}
I want to have the cash on delivery option only for price below 100$ and hide it automatically when cart is above 100$. The problem is that, I have 3 different payment methods right now. Paypal, cheque and COD. When a person buy something, and choose cash on delievry method, I've written a description there saying "you can choose COD if your order is below 100$". But some people neglect it and still choose COD even their purchase is above 100$. So, I want to hide COD automatically, when a purchase is above 100$. Hence, when a purchase is above 100$, there would be just two options, Paypal and Cheque.
Hope I could clarify it a bit more.
Thanks
You can use the woocommerce_available_payment_gateways hook to edit woocommerce gateways.
add_filter( 'woocommerce_available_payment_gateways' , 'change_payment_gateway', 20, 1);
/**
* remove cod gateway if cart total > 100
* #param $gateways
* #return mixed
*/
function change_payment_gateway( $gateways ){
// Compare cart subtotal (without shipment fees)
if( WC()->cart->subtotal > 100 ){
// then unset the 'cod' key (cod is the unique id of COD Gateway)
unset( $gateways['cod'] );
}
return $gateways;
}
add_filter( 'woocommerce_available_payment_gateways' , 'hide_payment_gateway', 20, 1);
function hide_payment_gateway( $gateways ){
//change whatever amount you want
if( WC()->cart->subtotal < 699 ){
// then unset the 'cod' key (cod is the unique id of COD Gateway)
unset( $gateways['cod'] );
add_action( 'woocommerce_review_order_before_payment', 'COD_exceed_amount_before_paying_notice' );
}
return $gateways;
}
function COD_exceed_amount_before_paying_notice() {
wc_print_notice( __( 'COD option not available on orders below 699.00', 'woocommerce' ), 'notice' );
}