Santiago Valdés
Santiago Valdés

Reputation: 45

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

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

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.

Upvotes: 1

Views: 317

Answers (1)

LoicTheAztec
LoicTheAztec

Reputation: 253867

Updated - Added guest using the billing email.

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.

Upvotes: 1

Related Questions