简体   繁体   中英

Check WooCommerce User Role and Payment Gateway and if they match - Apply fee

I'm struggling with applying a fee for an array of user roles if and when a specific payment gateway is selected.

The code I've written works fine if I do not check the user role, but once I try and do that, it does not.

I've removed (commented) the user role if statement in the code and I'm asking for help making it work.

I need to check if the user role match my array and if it does, check the payment gateway. If the payment gateway match too, apply the fee.

This is my code:

add_action( 'woocommerce_cart_calculate_fees', 'custom_fee', 20, 1 );
function custom_fee ($cart){

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

    if (!is_user_logged_in()) return;

    if (!is_checkout() && !is_wc_endpoint_url()) return;

    $customer_role = wp_get_current_user();
    $roles_to_check = array( 'vendor', 'external' );
    $payment_method = WC()->session->get('chosen_payment_method');

        // if (!in_array($roles_to_check, $customer_role->roles)) return;

    if ('bacs' == $payment_method){
        $payment_fee = $cart->subtotal * 0.05;
            $cart->add_fee( 'Payment Fee', $payment_fee, true );
    }
}

You could use the following, explanation with comments added in the code

Conditions that must be met in this code are:

  • only for certain user roles
  • checks on payment method
function custom_fee( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) )
        return;
    
    if ( ! ( is_checkout() && ! is_wc_endpoint_url() ) )
        return; // Only checkout page
    
    if ( ! is_user_logged_in())
        return;

    // Get current WP_User Object
    $user = wp_get_current_user();
    
    // User roles
    $roles = ( array ) $user->roles;

    // Roles to check
    $roles_to_check = array( 'vendor', 'external', 'administrator' );
    
    // Compare
    $compare = array_diff( $roles, $roles_to_check );

    // Result is empty
    if ( empty ( $compare ) ) {
        // Payment method
        $payment_method = WC()->session->get('chosen_payment_method');

        // Condition equal to
        if ( $payment_method == 'bacs' ) { 
            // Calculate
            $payment_fee = $cart->subtotal * 0.05;

            // Add fee
            $cart->add_fee( 'Payment Fee', $payment_fee, true );
        }
    }
}
add_action( 'woocommerce_cart_calculate_fees', 'custom_fee', 10, 1 );

EDIT

To complete my answer, see the answer from @ LoicTheAztec

The answer of @7uc1f3r is good, but something important is missing from it.

In WooCommerce checkout when choosing a payment method, checkout totals are not refreshed. So something additional is required to refresh checkout "order review" section:

// jQuery - Update checkout on payment method change
add_action( 'wp_footer', 'custom_checkout_jquery_script' );
function custom_checkout_jquery_script() {
    if ( is_checkout() && ! is_wc_endpoint_url() ) :
    ?>
    <script type="text/javascript">
    jQuery( function($){
        $('form.checkout').on('change', 'input[name="payment_method"]', function(){
            $(document.body).trigger('update_checkout');
        });
    });
    </script>
    <?php
    endif;
}

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

Related: Add fee based on specific payment methods in WooCommerce

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM