I want to set the billing phone number required or not required based on the shipping method.
I have set the shipping method as an array and checked it from the session selected shipping method but it not working
add_filter('woocommerce_checkout_fields', 'fire_remove_billing_checkout_fields');
function fire_remove_billing_checkout_fields($fields) {
global $woocommerce;
$methods = array('flat_rate:2', 'flat_rate:3', 'flat_rate:17', 'flat_rate:20');// Set shipping method to hide the checkout field(s).
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
$chosen_shipping = $chosen_methods[0];
if(in_array($chosen_shipping, $methods)){
$fields['billing']['billing_phone'][ 'required' ] = true;
}else{
$fields['billing']['billing_phone'][ 'required' ] = false;
}
return $fields;
}
Your code works well for me. I've added my shipping rate IDs and it works as expected, however refresh of the page is necessary, because WooCommerce doesn't refresh the billing fields natively on update_checkout trigger.
You should either reload the page using Javascript/jQuery on updated_checkout event, or reload only the billing fields using AJAX like so:
add_action( 'wp_footer', 'reload_billing_fields_on_updated_checkout' );
function reload_billing_fields_on_updated_checkout() {
?>
<script>
jQuery(document.body).on('updated_checkout', () => {
jQuery('.woocommerce-billing-fields').load(`${location.href} .woocommerce-billing-fields>*`, '');
});
</script>
<?php
}
Keep in mind that it might take a short while for those fields to reload, so you might want to add some loading CSS classes, or maybe a spinner.
I am unsetting some checkout fields in Woocommerce via code and I am a little stumped on how to unset some custom checkout fields (not default Woocommerce checkout fields). Note that I am using Custom WooCommerce Checkout Fields Editor and Delivery & Pickup Date Time for WooCommerce third party plugins.
Below is the code I am writing that unsets some of the woocommerce related fields (billing, shipping and order):
/**
Remove following checkout fields
**/
function wc_remove_checkout_fields( $fields ) {
// Billing fields
unset( $fields['billing']['billing_company'] );
unset( $fields['billing']['billing_state'] );
// Shipping fields
unset( $fields['shipping']['shipping_company'] );
unset( $fields['shipping']['shipping_state'] );
unset( $fields['shipping']['shipping_country'] );
// Order fields
unset( $fields['order']['order_comments'] );
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'wc_remove_checkout_fields' );
HTML of delivery data field:
<input type="text" class="input-text flatpickr-input active" name="coderockz_woo_delivery_date_field" id="coderockz_woo_delivery_date_datepicker" placeholder="Delivery Date" value="" data-selectable_dates="365" data-disable_week_days="[]" data-date_format="F j, Y" data-disable_dates="[]" data-week_starts_from="0" data-default_date="1" readonly="readonly">
But how do I unset some custom checkout fields added via a third party plugin?
••• Edit •••
$hide_pickup_date_time = array('coderockz_woo_delivery_delivery_date_field');
foreach($hide_pickup_date_time as $pickup_date_time ) {
if ($chosen_shipping_pickup == $shipping_method_pickup) {
$fields_pickup['order'][$pickup_date_time]['required'] = false;
}
}
Plugin screenshot
I am looking for solution where I can find user's country in woocommerce checkout page. I am doing it via geolocation. However, the user can change that. I want to restrict it.
I am using a paid plugin to give coupons to users from a specific country. The country gets loaded perfectly and coupon is applied or rejected based on country. However, the user manually can change the country at the checkout page and avail the discount. My service is online thus there is no delivery of physical goods so entering wrong country wouldn't cause anything to the user.
I have tried 2-3 different coupon restriction plugins but all has the same problem. Does anyone has faced similar issue?
Updated
You can make checkout country dropdown fields disabled (read only) as follows:
add_filter( 'woocommerce_checkout_fields', 'checkout_country_fields_disabled' );
function checkout_country_fields_disabled( $fields ) {
$fields['billing']['billing_country']['custom_attributes']['disabled'] = 'disabled';
$fields['billing']['shipping_country']['custom_attributes']['disabled'] = 'disabled';
return $fields;
}
As disabled select fields doesn't get posted, you need additionally the following duplicated hidden fields with the correct values set in. It will avoid an error notice notifying that country required fields values are empty. So add this too:
// Mandatory for disable fields (hidden billing and shipping country fields with correct values)
add_filter( 'woocommerce_after_checkout_billing_form', 'checkout_country_hidden_fields_replacement' );
function checkout_country_hidden_fields_replacement( $fields ) {
$billing_country = WC()->customer->get_billing_country();
$shipping_country = WC()->customer->get_shipping_country();
?>
<input type="hidden" name="billing_country" value="<?php echo $billing_country; ?>">
<input type="hidden" name="shipping_country" value="<?php echo $shipping_country; ?>">
<?php
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Notes:
You will need to disable shipping calculator in cart page, if it's not done.
If you want to make country dropdown read only in Checkout and in My account Edit Address too, use the following instead:
add_filter( 'woocommerce_billing_fields', 'checkout_billing_country_field_disabled' );
function checkout_billing_country_field_disabled( $fields ) {
$fields['billing_country']['custom_attributes']['disabled'] = 'disabled';
return $fields;
}
add_filter( 'woocommerce_shipping_fields', 'checkout_shipping_country_field_disabled' );
function checkout_shipping_country_field_disabled( $fields ) {
$fields['shipping_country']['custom_attributes']['disabled'] = 'disabled';
return $fields;
}
// Mandatory for disable fields (hidden billing and shipping country fields with correct values)
add_filter( 'woocommerce_after_checkout_billing_form', 'checkout_country_hidden_fields_replacement' );
function checkout_country_hidden_fields_replacement( $fields ) {
$billing_country = WC()->customer->get_billing_country();
$shipping_country = WC()->customer->get_shipping_country();
?>
<input type="hidden" name="billing_country" value="<?php echo $billing_country; ?>">
<input type="hidden" name="shipping_country" value="<?php echo $shipping_country; ?>">
<?php
}
I can unset fields from billing and shipping but why I can't unset fields from additional field section. I am adding a condition on these fields. Maybe I am using wrong meta keys.
function wc_remove_checkout_field( $fields ) {
unset( $fields['billing']['test_field'] ); //this one working
unset( $fields['additional']['delivery_time'] ); //this one not even if I replace additional with order.
return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'wc_remove_checkout_field' );
Creating fields usings this plugin WooCommerce Checkout Field Editor
You can use this filter to remove the order notes field:
add_filter('woocommerce_enable_order_notes_field', '__return_false');
If you want to stick with your method using unset, you need to replace "additional" with "order":
unset($fields['order']['order_comments']);
I created an ecommerce using the plugin woocommerce. I am selling only a subscription so the "/cart/" page is useless. I'm trying to get rid of it so that when my customer click on "Add to cart" button, he ends up on the checkout page.
In WooCommerce 3.6 or later you can use woocommerce_add_to_cart_redirect (props #roman)
add_filter ('woocommerce_add_to_cart_redirect', function( $url, $adding_to_cart ) {
return wc_get_checkout_url();
}, 10, 2 );
Original answer:
you can use a filter in functions.php:
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
global $woocommerce;
$checkout_url = $woocommerce->cart->get_checkout_url();
return $checkout_url;
}
it doesn't seem to work with ajax, but it works from the single product pages, which I think is what you use
On WooCommerce (>= 2.1) the function can be simplified as:
function redirect_to_checkout() {
return WC()->cart->get_checkout_url();
}
There is an option within WooCommerce settings that allows you to enable this functionality:
Simply login to your WP admin panel > WooCommerce > Catalog and select the option. I hope this helps!
I've found a simple solution that work like magic.
As mentioned by #Ewout, check the box that says "Redirecto to cart page after succesful addtion".
Woocommerce > Settings > Checkout (Tab) - where you should select pages for cart and checkout, select the checkout page as the cart page (image attached).
That's it. works for me.
Update for WooCommerce 3.5.1
Step 1.
First of all go to WooCommerce Products settings and deactivate AJAX add to cart.
Step 2.
Use woocommerce_add_to_cart_redirect hook to make a redirect to checkout.
add_filter( 'woocommerce_add_to_cart_redirect', function( $url ) {
return wc_get_checkout_url();
});
Of course there some small things are left to do, like changing add to cart buttons text and removing some WooCommerce cart-related notices. I recommend to check this tutorial for more https://rudrastyh.com/woocommerce/redirect-to-checkout-skip-cart.html
#RemiCorson posted this brief but beneficial tutorial:
http://www.remicorson.com/woocommerce-skip-product-cart-pages/
He mentions the same filter as #Ewout above,
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
global $woocommerce;
$checkout_url = $woocommerce->cart->get_checkout_url();
return $checkout_url;
}
but one line of code stands out and is of super value for me for my current woocommerce project:
There is a direct link that a user can use to automatically bypass the product page.
http://your-site.com/?add-to-cart=37
'37' will be replaced by your product ID.
This was useful for me to eliminate unnecessary steps and take users directly to checkout from the home page and other non-woocommerce pages/posts.
Filter add_to_cart_redirect is deprecated in WooCommerce 2.6. Use woocommerce_add_to_cart_redirect instead.
Add this to your functions.php :
add_filter ('woocommerce_add_to_cart_redirect', function() {
return WC()->cart->get_checkout_url();
} );
Try the below code in the themes function.php file
add_filter( 'woocommerce_add_to_cart_redirect', 'woo_skip_cart_redirect_checkout' );
function woo_skip_cart_redirect_checkout( $url ) {
return wc_get_checkout_url();
}
On shop page, if you want use ajax and redirect toghether. The second method only when there are some condition, you can use this filter and leave on Woocommerce setting ajax enabled:
add_filter('woocommerce_loop_add_to_cart_link', array( $this, 'add_quantity_input' ), 4, 2);
to remove on a class attribute ajax_add_to_cart and change the href value to checkout url page;
On my template case:
public function add_quantity_input($text = null, $product = null) {
global $product, $woocommerce;
if ( $text != null and $product != null ) {
if(ismycondition($product->id)) {
$s = explode('class="', $text);
$s[2]=str_replace('ajax_add_to_cart', '', $s[2]);
$text = implode('class="', $s);
$text = preg_replace('/<a(.*)href="([^"]*)"(.*)>/','<a$1href="'.$woocommerce->cart->get_checkout_url().'"$3>', $text);
}
}
return $text;
}
I hope that this help.
None of the solutions actually worked out for me, the filter add_to_cart_redirect was triggering on every page,not only on the cart.I did some modification on the suggested answer.
add_filter ('add_to_cart_redirect', 'redirect_to_checkout');
function redirect_to_checkout() {
if(is_cart()){
$checkout_url = WC()->cart->get_checkout_url();
?>
<script>
location = '<?=$checkout_url?>';
</script>
<?php
}
}