I’ve built an online shop on WooCommerce that sells retail as well as wholesale. But credit card fees are so damn expensive. I’m happy to pay the credit card fees for my retail customers but I want to charge my resellers if they choose to pay by credit card.
I managed to come up with the following code that works really well. But I have two different types of resellers so I need to expand the code and I’m not sure how to go about it.
I’m trying to expand this bit of code to include three different user roles:
Role 1: wholesaler-non-vat-registered
Role 2: default_wholesaler
Role 3: administrator
Any idea how to go about it?
add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_add_checkout_fee_for_gateway' );
function bbloomer_add_checkout_fee_for_gateway() {
if ( ! current_user_can( 'wholesaler-non-vat-registered' ) )
return;
global $woocommerce;
$chosen_gateway = $woocommerce->session->chosen_payment_method;
if ( $chosen_gateway == 'cardgatecreditcard' ) {
$percentage = 0.085;
$surcharge = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage;
$woocommerce->cart->add_fee( 'Credit Card Fee (8.5%)', $surcharge, true, '');
}
}
This code works too, but it adds the credit card fee to logged in Customers too. So the code works for Guests, but as soon as the customer signs into their account they get charged a credit card fee.
add_action( 'woocommerce_cart_calculate_fees', 'bbloomer_add_checkout_fee_for_gateway' );
function bbloomer_add_checkout_fee_for_gateway() {
global $woocommerce;
$user_role = wp_get_current_user();
$order_fee_roles = array( 'customer', 'wholesale', 'administrator' );
if (! is_user_logged_in() && !in_array($order_fee_roles, $user_role->roles ))
return;
$chosen_gateway = WC()->session->get( 'chosen_payment_method' );
if ( $chosen_gateway == 'cardgatecreditcard' ){
$percentage = 0.085;
$surcharge = ( $woocommerce->cart->cart_contents_total + $woocommerce->cart->shipping_total ) * $percentage;
$woocommerce->cart->add_fee( 'Credit Card Fee (8.5%)', $surcharge, true, '');
}}
add_action( 'woocommerce_review_order_before_payment', 'bbloomer_refresh_checkout_on_payment_methods_change' );
function bbloomer_refresh_checkout_on_payment_methods_change(){ ?>
<script type="text/javascript">
(function($){
$( 'form.checkout' ).on( 'change', 'input[name^="payment_method"]', function() {
$('body').trigger('update_checkout');
});
})(jQuery);
</script>
<?php
}
Here’s the solution thanks to Sara McMahon. Works like a charm!
add_action('woocommerce_cart_calculate_fees', 'sm_credit_card_fee_role_gateway', 10, 1);
function sm_credit_card_fee_role_gateway($cart){
if (is_admin() && !defined('DOING_AJAX'))
return;
if (!(is_checkout() && !is_wc_endpoint_url()))
return;
if (!is_user_logged_in())
return;
$user = wp_get_current_user();
$roles = (array) $user->roles;
$roles_to_check = array('administrator', 'default_wholesaler', 'wholesaler-non-vat-registered');
$compare = array_diff($roles, $roles_to_check);
if (empty($compare)){
$payment_method = WC()->session->get('chosen_payment_method');
if ($payment_method == 'cardgatecreditcard'){
$percentage = 0.085;
$surcharge = (WC()->cart->cart_contents_total + WC()->cart->shipping_total) * $percentage;
$cart->add_fee( 'Credit Card Fee (8.5%)', $surcharge, true );
}
}
}
2
Answers
Your issue with the second code is the probably the specific conditionals you’ve set.
$order_fee_roles = array( ‘customer’, ‘wholesale’, ‘administrator’ );
if (! is_user_logged_in() && !in_array($order_fee_roles, $user_role->roles ))
You could consider breaking them up to make it easier to test. So first do a check on if the user is logged in. Then inside that check if they are logged in then check the user role.
One issue you’re having with the conditions you’ve set is that you’re saying ‘if the user is not logged in and is not one of these roles then don’t run’. When a user is logged out then they don’t have a role, and when the user is logged in this code doesn’t apply. This is why it is running for everyone. To make the conditional so that you are checking if the user is logged in just remove the exclamation mark. This would change your check to ‘if the user is logged in and not one of the following roles’…