Hide shipping and payment methods in WooCommerce - wordpress

I'm building a WooCommerce e-shop and I need to tweak my checkout page by doing the following:
Hide a certain shipping method (only one) if the order total > 100€.
Hide the cash on delivery payment method if local pickup is selected.
Does anyone know how to do that? I have the Code Snippets plugin so I can easily add any custom code.

To hide specific shipping method based on the cart total, you can use below code snippet. You need to update your shipping method name in the code.
Disable shipping method as per cart total
Add this snippet in your theme's functions.php file or custom plugin file.
add_filter( 'woocommerce_package_rates', 'shipping_based_on_price', 10, 2 );
function shipping_based_on_price( $rates, $package ) {
$total = WC()->cart->cart_contents_total;
//echo $total;
if ( $total > 100 ) {
unset( $rates['local_delivery'] ); // Unset your shipping method
}
return $rates;
}
Disable Payment Gateway For Specific Shipping Method
Use below code snippet. Update code as per your payment method & shipping method.
add_filter( 'woocommerce_available_payment_gateways', 'x34fg_gateway_disable_shipping' );
function x34fg_gateway_disable_shipping( $available_gateways ) {
global $woocommerce;
if ( !is_admin() ) {
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if ( isset( $available_gateways['cod'] ) && 0 === strpos( $chosen_shipping, 'local_pickup' ) ) {
unset( $available_gateways['cod'] );
}
}
return $available_gateways;
}

There are a number of plugins that will do this for you, take a look at this one WooCommerce Conditional Shipping and Payments
You'll want to tie in to the "woocommerce_payment_gateways" action
Something along these lines:
function alter_payment_gateways( $gateways ){
$chosen_rates = ( isset( WC()->session ) ) ? WC()->session->get( 'chosen_shipping_methods' ) : array();
if( in_array( 'local-pickup:6', $chosen_rates ) ) {
$array_diff = array('cod');
$list = array_diff( $list, $array_diff );
}
return $list;
}
add_action('woocommerce_payment_gateways', 'alter_payment_gateways', 50, 1);
The number on the end of 'local-pickup' on line 4 will depend on your woocommerce setup. You can find the string you need to put in here by adding something to a basket, going to the checkout, right clicking on the "Local Pickup" option in the delivery methods and looking at the value attribute.

Related

Can't pass custom cart item data to WC()->cart->add_to_cart() woocommerce 4.9

I'm working on woocommerce API plugin development and trying to pass custom cart item data using the below code in add to cart API endpoint.
$cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations, array('margin' => 200));
and want to use that custom cart item data on woocommerce_before_calculate_totals hook (see code below) but can't getting custom cart item data ($cart_item['margin']) there.
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 30, 1 );
function custom_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart->get_cart() as $cart_item ) {
if( isset($cart_item['margin']) ){
$final_price = ($cart_item['data']->get_price() + $cart_item['margin']);
$cart_item['data']->set_price($final_price);
}
}
}
I have installed Woocommerece 4.9 version, please help me to solve this issue.
Thanks in advance.
I had kind of the same problem, the issue was there was another plugin that might have a higher priority on the filter. It was a Role based pricing plugin, after deactivating it, everything worked. So just check if there is no other thing overwriting the function.
To do a test I used the woocommerce_add_to_cart_validation hook and I added a product to cart with add_to_cart() method of the WC_Cart class.
add_action( 'woocommerce_add_to_cart_validation', 'add_product_to_cart_programmatically', 10, 3 );
function add_product_to_cart_programmatically( $passed, $product_id, $quantity) {
$product_id = 166; // product id to add
$quantity = 10; // quantity product to add
WC()->cart->add_to_cart( $product_id, $quantity, 0, array(), array( 'margin' => 200 ) );
return $passed;
}
Once the product has been added to the cart, I can apply a custom price based on the custom cart item data:
add_action( 'woocommerce_before_calculate_totals', 'custom_cart_item_price', 30, 1 );
function custom_cart_item_price( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) )
return;
foreach ( $cart->get_cart() as $cart_item ) {
if ( isset( $cart_item['margin'] ) && ! empty( $cart_item['margin'] ) ) {
$final_price = $cart_item['data']->get_price() + $cart_item['margin'];
$cart_item['data']->set_price( $final_price );
}
}
}
As recommended by #danielsalare you can try to increase the priority of the action, as in my example above.
I had a similar problem and found this solution: First, we add the custom products to Woocommerce. Second, we generate an identifier (ID), and later we add it.
for example, obtain product-id trow a with $_POST
$myProduct = $_POST['myProduct'];
$myProduct_id = WC()->cart->generate_cart_id($myProduct);
if (!WC()->cart->find_product_in_cart($myProduct_id )) {
WC()->cart->add_to_cart($myProduct);
}

Wordpress variable, user created, woocommerce product

Basically I am interested in using woocommerce to sell a product . This product is a Print Order of a external printing service that I have implemented in a brand new plugin.
What I want now is after the order, is to be able to put that "order" in the buy cart, and buy it normally as just another woocommerce product.
The product has to be created on the fly, manually by a way of some function that I can use to create a product during a certain workflow point.
Can you help me to find a solution?
Using woocommerce or not!
What i understand from your requirement/comments is that you want to be able to dynamically create a product, which is bad idea. But here is my suggestion.
Lets say you have a simple product called "Print Job" with a price of $1 and with an id of 10. And i am supposing that your external printing service would send back a response with the order and the price of printing, lets say $64.
Once you recieve the response you can simply call add_product_to_cart(10), this will automatically add the print job product to your cart.
/************* functions.php ***************/
function add_product_to_cart($product_id) {
if ( ! is_admin() ) {
$found = false;
//check if product already in cart
if ( sizeof( WC()->cart->get_cart() ) > 0 ) {
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$_product = $values['data'];
if ( $_product->id == $product_id )
$found = true;
}
// if product not found, add it
if ( ! $found )
WC()->cart->add_to_cart( $product_id );
} else {
// if no products in cart, add it
WC()->cart->add_to_cart( $product_id );
}
}
}
You also need to add this function in your functions.php, this function will override the price of the product i.e "Print Job" with the actual price of $64.
/******************* Functions.php ****************/
add_action( 'woocommerce_before_calculate_totals', 'override_printing_price' );
function override_printing_price( $cart_object ) {
$custom_price = 64;
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}

Woocommerce : how to Disable "Free shipping" if Coupon applied?

I'm using woocommerce plugin for online shop.
I set free shipping option after certain amount of order.
how to disable "free shipping" option if coupon applied?
Based on a quick google lookup.
add_filter( 'woocommerce_shipping_packages', function( $packages ) {
$applied_coupons = WC()->session->get( 'applied_coupons', array() );
if ( ! empty( $applied_coupons ) ) {
$free_shipping_id = 'free_shipping:2';
unset($packages[0]['rates'][ $free_shipping_id ]);
}
return $packages;
} );
Where $free_shipping_id is set to the id of your free shipping method.

Wordpress woocommerce - hide flat rate when free shipping

I have one wordpress/woocommerce site. When user cart amount is over 500 i must have free shipping in cart subtotal. Right now i have setup flat rate 25 and free shipping if amount is more then 500.
I google it from help and add some code into functions.php but still have same problem.
function hide_all_shipping_when_free_is_available( $available_methods ) {
if( isset( $available_methods['free_shipping'] ) ) :
// Get Free Shipping array into a new array
$freeshipping = array();
$freeshipping = $available_methods['free_shipping'];
// Empty the $available_methods array
unset( $available_methods );
// Add Free Shipping back into $avaialble_methods
$available_methods = array();
$available_methods['free_shipping'] = $freeshipping;
endif;
return $available_methods;
}
i use wordpress with woocommerce 2.3.8 on Oxygen theme.
Best regards
You're using the old method, you need to use this new one I think.
Copied from WooThemes website:
add_filter( 'woocommerce_package_rates','hide_shipping_when_free_is_available', 10, 2 );
function hide_shipping_when_free_is_available( $rates, $package ) {
// Only modify rates if free_shipping is present
if ( isset( $rates['free_shipping'] ) ) {
// To unset a single rate/method, do the following. This example unsets flat_rate shipping
unset( $rates['flat_rate'] );
// To unset all methods except for free_shipping, do the following
$free_shipping = $rates['free_shipping'];
$rates = array();
$rates['free_shipping'] = $free_shipping;
}
return $rates;
}

How to Hide Payment Method in Woocommerce based on Postal Code

In this woocommerce setup, I have 2 Payment methods, Paypal and Cash on Delivery.
Now how can Cash on Delivery be hidden/disabled for certain Postal codes only.
This is the code I found on Gist
// Disable gateway based on country
function payment_gateway_disable_country( $available_gateways ) {
global $woocommerce;
if ( isset( $available_gateways['ccavenue'] ) && $woocommerce->customer->get_country() <> 'IN' ) {
unset( $available_gateways['ccavenue'] );
} else if ( isset( $available_gateways['paypal'] ) && $woocommerce->customer->get_country() == 'IN' ) {
unset( $available_gateways['paypal'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
Gist Link
To disable/hidden "Cash on Delivery", Place this code in your theme's function.php .
For more detail: woocommerce-hide-payment-gatway-based-on-visitors-country
// Disable gateway based on country
function payment_gateway_disable_country( $available_gateways ) {
global $woocommerce;
if ( isset( $available_gateways['cod'] ) && $woocommerce->customer->get_country() <> 'IN' ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
In the "checkout page" user can have two addresses - billing and shipping one.
To work correctly only with changes of Shipping one if it's filled I changed a bit the code. You have to test shipping countrycode if it's set, if not just user countrycode:
function payment_gateway_disable_country( $available_gateways ) {
global $woocommerce;
$country = !empty($woocommerce->customer->get_shipping_country()) ? $woocommerce->customer->get_shipping_country() : $woocommerce->customer->get_country();
if ( isset( $available_gateways['cod'] ) && $country <> 'CZ' ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_country' );
In the code above you used country code to disable payment gateway by, but you mentioned you would like to do it by Postal Code.
You're right about using woocommerce_available_payment_gateways, but instead of using $woocommerce->customer->get_country() you have to use WC()->customer->get_shipping_postcode() (or WC()->customer->get_billing_postcode() for some situations).
You mentioned PayPal and Cash on Delivery payment gateway, we need their IDs, there are paypal and cod accordingly.
In the code below let's deactivate Cash on Delivery for a couple postal codes, for example '1234' and '5678':
add_filter( 'woocommerce_available_payment_gateways', function( $available_gateways ) {
// if Cash on Delivery is already disabled, let's exit the function
if( empty( $available_gateways['cod'] ) ) {
return $available_gateways['cod'];
}
// get postal code
$postal_code = WC()->customer->get_billing_postcode();
// deactivate payment method
if( in_array( $postal_code, array( '1234', '5678' ) ) ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
} );
Code can be inserted to your current theme functions.php file or a custom plugin. More info you can find in this tutorial: https://rudrastyh.com/woocommerce/hide-payment-methods-based-on-postal-code.html

Resources