questions

Limit BACS “on-hold” orders to only one by customer in WooCommerce

Rate this post

We offer BACS (bank transfer) as a payment method on our WooCommerce store. If someone uses that method:

  • stock is reduced for that product
  • order is on-hold for 48 hrs

The issue we are having is that some people take advantage of that and they use that method to reserve products. They wait for the order to be cancelled and then do it again, and whenever they have some money, they actually pay for it.

As a secondhand store, of course that is not desired behavior.

Is there a way to limit the number of BACS orders with “on hold” status to just only one?

That way, if you want to pay with BACS and your email already has one order pending, it will return an error and you won’t be able to finish checkout. Of course people can use different emails, but it starts to get complex.

Any help is appreciated.

 

✔️Solution:

The following very simple hooked function will check if the current customer has any “on-hold” BACS order and if it’s the case, it will display an error message avoiding checkout, if the current order is using BACS payment method:

add_action( 'woocommerce_checkout_process', 'action_wc_checkout_process_callback' );
function action_wc_checkout_process_callback() {
    if( is_user_logged_in() ) {
        // Get customer "on-hold" orders
        $orders = (array) wc_get_orders(['limit' => - 1, 'customer_id' => get_current_user_id(),
            'status' => 'on-hold', 'return' => 'ids']);
    } elseif ( isset($_POST['billing_email']) && ! empty($_POST['billing_email']) ) {
        // Get customer "on-hold" orders
        $orders = (array) wc_get_orders(['limit' => - 1, 'customer' => sanitize_email($_POST['billing_email']), 'status' => 'on-hold', 'return' => 'ids']);
    }

    // Check if the current customer has any "on-hold" BACS order and if current order is using BACS as payment method
    if ( isset($orders) && count($orders) > 0 && isset($_POST['payment_method']) && $_POST['payment_method'] === 'bacs' ) {
        // Display an error notice (and avoid checkout)
        wc_add_notice( __( "You have already one order awaiting payment and you can have only one at the time.", "woocommerce" ), 'error' );
    }
}

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

Leave a Reply

Your email address will not be published.

Back to top button