I am trying to disable WooCommerce PayPal Checkout Payment Gateway for unlogged users. How can I do that?
Updated - The following will disable Paypal Checkout Payment gateway for unlogged users:
add_filter( 'woocommerce_available_payment_gateways', 'conditionally_disable_paypal_payment_gateways', 10, 1 );
function conditionally_disable_paypal_payment_gateways( $available_gateways ) {
if ( is_admin() ) return $available_gateways; // Only on frontend
// Loop through payment gateways
foreach( $available_gateways as $gateways_id => $gateways ){
if ( ! is_user_logged_in() && $gateways_id === 'ppec_paypal' ) {
unset($available_gateways[$gateways_id]);
}
}
return $available_gateways;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
For Woocommerce default Paypal payment gateway, replace 'ppec_paypal' by 'paypal'.
Related
I tried this code below to hide/disable Credit/Debit card and Direct bank transfer payment method on Woo commerce(WordPress) when the checkout total == 400 but did not work. Please any idea on how to achieve this? Thank you so kindly.
function payment_gateway_disable_total_amount( $available_gateways ) {
global $woocommerce;
if ( isset( $available_gateways['bacs'] ) && $woocommerce->cart->total == 400 ) {
unset( $available_gateways['bacs'] );
}
if ( isset( $available_gateways['youpay'] ) && $woocommerce->cart->total == 400 ) {
unset( $available_gateways['youpay'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_total_amount' );
Why using a fixed total? There is very few chances that any customer get speifically 400 as total. It should be "up to 400" instead, so something like if( $tolal >= 400 ).
Also "Debit/Credit Cards" doesn't seem to be the right Payment method Id… See [this thread][1] to find out the right Payment method Id for "Debit/Credit Cards" payment gateway.
Try the following (assuming that "Debit/Credit Cards" payment method id is correct):
add_filter( 'woocommerce_available_payment_gateways', 'show_hide_payment_methods' );
function show_hide_payment_methods( $available_gateways ) {
if ( WC()->cart->total >= 400 ) {
if ( isset($available_gateways['bacs']) ) {
unset($available_gateways['bacs']);
}
if ( isset($available_gateways['Debit/Credit Cards']) ) {
unset($available_gateways['Debit/Credit Cards']);
}
}
return $available_gateways;
}
Code goes in functions.php file of the active child theme (or active theme). It should works.
The code I have works for hiding the BACS payment gateway for guests and customers, but I need to change it so that the BACS gateway only becomes available IF the customer/admin apply a certain coupon code called FOOD on the CART or CHECKOUT.
In other words: hide the BACS gateway until the COUPON called FOOD is applied on the CART or CHECKOUT.
Here's the code that I have:
add_filter('woocommerce_available_payment_gateways', 'show_bacs_if_coupon_is_used', 99, 1);
function show_bacs_if_coupon_is_used( $available_gateways ) {
$current_user = wp_get_current_user();
if ( isset($available_gateways['bacs']) && (current_user_can('customer'))) {
unset($available_gateways['bacs']);
} else if ( isset($available_gateways['bacs']) && !is_user_logged_in()) {
unset($available_gateways['bacs']);
}
return $available_gateways;
}
Only show BACS payment method when a specific coupon is applied to cart for logged in users only (using WC_Cart get_applied_coupons() method):
add_filter('woocommerce_available_payment_gateways', 'show_bacs_for_specific_applied_coupon', 99, 1);
function show_bacs_for_specific_applied_coupon( $available_gateways ) {
if ( is_admin() ) return $available_gateways; // Only on frontend
$coupon_code = 'FOOD'; // <== Set here the coupon code
if ( isset($available_gateways['bacs']) && ! ( is_user_logged_in() &&
in_array( strtolower($coupon_code), WC()->cart->get_applied_coupons() ) ) ) {
unset($available_gateways['bacs']);
}
return $available_gateways;
}
Code goes in functions.php file of your active child theme (or active theme). Tested and works.
I made a two-step payment on the site. Payment occurs after confirmation of the order by the manager. First, the user selects the payment method "for confirmation"(renamed "cash on delivery") and pay only after receiving the invoice for payment. On the checkout page, I hide paypal via js. I would like paypal to be hidden when on-hold status. When the status of "Pending payment" is disabled "for confirmation"(renamed "cash on delivery") and payment via paypal is available.
Update July 2020
The following code will show hide payment gateways:
On checkout page it will remove "paypal" payment option (So you can remove your jQuery code)
On Order Pay page it will:
Keep "paypal" only payment option if the order status is "pending" (removing all other options)
For others order statuses than "pending", the payment is not allowed by Woocommerce…
The code:
// Show/hide payment gateways
add_filter( 'woocommerce_available_payment_gateways', 'conditionally_hide_payment_gateways', 100, 1 );
function conditionally_hide_payment_gateways( $available_gateways ) {
// 1. On Order Pay page
if( is_wc_endpoint_url( 'order-pay' ) ) {
// Get an instance of the WC_Order Object
$order = wc_get_order( get_query_var('order-pay') );
// Loop through payment gateways 'pending', 'on-hold', 'processing'
foreach( $available_gateways as $gateways_id => $gateways ){
// Keep paypal only for "pending" order status
if( $gateways_id !== 'paypal' && $order->has_status('pending') ) {
unset($available_gateways[$gateways_id]);
}
}
}
// 2. On Checkout page
elseif( is_checkout() && ! is_wc_endpoint_url() ) {
// Disable paypal
if( isset($available_gateways['paypal']) ) {
unset($available_gateways['paypal']);
}
}
return $available_gateways;
}
Code goes in function.php file of your active child theme (or active theme). Tested and work.
Copy and paste the same code and it didn't work
syntax error, unexpected 'elseif' (T_ELSEIF)
I correct the code
// Show/hide payment gateways
add_filter( 'woocommerce_available_payment_gateways', 'conditionally_hide_payment_gateways', 100, 1 );
function conditionally_hide_payment_gateways( $available_gateways ) {
// 1. On Order Pay page
if( is_wc_endpoint_url( 'order-pay' ) ) {
// Get an instance of the WC_Order Object
$order = wc_get_order( get_query_var('order-pay') );
// Loop through payment gateways 'pending', 'on-hold', 'processing'
foreach( $available_gateways as $gateways_id => $gateways ){
// Keep paypal only for "pending" order status
if( $gateways_id !== 'paypal' && $order->has_status('pending') ) {
unset($available_gateways[$gateways_id]);
}
}
}
// 2. On Checkout page
elseif( is_checkout() && ! is_wc_endpoint_url() ) {
// Disable paypal
if( isset($available_gateways['paypal']) ) {
unset($available_gateways['paypal']);
}
}
return $available_gateways;
}
enter image description here
I started to work on small Woocommerce project. I have 3 payment gateways into this store: Paypal, Credit Card and Direct bank Transfer.
What I would like is: If coupon code is used, I would like to disable (or remove) Paypal and Credit Card from available payment gateways, and just keep "Direct bank Transfer" as available payment gateway choice.
To show how is look current state from checkout page:
I found a similar solution, but this is for removing gateway based on product category.
add_filter( 'woocommerce_available_payment_gateways', 'unset_payment_gateways_by_category' );
function unset_payment_gateways_by_category( $available_gateways ) {
global $woocommerce;
$unset = false;
$category_ids = array( 8, 37 );
foreach ( $woocommerce->cart->cart_contents as $key => $values ) {
$terms = get_the_terms( $values['product_id'], 'product_cat' );
foreach ( $terms as $term ) {
if ( in_array( $term->term_id, $category_ids ) ) {
$unset = true;
break;
}
}
}
if ( $unset == true )
unset( $available_gateways['cheque'] );
return $available_gateways;
}
So I think that this function can be used, but slightly modified per my problem.
Any help is appreciated.
The following code will remove all payment gateways except "Direct bank Transfer" (bacs) only if at least one coupon code has been applied by the customer:
add_filter('woocommerce_available_payment_gateways', 'applied_coupons_hide_payment_gateways', 20, 1 );
function applied_coupons_hide_payment_gateways( $available_gateways){
// Not in backend (admin)
if( is_admin() )
return $available_gateways;
// If at least a coupon is applied
if( sizeof( WC()->cart->get_applied_coupons() ) > 0 ){
// Loop through payment gateways
foreach ( $available_gateways as $gateway_id => $gateway ) {
// Remove all payment gateways except BACS (Bank Wire)
if( $gateway_id != 'bacs' )
unset($available_gateways[$gateway_id]);
}
}
return $available_gateways;
}
Code goes in function.php file of the active child theme (or active theme). Tested and works.
here you go :
add_filter('woocommerce_available_payment_gateways', 'unset_gatway_by_applied_coupons');
function unset_gatway_by_applied_coupons($available_gateways)
{
$coupons = WC()->cart->applied_coupons;
if (!empty($coupons)) {
unset($available_gateways['bacs']);
}
return $available_gateways;
}
what we did here we checked if any coupons is applied trough WC()->cart->applied_coupons; which will return an array of coupons if coupons array not empty remove specific payment gateway
if you want to check if certain coupon is applied and remove gatway based on your condition you can use the following:
add_filter('woocommerce_available_payment_gateways', 'unset_gatway_by_applied_coupons');
function unset_gatway_by_applied_coupons($available_gateways)
{
$coupons = WC()->cart->applied_coupons;
foreach ($coupons as $coupon) {
if ($coupon == 'my_coupon') { //here you can specific your coupon name
unset($available_gateways['bacs']);
}
}
return $available_gateways;
}
of course both functions are tested, you just need to place them in your functions.php
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.
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.
Similar answer:
Add a custom fee for a specific payment gateway in Woocommerce
Add a fee based on shipping method and payment method in Woocommerce
Percentage discount based on user role and payment method in Woocommerce
First of all there are some key things we need to understand:
We are going to use the only filter hook which is woocommerce_cart_calculate_fees
In order to get user selected payment method we must retrieve it from user sessions using this method WC()->session->get( 'chosen_payment_method' )
calculate_fees() and calculate_totals() methods are not necessary.
We are going to add the fee using cart method WC()->cart->add_fee() which accepts two parameters – the first one, is the fee description, the second one – fee amount.
And one more thing – we will need a payment method slug, the easiest way to get it described in this tutorial https://rudrastyh.com/woocommerce/add-id-column-to-payment-methods-table.html
Let's go now:
add_action( 'woocommerce_cart_calculate_fees', 'rudr_paypal_fee', 25 );
function rudr_paypal_fee() {
if( 'paypal' == WC()->session->get( 'chosen_payment_method' ) ) {
WC()->cart->add_fee( 'PayPal fee', 2 ); // let's add a fee for paypal
}
}
It would be also great to refresh the checkout every time payment gateway is changed, it is easy to do using this code:
jQuery( function( $ ) {
$( 'form.checkout' ).on( 'change', 'input[name^="payment_method"]', function() {
$( 'body' ).trigger( 'update_checkout' );
});
});
That's it. Everything is described in details here as well: https://rudrastyh.com/woocommerce/charge-additional-fees-based-on-payment-gateway.html
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);
}
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, '' );
}
}