I want to make sure the cancel button is not visible in my-account> my-order when 'Payment Method Title' is 'Npay'.
The 'Npay' is an external payment gateway and does not work with the commerce. Therefore, payment cancellation must be done externally only.
add_filter('woocommerce_my_account_my_orders_actions', 'remove_my_cancel_button', 10, 2);
function remove_my_cancel_button($actions, $order){
if ( $payment_method->has_title( 'Npay' ) ) {
unset($actions['cancel']);
return $actions;
}
}
To remove the cancel button from My account Orders, we use the following:
add_filter('woocommerce_my_account_my_orders_actions', 'remove_myaccount_orders_cancel_button', 10, 2);
function remove_myaccount_orders_cancel_button( $actions, $order ){
unset($actions['cancel']);
return $actions;
}
But to remove the cancel button from My account Orders based on the payment title, you will use the WC_Order method get_payment_method_title() like:
add_filter('woocommerce_my_account_my_orders_actions', 'remove_myaccount_orders_cancel_button', 10, 2);
function remove_myaccount_orders_cancel_button( $actions, $order ){
if ( $order->get_payment_method_title() === 'Npay' ) {
unset($actions['cancel']);
}
return $actions;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
The main variable argument $actions need to be returned at the end outside the IF statement
Related
As I sell virtual products I don’t need the WooCommerce shipping address fields. I've already removed them from the checkout page and also want to remove them from the “My Account” page.
In the dashboard under the „Edit address“ tab the user should be directed directly to the page where he can edit the billing address. The page that shows the billing / shipping address and where the user has to click on "Edit address" is not longer needed.
Is there a way to achieve this? Any help is appreciated.
You can unset the Address endpoint and create a new one for Billing. For example, in your functions.php add the following code.
//1
function add_d_endpoint() {
add_rewrite_endpoint( 'billing', EP_ROOT | EP_PAGES );
}
add_action( 'init', 'add_d_endpoint' );
//2
function d_query_vars( $vars ) {
$vars[] = 'billing';
return $vars;
}
add_filter( 'query_vars', 'd_query_vars', 0 );
//3
function add_d_link_my_account( $items ) {
$items[ 'billing' ] = 'Billing Address'; //The title of new endpoint
return $items;
}
add_filter( 'woocommerce_account_menu_items', 'add_d_link_my_account' );
//4
function d_content() {
echo WC_Shortcode_My_Account::edit_address( 'billing' ); //The content of new endpoint
}
//5
add_action( 'woocommerce_account_billing_endpoint', 'd_content' );
// Note: add_action must follow 'woocommerce_account_{your-endpoint-slug}_endpoint' format
//6
/** Remove Address from My Account Menu **/
add_filter( 'woocommerce_account_menu_items', 'dsx_remove_my_account_dashboard' );
function dsx_remove_my_account_dashboard( $menu_links ) {
unset( $menu_links[ 'edit-address' ] ); //remove the address from endpoint
return $menu_links;
}
Then go to your Dashboard > Settings > Permalinks, then click the button Save, that should do it.
Alternatively, you can override the my-address.php located on woocommerce/templates/myaccount, just use WC_Shortcode_My_Account::edit_address( 'billing' );.
Or you can redirect into Billing when user(s) is trying to access the Edit-Address endpoint, try using the below code in your functions.php.
function redirect_to_billing( $wp ) {
$current_url = home_url(add_query_arg(array(),$wp->request));
$billing = home_url('/account/edit-address/billing');
/** If user is accessing edit-address endpoint and it's not the billing address**/
if(is_wc_endpoint_url('edit-address') && $current_url !== $billing){
wp_redirect($billing);
exit();
}
}
add_action( 'parse_request', 'redirect_to_billing' , 10);
In Woocommerce, I need to stop email notifications sent to the customer when order place except when payment_method is BACS (Direct bank transfer).
I tried following in my active theme's function.php file:
add_filter( 'woocommerce_email_recipient_customer_on_hold_order_order', 'customer_order_email_if_bacs', 10, 2 );
function customer_order_email_if_bacs( $recipient, $order ) {
if( $order->payment_method() !== 'bacs' ) $recipient = '';
return $recipient;
}
But it don't work. Any help is appreciated.
Update 2
The woocommerce_email_recipient_{$email_id} filter is a composite hook and the right email ID to set in it is customer_on_hold_order and not customer_on_hold_order_order which will not work…
With the WC_Order object, since Woocommerce 3, you need to use get_payment_method() method.
To avoid Customer ON Hold email notification except for "Bacs" payment method use:
add_filter( 'woocommerce_email_recipient_customer_on_hold_order', 'customer_on_hold_order_for_bacs', 10, 2 );
function customer_on_hold_order_for_bacs( $recipient, $order ) {
if( is_a('WC_Order', $order) && $order->get_payment_method() !== 'bacs' ){
$recipient = '';
}
return $recipient;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
I am using a function in my functions.php file to display the purchase note for products in Woocommerce customer email. It looks like this:
function sww_add_note_woocommerce_emails( $output, $order ) {
// set a flag so we don't recursively call this filter
static $run = 0;
// if we've already run this filter, bail out
if ( $run ) {
return $output;
}
$args = array(
'show_purchase_note' => true,
);
// increment our flag so we don't run again
$run++;
// if first run, give WooComm our updated table
return wc_get_email_order_items( $order, $args );
}
add_filter( 'wc_get_email_order_items', 'sww_add_note_woocommerce_emails', 10, 2 );
This works perfectly for the email that the customer receives, but I also want it to display the notes in the 'new order' email that admin receives.
They both use the same order table so I'm not sure why it isn't working.
I didn't find a hook for wc_get_email_order_items but a function with some other hooks. Try instead:
add_filter( 'woocommerce_email_order_items_args', 'display_customer_note_in_all_emails', 10, 1 );
function display_customer_note_in_all_emails( $args ) {
$args['show_purchase_note'] = true;
return $args;
}
Code goes in function.php file of your active child theme (or active theme). It should works.
I Would like to add some CSS to the order admin page to hide a custom order action button, but only if the order contains only downloadable products.
This is the function I need to load conditionally:
add_action( 'admin_head', 'hide_custom_order_status_dispatch_icon' );
function hide_custom_order_status_dispatch_icon() {
echo '<style>.widefat .column-order_actions a.dispatch { display: none; }</style>';
}
Is that possible?
With CSS it's not be possible.
Instead you can hook in woocommerce_admin_order_actions filter hook, where you will be able to check if all order item are downloadable and then remove the action button "dispatch":
add_filter( 'woocommerce_admin_order_actions', 'custom_admin_order_actions', 900, 2 );
function custom_admin_order_actions( $actions, $the_order ){
// If button action "dispatch" doesn't exist we exit
if( ! $actions['dispatch'] ) return $actions;
// Loop through order items
foreach( $the_order->get_items() as $item ){
$product = $item->get_product();
// Check if any product is not downloadable
if( ! $product->is_downloadable() )
return $actions; // Product "not downloadable" Found ==> WE EXIT
}
// If there is only downloadable products, We remove "dispatch" action button
unset($actions['dispatch']);
return $actions;
}
Code goes in function.php file of the active child theme (or active theme).
This is untested but should work…
You will have to check that 'dispatch' is the correct slug for this action button…
I am trying to hide the payment method once user click place order using payment method lets say 'B' which returns in failure of payment.
public function process_payment( $order_id ) {
global $woocommerce;
$order = new WC_Order( $order_id );
if($this->api->somemethod()){
// Payment complete
$order->payment_complete();
return array(
'result' => 'success',
'redirect' => $this->get_return_url( $order )
);
}
else {
wc_add_notice( pll__('Payment error: You cannot use this payment method, Choose another method '), 'error' );
return;
}
}
I have used following filter
add_filter( 'woocommerce_payment_gateways', 'add_gateway_cb' );
But it only works on page reload. I want something which works with Ajax process payment or at least triggers the payment methods to reload upon failure.
Alternatively:
I can use custom JS on place order click.