Payment methods not showing if cart total is 0 in WooCommerce - wordpress

I'm setting up a store for a client with multiples user roles. One of them need to have prices of 0$ because the company's billed monthly. Others roles have to pay differents prices with multipliers depending on their roles using "Product Price by User Role".
Anyway, when a user buy some products for 0$ the COD method's not showing and i need that payment gateway to set a custom status.
Anyone encountered the problem before? If so, any guidance is appreciated!

"Anyone encountered the problem before?". This is default behavior in WooCommerce
To prevent this, use:
// Looks at the totals to see if payment is actually required.
function filter_woocommerce_cart_needs_payment( $needs_payment, $cart ) {
// Set true
$needs_payment = true;
return $needs_payment;
}
add_filter( 'woocommerce_cart_needs_payment', 'filter_woocommerce_cart_needs_payment', 10, 2 );
Or in short
add_filter( 'woocommerce_cart_needs_payment', '__return_true' );
AND
// Checks if an order needs payment, based on status and order total.
function filter_woocommerce_order_needs_payment( $needs_payment, $order, $valid_order_statuses ) {
// Set true
$needs_payment = true;
return $needs_payment;
}
add_filter( 'woocommerce_order_needs_payment', 'filter_woocommerce_order_needs_payment', 10, 3 );
Or in short
add_filter( 'woocommerce_order_needs_payment', '__return_true' );

Related

WooCommerce Distance Rate Shipping causing tax rate to reset

I am on the verge of losing it with this problem. So what I am attempting is to apply Zero rate tax rate when a specific coupon ('12345') is applied to the order. This site also has the plugin WooCommerce Distance Rate Shipping installed which adds its own costs and tax to the order based on billing distance.
While the billing address fields are empty, the following code successfully detects the coupon in question and sets tax rate to 'Zero Rate':
function apply_matched_coupons() {
$coupon_code = '12345';
if ( !is_admin() && WC()->cart->has_discount( $coupon_code ) ) {
$tax_class = 'Zero rate';
}
return $tax_class;
};
add_action( 'woocommerce_product_tax_class','apply_matched_coupons' );
But when an address is typed in the billing fields, the Woocommerce order update AJAX works and the WooCommerce Distance Rate Shipping plugin reads the billing addresss, re-checks its rules, applies its costs and also adds its tax. Hence, overwriting my Zero Tax rate set earlier. Screenshot is attached. I believe a hook like woocommerce_checkout_update_order_review may work which fires each time the order is updated on checkout, but can't figure out exactly how to set it.
The plugin's page here does show an example to set the $rule_cost to 0 with this code:
add_filter( 'woocommerce_distance_rate_shipping_rule_cost_distance_shipping', function( $rule_cost, $rule, $distance, $package ) {
$order_total = $package['contents_cost'];
if ( $order_total > 100 && $distance <= 5 ) {
$rule_cost = 0;
}
return $rule_cost;
}, 10, 4 );
Could this help in any way?
screenshot of extra tax added by the said plugin

Woocommerce DISABLE autocomplete € 0 orders

I wish i could just use Uncle Google but he serve me only what i DON'T want :D
I have a free Product on my website. But I want to check every order manualy, because it's only for company accounts and not for "customers".
But every order will set the Status to approved - or what ever in english language- and the order is complete.
The user has automaticaly acces to "restricted area" and that's what I don't want. I want to check every order manualy and pick every spam account.
I can imagine, this is going to work with only one simple function but I can't get it. It's only one free Product, other Products are for moneeeeey.
It would be great if somebody has the same issue and can help me :)
Thank you
Place the following function in your active theme functions.php. Check all default statuses here and change on-hold to what you want - https://woocommerce.wp-a2z.org/oik_api/wc_get_order_statuses/
function change_free_order_status( $order_id ) {
if ( ! $order_id ) {return;}
$order = wc_get_order( $order_id );
if($order->get_total() <= 0):
$order->update_status( 'on-hold' ); // Change to what you need
endif;
}
add_action('woocommerce_thankyou','change_free_order_status');

In WooCommerce how can I make it so users can only buy 1 product per order and make it so on a specific product they can only buy it once per user?

I'm building a ticketing website for events. I'm using WooCommerce and The Events Calendar plugin.
I've already made it so that users must be logged in to buy a ticket (product).
Then I found this code snippet that would limit it so that only 1 product can be purchased per order
add_filter( 'woocommerce_add_to_cart_validation', 'wc_limit_one_per_order', 10, 2 );
function wc_limit_one_per_order( $passed_validation, $product_id ) {
if ( 31 !== $product_id ) {
return $passed_validation;
}
if ( WC()->cart->get_cart_contents_count() >= 1 ) {
wc_add_notice( __( 'This product cannot be purchased with other products. Please, empty your cart first and then add it again.', 'woocommerce' ), 'error' );
return false;
}
return $passed_validation;
}
This would work, but in the first if statement you can see that the product ID has to be specified. I know I can also change this to an array like if ( ! in_array( $product_id, array( 31, 32, 33 ) ) ) { but the problem is that I would need to keep updating the IDs for every new event. Is there a way to do this so it applies to all products all the time? If not with code then maybe with settings or a plugin?
I also need to prevent customers (users) from returning to the site later and buying another ticket. So, I need to limit specific products so that only 1 of that SKU can be purchased per user account forever, meaning they can't just return to the site and start the buying process again. Is there a way to do this?
Many thanks in advance.
Is there a way to do this so it applies to all products all the time?
Sure. Just force the Cart to empty before adding a new item:
add_filter( 'woocommerce_add_to_cart_validation', 'bbloomer_only_one_in_cart', 9999, 2 );
function bbloomer_only_one_in_cart( $passed, $added_product_id ) {
wc_empty_cart();
return $passed;
}
Source and screenshot: https://www.businessbloomer.com/woocommerce-allow-1-product-cart/
I need to limit specific products so that only 1 of that SKU can be
purchased per user account forever, meaning they can't just return to
the site and start the buying process again
As #7uc1f3r said, please share the code you tried with and then we'll take a look

Woocommerce subscription : apply coupon for renewal orders

I want to apply a coupon when a renewal order for a subscription is created.
I use stripe as payment gateway for woocommerce subscription.
I found the filter 'wcs_renewal_order_created' from the docs : https://docs.woocommerce.com/document/subscriptions/develop/filter-reference/
I manage to apply it, it's well trigger and I can apply a coupon to this order.
The order amount is reduce by the amount of the coupon.
Problem: Stripe charges the full amount of the order, without the discount. It's just like if the order I changed was not used by Stripe.
Here is the code sample, that reduce by 5 any renewal order :
function gens_renewal_order_created($order, $subscription){
$order = new WC_Order( $order->id );
$order->set_total($order->get_total() - 5);
return $order;
}
This is a bit late but there has been no reply.
If you take a look at 'wcs_create_order_from_subscription()'
This the function where the new order is created. here also has a different filter that isn't mentioned within the documentation 'wcs_new_order_created'.
So here is what your code should be.
function gens_renewal_order_created($order, $subscription){
$order = new WC_Order( $order->id );
$order->set_total($order->get_total() - 5);
return $order;
}
add_filter('wcs_new_order_created','gens_renewal_order_created', 10, 2 );

Woocommerce "No Shipping methods" message: Customise message based on the Zipcode customer enters

Our store has been setup to process orders only within Sydney city. We manage this in Woocommerce by setting the allowed postcodes for a Flat Rate Delivery.
We are now extending deliveries to other other areas but only via telephone (no online orders for these new postcodes). Woocommerce displays a standard No Shipping message but we would to customise such that
Customer enters a postcode within the city, allow online orders. No
change to current behaviour.
Customer enters a postcode for which
telephone orders are allowed, show a customised message asking the
customer to make the call.
All other postcodes, disallow orders.
Any technical direction will be greatly appreciated.
Thanks.
Below code should help you. Change the value of array variable $zip_array in both the functions as a comma separated list of zip codes, which you want to show a custom message. Also, change the string value of $custom_msg to your custom message. More details, please refer this article.
// For Cart Page.
add_filter( 'woocommerce_no_shipping_available_html', 'wf_customize_default_message', 10, 1 );
// For Checkout page
add_filter( 'woocommerce_cart_no_shipping_available_html', 'wf_customize_default_message', 10, 1 );
function wf_customize_default_message( $default_msg ) {
$zip_array = array(
'30031',
);
if ( in_array( WC()->customer->get_shipping_postcode() , $zip_array) ) {
$custom_msg = "Call us for quotation - 1-800-XXX-XXXX";
if( empty( $custom_msg ) ) {
return $default_msg;
}
return $custom_msg;
}
return $default_msg;
}
add_filter('woocommerce_package_rates', 'wf_remove_shipping_options_for_particular_zip_codes', 8, 2);
function wf_remove_shipping_options_for_particular_zip_codes($rates, $package)
{
global $woocommerce;
$zip_array = array(
'30031',
);
if ( in_array( $woocommerce->customer->get_shipping_postcode() , $zip_array) ) {
$rates = array();
}
return $rates;
}

Resources