Prevent the checkout process if the customer has pending payments

Sometimes customers might leave some orders unpaid, perhaps from their card being declined, payment processing errors and many other reasons. You have the ability as a WooCommerce based store owner to prevent them from placing additional orders until they settle their outstanding ones. This can prevent your order queue from being cluttered and minimize illegitimate orders.

Install and activate a child theme

The first step on our process here is to create and install a child theme. If you are using one of our themes you can easily grab its child theme from our downloads section. If not, you can read our beginner’s guide on child themes to create your own. This step is essential in order to preserve our changes throughout theme updates.

All code below will be placed in our child theme’s functions.php file. If the file is empty the code will go just below the opening <?php tag, otherwise, if it has contents, the code should be placed at the end of the file, before the closing ?> PHP tag if it exists.

Blocking checkout if outstanding payments are found

To add our check for pending payments we will use the woocommerce_checkout_process hook and use it to look for pending payment orders on the customer’s history.

add_action( 'woocommerce_checkout_process', 'cssigniter_prevent_checkout_if_pending_payments' );
function cssigniter_prevent_checkout_if_pending_payments() {
	$customer = wp_get_current_user();

	if ( ! empty( $customer ) ) {
		$args = array(
			'customer_id' => $customer->ID,
			'status'      => array( 'wc-pending' ),
		);

		$pending_orders = wc_get_orders( $args );

		if ( count( $pending_orders ) > 0 ) {
			$payment_links = array();

			foreach ( $pending_orders as $pending_order ) {
				array_push( $payment_links, '<a href="' . $pending_order->get_checkout_payment_url() . '" target="_blank">#' . $pending_order->get_order_number() . '</a>' );
			}

			$payment_links = implode( ', ', $payment_links );
			$message       = sprintf(
				// Translators: 1$%s is the my account page URL, 2$%s are the individual pending order payment links.
				__( 'Please take care of any outstanding payments from your <a href="%1$s" target="_blank">account page</a>, or the following links %2$s, before proceeding with new orders. Thank you.', 'your-text-domain' ),
				wc_get_page_permalink( 'myaccount' ),
				$payment_links
			);

			wc_add_notice( $message, 'error' );
		}
	}
}

Let’s break things down a bit. We start by getting the current user to find out which customer is making the order. If the current user exists, i.e. it is a returning customer we get all their pending orders using wc_get_orders and if we find any we create a WooCommerce notice which informs the customer that they have pending payments under their user account, the notice prompts the customer to take care of these pending payments and provides them with links to both their my account page and to each order’s payment URL directly. This way they can sort the payments out and be able to place new ones on the store.

The notice received when the user has pending payments in their account.

Wrapping up

With this simple snippet we managed to prevent any users with outstanding payments from placing additional ones until they take care of their balance. Did you find this tutorial useful? Please let us know in the comments below.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *