Adding a hook to "Place order" button in woocommerce - wordpress

When the user gets to the checkout, there is a button , the "Place order" button at the bottom of the form. I have been trying to add a hook to this button in woocommerce, but I don't seem to find the correct one, I have tried woocommerce_checkout_place_order... but it doesnt do anything.
function my_function() {
//write function
}
add_action( "woocommerce_order_status_pending", "my_function");
Thanks in advance!

You need this hook woocommerce_review_order_after_submit. It will execute any function you hook to it just after the submit area. with this hook you can add some html on the checkout page after the submit button.
But if you need to call a function after the user have pressed the "Place order" button - use woocommerce_checkout_order_processed. This one will hook you just after the order was created so you can use the freshly generated order details:
add_action( 'woocommerce_checkout_order_processed', 'is_express_delivery', 1, 1 );
function is_express_delivery( $order_id ){
$order = new WC_Order( $order_id );
//something else
}
You may check this site for some more hooks you might use on the checkout page.

## I USED THIS CODE FOR ADDING DELIVERY CHARGES DEPENDING UPON THE CART SUBTOTAL AND SOME POST FIELDS ##
function action_woocommerce_checkout_process($wccs_custom_checkout_field_pro_process )
{
global $woocommerce;
//Add Fuel Surcharge & CAF
function woo_add_cart_fee() {
global $woocommerce;
if ( WC()->cart->cart_contents_total < 1500 &&
$_POST['delivery_type']=='Pick Up') {
$fuel_surchargeandCAF = get_option( 'fuel_surchargeandCAF',
70 );
WC()->cart->add_fee( __('Delivery Charges', 'woocommerce'),
$fuel_surchargeandCAF, TRUE, '');
}
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' );
};
add_action( 'woocommerce_checkout_process', 'action_woocommerce_checkout_process', 10,
1 );

Related

How to update Order meta data, from a WooCommerce Action

I'm trying to add some custom meta_data to a WooCommerce Order, by running a Order action.
Here is my code:
function custom_add_order_actions( $actions ){
global $theorder;
$actions['my_custom_action'] = 'My custom action';
return $actions;
}
add_action( 'woocommerce_order_actions', 'custom_add_order_actions' );
function custom_add_single_action( $order ){
// Non of these change anything on the order
$order->set_billing_first_name( 'A new test name' );
$order->update_post_meta( 'a_test_field', 'Test field value' );
update_post_meta( $order->get_id(), 'a_test_field', 'Some other value' );
// $order->save(); // I even tried adding this as well, but it doesn't change anything.
}
add_action( 'woocommerce_order_action_my_custom_action', 'custom_add_single_action' );
How do I change the order (or specifically, post_meta fields for an order) from inside an action?
A example
Imagine that I add a post_meta field, with the field name (key): a_test_field.
It's currently an ACF-field, but it's the same for regular WordPress custom fields.
If I change the value of the field and press 'Update', then the value changes:
So far so good. Now the value of the field is 'Foobar'.
What's wierd is that even if I do this:
add_action( 'woocommerce_order_action_my_custom_action', 'custom_add_single_action' );
function custom_add_single_action( $order ){
update_post_meta( $order->get_id(), 'a_test_field', 'A new value' );
die(); // This die is vital, to make the change in the database.
}
Then I can see the value change in the database to 'A new value'.
But if I just do this:
add_action( 'woocommerce_order_action_my_custom_action', 'custom_add_single_action' );
function custom_add_single_action( $order ){
$order->update_post_meta( 'a_test_field', 'A new value' );
// No die(); here...
}
Then the value remains 'Foobar' in the database.
Sorry but the following lightly revisited code works (Selecting the action and click on the button arrow):
add_action( 'woocommerce_order_actions', 'add_custom_order_action' );
function add_custom_order_action( $actions ){
$actions['my_custom_action'] = __('My custom action', 'WooCommerce');
return $actions;
}
add_action( 'woocommerce_order_action_my_custom_action', 'triggered_custom_order_action' );
function triggered_custom_order_action( $order ){
$order->update_meta_data( '_test_1_custom_field', 'AAFFBB9977' );
$order->save();
update_post_meta( $order->get_id(), '_test_2_custom_field', 'Some other value' );
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Note: Order actions are mostly used for some other things than what you are trying to do.
Now when using a meta box with an input field (as you are showing), on submit, you should save that field value using the action hook save_post_shop_order like in those related threads:
Metabox with multi checkbox in WooCommerce admin single orders
Dynamic custom order numbers based on payment method
Metabox with multiple custom fields for WooCommerce admin order pages

Error with: WooCommerce Avoid add to cart for non logged user

I wondered if anyone can help me?
I am using a Wordpress site with Woocommerce plugin.
I am using a piece of code to avoid adding to cart for non logged in customers which I found on this site, it works great apart from one issue. It doesn't work on the product page. When you click the add to cart button, it doesn't redirect to the custom login page like it does if you press the button on the category view page. Instead the page just refreshes.
I put the code in to the functions.php file. I've then tried putting it into a few other places but that hasn't worked. Could anyone help me with this and let me know if there is another location I should be putting the code in? Thanks in advance, I'd really appreciate the help!
Here's the link to the question and the code is below: WooCommerce Avoid add to cart for non logged user
// Replacing add-to-cart button in shop pages and archives pages (forn non logged in users)
add_filter( 'woocommerce_loop_add_to_cart_link', 'conditionally_change_loop_add_to_cart_link', 10, 2 );
function quantity_inputs_for_woocommerce_loop_add_to_cart_link( $html, $product ) {
if ( ! is_user_logged_in() ) {
$link = get_permalink($product_id);
$button_text = __( "View product", "woocommerce" );
$html = ''.$button_text.'';
}
return $html;
}
// Avoid add to cart for non logged user (or not registered)
add_filter( 'woocommerce_add_to_cart_validation', 'logged_in_customers_validation', 10, 3 );
function logged_in_customers_validation( $passed, $product_id, $quantity) {
if( ! is_user_logged_in() ) {
$passed = false;
// Displaying a custom message
$message = __("You need to be logged in to be able adding to cart…", "woocommerce");
$button_link = get_permalink( get_option('woocommerce_myaccount_page_id') );
$button_text = __("Login or register", "woocommerce");
$message .= ' '.$button_text.'';
wc_add_notice( $message, 'error' );
}
return $passed;
}
Firstly, your function hook for woocommerce_loop_add_to_cart_link is incorrect. You are using conditionally_change_loop_add_to_cart_link rather than quantity_inputs_for_woocommerce_loop_add_to_cart_link.
Secondly, your URL for the link is using the current product page ID, which is going to point you at the current product page URL and not another page.
Other than that, you had it mostly correct with woocommerce_add_to_cart_validation.
EDIT:
For product single pages, if you look at content-single-product.php in Woocommerce, the action woocommerce_template_single_add_to_cart seems to handle what the "add to cart" form looks like. If you'd like to not show the add to cart form, you'll want to first remove the action from the woocommerce_single_product_summary hook.
if(!is_user_logged_in()) {
remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart',30);
}
Then add your own action in at that priority to put in your message:
add_action('woocommerce_single_product_summary', function() {
global $product_id;
if(!is_user_logged_in()) {
$message = __("You need to be logged in to be able adding to cart…", "woocommerce");
$button_link = get_permalink( get_option('woocommerce_myaccount_page_id') );
$button_text = __("Login or register", "woocommerce");
$message .= ' '.$button_text.'';
echo $message;
}
});
yes, you can do it by just adding following code into your active theme function.php file.
add_filter('woocommerce_get_price_html','login_before_addtocart');
function login_before_addtocart($price){
if(is_user_logged_in() ){
return $price;
}
else {
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart' );
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30 );
$response .= $price;
$response .= '<br> Login to add product into cart';
return $response;
}
}

disable postcode validation in WooCommerce checkout page

Does anybody know how to disable the Postcode validation on the checkout page in WooCommerce?
I want to input 'text content' in "billing_postcode" field, but the shop says it's an invalid postcode.
Does anyone know how I can disable Postcode validation or allow text characters?
Just do this:
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields', 99 );
function custom_override_checkout_fields( $fields ) {
unset($fields['billing']['billing_postcode']['validate']);
unset($fields['shipping']['shipping_postcode']['validate']);
return $fields;
}
You can put this pretty much anywhere, but preferably in a custom plugin or in your theme's functions.php
You could try this:
add_filter( 'woocommerce_default_address_fields', 'custom_override_address_fields', 999, 1 );
function custom_override_address_fields( $address_fields ) {
// set as not required
$address_fields['postcode']['required'] = false;
// remove validation
unset( $address_fields['postcode']['validate'] );
return $address_fields;
}

WooCommerce code - Dynamically add a surcharge to cart and checkout

I've added 2 radio buttons to my WooCommerce cart. However I want to add a surcharge when one is slected but not the other, and I want it to update the check out data that is displayed.
I know I can do this to add the surcharge all time:
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
function woocommerce_custom_surcharge() {
global $woocommerce;
$surcharge = 5.32;
$woocommerce->cart->add_fee( 'Surcharge', $surcharge, true, '' );
}
however how to I control it to add this or not based on which radio button I have selected?
The best way is with ajax (untested code):
<input type="radio" name"surcharge" value="5.32" class="surcharge" />
<script>
$(document).ready(function () {
$(".surcharge").click(function(){
$.ajax({
url: "where_is_your.php", // Name of PHP script
type: "POST",
data: {
action: $(this).val(), //here you get the value 5.32
}
}).done(function(data) {
alert( data.message ); //your success message if you want it
});
})
})
</script>
and your php:
add_action( 'woocommerce_cart_calculate_fees','woocommerce_custom_surcharge' );
$surcharge = $_POST['action'];
function woocommerce_custom_surcharge() {
global $woocommerce;
$woocommerce->cart->add_fee( 'Surcharge', $surcharge, true, '' );
}
<?php
/**
* WooCommerce Extra Feature
* --------------------------
*
* Add custom fee to cart automatically
*
*/
function woo_add_cart_fee() {
global $woocommerce;
$woocommerce->cart->add_fee( __('Custom', 'woocommerce'), 5 );
}
add_action( 'woocommerce_cart_calculate_fees', 'woo_add_cart_fee' ); ?>
You can use "woocommerce_cart_calculate_fees" to add surcharge money with an amount to your theme, and plus AJAX as above will help you out.
Well I solved this by creating an AJAX to handle the buttons and then in the PHP callback issuing a WC->session->set to set a session variable. Upon return, I then issue a location.reload() which refreshes the page but does not clear the cache. That way when the functions.php are loaded again, inside the surcharge function I added as a action_add, I can query the session variable to see which of the radio buttons were clicked and add the appropriate cart->add_fee.

WooCommerce pass order data into woocommerce_checkout_update_user_meta

I'm trying to add user_meta upon checkout in WooCommerce. Currently I'm using woocommerce_checkout_update_user_meta action to update user meta. I'd like to pass some of the order data itself in as well specifically I'd like to make the order id the value of the meta like so...
function woocommerce_add_my_user_meta( $user_id ) {
global $woocommerce;
update_user_meta( $user_id, 'purchased', ''.$order->ID.'' );
}
add_action('woocommerce_checkout_update_user_meta', 'woocommerce_add_my_user_meta');
This however is not working. It's just adding a blank purchased user meta.
Any help greatly appreciated.
You could use the woocommerce_checkout_update_order_meta hook
// Use hook after checkout
add_action( 'woocommerce_checkout_update_order_meta', 'do-additional-stuff-on-checkout', 10, 2 );
// Things you want to be done when hook is called
function do-additional-stuff-on-checkout( $order_id, $post_values ) {
// get user
$current_user = wp_get_current_user();
// update
update_user_meta( $current_user->ID, 'purchased', $order_id );
}

Resources