Search code examples
phpwordpresswoocommercecheckoutorders

Conditionally hiding et showing payment gateways


In Woocommerce, I would like to hide "paypal" gateway on the "checkout" page before the order is created for the first time and just show "cash on delivery" gateway (labeled as Reserve).

On the other hand, on checkout/order-pay page when the order status is "pending", hide the 'Reserve' gateway and show "paypal". (this happens when we change the status of the order to "pending" manually and send the invoice to the customer with a payment link).

I thought it should be done by checking order status and using the woocommerce_available_payment_gateways filter hook. But I have problems with getting current order status.

Also I'm not sure what's the status of a newly created order which the user is on the checkout page and still the order is not shown in the admin backend.

This is my incomplete code:

function myFunction( $available_gateways ) {

    // How to check if the order's status is not pending payment?
    // How to pass the id of the current order to wc_get_order()?
     $order = wc_get_order($order_id); 

    if ( isset($available_gateways['cod']) && /* pending order status?? */ ) { 
        // hide "cod" gateway
    } else {
        // hide "paypal" gateway
    }
    return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'myFunction' );

I also tried WC()->query_vars['order'] instead of wc_get_order(); to get the current order and check its status but it didn't work too.

I saw woocommerce_order_items_table action hook but couldn't get the order either.

How could I retrieve the Id and the status of the order on the checkout/order-pay page?


Solution

  • Update 2021

    If I have correctly understood, You want to set/unset your available payment gateways, depending on the live generated order which status has to pending to have the "paypal" gateway. Ian all other cases the available gateway is only "reserve" (renamed "cod" payment gateway).

    This code retrieve the live order ID using the get_query_var(), this way:

    add_filter( 'woocommerce_available_payment_gateways', 'custom_available_payment_gateways' );
    function custom_available_payment_gateways( $available_gateways ) {
        // Not in backend (admin)
        if( is_admin() ) 
            return $available_gateways;
    
        if ( is_wc_endpoint_url( 'order-pay' ) ) {
            $order = wc_get_order( absint( get_query_var('order-pay') ) );
    
            if ( is_a( $order, 'WC_Order' ) && $order->has_status('pending') ) {
                unset( $available_gateways['cod'] );
            } else {
                unset( $available_gateways['paypal'] );
            }
        } else {
            unset( $gateways['paypal'] );
        }
        return $available_gateways;
    }
    

    Code goes in functions.php file of your active child theme (or theme) or also in any plugin file.

    The code is tested and works.