I ran into an issue in WooCommerce and I'm wondering if anyone else has experienced it too.
I sell certain products that are too fragile to be shipped by UPS/DHL/FedEx. So I have to ship these products via pallet. To solve my problem I created a "request a quote" shipping method that allows my customers to select BACS as the payment method, request a quote as the shipping method and submit their orders. And after I have calculated the shipping costs, I update the order (change the shipping method to N/A) and change the status from "on-hold" to "pending payment" to allow the customer to pay by card if they wish to.
This is where I ran into the issue. I noticed that if I unset several payment gateways and if these certain shipping methods are selected, these payment gateways are not available to the customer in the "order-pay" endpoint (website/my-account/orders/) even if I remove the shipping method from the order.
Is there a way around this?
This is the code I am using to Disable Payment Gateway For Specific Shipping Method.
add_filter( 'woocommerce_available_payment_gateways', 'filter_woocommerce_available_payment_gateways', 10, 1 );
function filter_woocommerce_available_payment_gateways( $available_gateways ) {
$gateways_to_disable = array( 'cardgatecreditcard', 'cardgategiropay', 'cardgateideal', 'cardgatesofortbanking' );
$shipping_methods = array( 'flat_rate', 'request_shipping_quote' );
$disable_gateways = false;
// Check if we need to disable gateways
foreach ( $shipping_methods as $shipping_method ) {
if ( strpos( WC()->session->get( 'chosen_shipping_methods' )[0], $shipping_method ) !== false ) $disable_gateways = true;
}
// If so, disable the gateways
if ( $disable_gateways ) {
foreach ( $available_gateways as $id => $gateway ) {
if ( in_array( $id, $gateways_to_disable ) ) {
unset( $available_gateways[$id] );
}
}
}
return $available_gateways;
}
UPDATE After consulting with a few developers they advised that this code runs every time Payment Gateways are required and suggested that I run this snippet only on the Checkout page.
They suggested adding the following to my code:
if ( is_checkout_pay_page() ) {
// unset Payment Gateways
}
SOLVED Here's my attempt and it works. But not sure if it can we expressed better:
add_filter( 'woocommerce_available_payment_gateways', 'filter_woocommerce_available_payment_gateways', 10, 1 );
function filter_woocommerce_available_payment_gateways( $available_gateways ) {
if ( ! ( is_checkout_pay_page() ) ) {
$gateways_to_disable = array( 'cardgatecreditcard', 'cardgategiropay', 'cardgateideal', 'cardgatesofortbanking' );
$shipping_methods = array( 'flat_rate', 'request_shipping_quote' );
$disable_gateways = false;
// Check if we need to disable gateways
foreach ( $shipping_methods as $shipping_method ) {
if ( strpos( WC()->session->get( 'chosen_shipping_methods' )[0], $shipping_method ) !== false ) $disable_gateways = true;
}
// If so, disable the gateways
if ( $disable_gateways ) {
foreach ( $available_gateways as $id => $gateway ) {
if ( in_array( $id, $gateways_to_disable ) ) {
unset( $available_gateways[$id] );
}
}
}
return $available_gateways;
}
else { return $available_gateways;
}
}