4
votes

In WooCommerce I need to apply a custom handling fee for a specific payment gateway. I have this piece of code from here: How to Add Handling Fee to WooCommerce Checkout.

This is my code:

add_action( 'woocommerce_cart_calculate_fees','endo_handling_fee' );
function endo_handling_fee() {
    global $woocommerce;

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

        $fee = 5.00;
    $woocommerce->cart->add_fee( 'Handling', $fee, true, 'standard' );
}

This function add a fee to all transactions.

Is it possible to tweak this function and make it apply for specific payment method only ?

The other problem is that I want this fee to be applied on cart. Is it possible?

I will welcome any alternative method as well. I know about the similar "Payment Gateway Based Fees" woo plugin, but I can't afford it.

3

3 Answers

20
votes

2021 UPDATE

Note: All payment methods are only available on Checkout page.

The following code will add conditionally a specific fee based on the chosen payment method:

// Add a custom fee (fixed or based cart subtotal percentage) by payment
add_action( 'woocommerce_cart_calculate_fees', 'custom_handling_fee' );
function custom_handling_fee ( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;

    $chosen_payment_id = WC()->session->get('chosen_payment_method');

    if ( empty( $chosen_payment_id ) )
        return;

    $subtotal = $cart->subtotal;

    // SETTINGS: Here set in the array the (payment Id) / (fee cost) pairs
    $targeted_payment_ids = array(
        'cod' => 8, // Fixed fee
        'paypal' => 5 * $subtotal / 100, // Percentage fee
    );

    // Loop through defined payment Ids array
    foreach ( $targeted_payment_ids as $payment_id => $fee_cost ) {
        if ( $chosen_payment_id === $payment_id ) {
            $cart->add_fee( __('Handling fee', 'woocommerce'), $fee_cost, true );
        }
    }
}

You will need the following to refresh checkout on payment method change, to get it work:

// jQuery - Update checkout on payment method change
add_action( 'woocommerce_checkout_init', 'payment_methods_refresh_checkout' );
function payment_methods_refresh_checkout() {
    wc_enqueue_js( "jQuery( function($){
        $('form.checkout').on('change', 'input[name=payment_method]', function(){
            $(document.body).trigger('update_checkout');
        });
    });");
}

Code goes in functions.php file of your active child theme (or active theme). tested and works.

How to find a specific payment method ID in WooCommerce Checkout page?

The following will display on checkout payment methods the payment Id just for admins:

add_filter( 'woocommerce_gateway_title', 'display_payment_method_id_for_admins_on_checkout', 100, 2 );
function display_payment_method_id_for_admins_on_checkout( $title, $payment_id ){
  if( is_checkout() && ( current_user_can( 'administrator') || current_user_can( 'shop_manager') ) ) {
      $title .= ' <code style="border:solid 1px #ccc;padding:2px 5px;color:red;">' . $payment_id . '</code>';
  }
  return $title;
}

Code goes in functions.php file of your active child theme (or active theme). Once used, remove it.

enter image description here


Similar answer:

0
votes

For anyone else looking to do this, I wanted to add a fee for Bank Transfers (BACS), here is the method I used:

//Hook the order creation since it is called during the checkout process:
add_filter('woocommerce_create_order', 'my_handle_bacs', 10, 2);

function my_handle_bacs($order_id, $checkout){
//Get the payment method from the $_POST
    $payment_method = isset( $_POST['payment_method'] ) ? wc_clean( $_POST['payment_method'] ) : '';

//Make sure it's the right payment method
    if($payment_method == "bacs"){

        //Use the cart API to add recalculate fees and totals, and hook the action to add our fee
        add_action('woocommerce_cart_calculate_fees', 'my_add_bacs_fee');
        WC()->cart->calculate_fees();
        WC()->cart->calculate_totals();
    }

    //This filter is for creating your own orders, we don't want to do that so return the $order_id untouched
    return $order_id;
}
function my_add_bacs_fee($cart){
    //Add the appropriate fee to the cart
    $cart->add_fee("Bank Transfer Fee", 40);
}
0
votes
add_action( 'woocommerce_cart_calculate_fees','cod_fee' );
function cod_fee() {
    global $woocommerce;

    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
        // get your payment method
        $chosen_gateway = WC()->session->chosen_payment_method;
        //echo $chosen_gateway;
        $fee = 5;
        if ( $chosen_gateway == 'cod' ) { //test with cash on delivery method
        WC()->cart->add_fee( 'delivery fee', $fee, false, '' );
    }


}