Managing Similar Payment Methods in WooCommerce: Enabling One While Disabling the Other

I've been working on a plugin featuring two payment gateways. However, users cannot activate both of them simultaneously. Therefore, if a user activates the first one, the second one should automatically deactivate.

1. Use woocommerce_update_option action

The woocommerce_update_option action is triggered every time a payment method is either activated or deactivated.


function youbou_manage_similar_payment_methods( $option ) {

    $gateway_prefix         = 'youbou_gateway';
    $current_gateway_key    = $option['id'] ?? '';

    if ( strpos($current_gateway_key, $gateway_prefix ) === false ) return;

    $current_option_enabled         = false;
    $payment_gateways_to_disable    = array();
    $payment_gateways               = WC()->payment_gateways->payment_gateways();

    foreach ( $payment_gateways as $gateway ) {

        $gateway_key = $gateway->get_option_key();

        if ( $gateway_key === $current_gateway_key ) {

            $enabled = $gateway->get_option( 'enabled', 'no' );

            if ( $enabled === 'no' ) {
                $current_option_enabled = true;
            }

        } else {

            if ( strpos($gateway_key, $gateway_prefix ) !== false ) {
                $payment_gateways_to_disable[] = $gateway;
            }
        }
    }

    if ( $current_option_enabled && count($payment_gateways_to_disable) > 0 ) {
        foreach ( $payment_gateways_to_disable as $payment_gateway ) {
            $payment_gateway->update_option( 'enabled', 'no' );
        }
    }
}
add_action('woocommerce_update_option', 'youbou_manage_similar_payment_methods' );

This code checks if the updated gateway has a specific prefix in its ID. If it does, it verifies whether our gateway is enabled and takes the opposite status because the action is triggered before the new status change. It also keeps track of other gateways that need to be disabled, based on a certain condition. Finally, it loops through the identified gateways and disables them.

2. Add javascript for the toggle

To disable the toggle on the WooCommerce payments page using JavaScript, we must enqueue our script.

function youbou_enqueue_scripts( $hook_suffix ) {

	if ( $hook_suffix === 'woocommerce_page_wc-settings' ) {

		wp_enqueue_script( 'youbou_script', 'path/to/the/js/file', array('jquery'), '1.0.0', true );
	}

}
add_action( 'admin_enqueue_scripts', 'youbou_enqueue_scripts' );

This code enhances the WooCommerce payment page by dynamically disabling specific payment gateways. It utilizes the gatewayIds array, where you can specify the gateway to be clicked and an array of gateway IDs to disable. In this example, i set up the code to disable a single gateway, but you can easily expand this functionality to disable multiple gateways with just adding them to the array.

(function ($) {

    $( function(){

        const gatewayIds = {
            'youbou_gateway_3x'     : ['youbou_gateway_3x_pro'],
            'youbou_gateway_3x_pro' : ['youbou_gateway_3x']
        };

        const gatewayIdsToArray = Object.keys(gatewayIds);

        gatewayIdsToArray.forEach( id => {
            
            $(`[data-gateway_id="${id}"] a.wc-payment-gateway-method-toggle-enabled`).on('click', e => {

                const enabled = $(e.currentTarget)
                            .find('span.woocommerce-input-toggle')
                            .hasClass('woocommerce-input-toggle--disabled');

                if ( enabled ) {

                    gatewayIds[id].forEach( idToDisable => {

                        $(`[data-gateway_id="${idToDisable}"] a.wc-payment-gateway-method-toggle-enabled`)
                            .find('span.woocommerce-input-toggle')
                            .addClass('woocommerce-input-toggle--disabled');
                    });
                }

            });
        });

    });

})(jQuery);