Skip to content

Instantly share code, notes, and snippets.

@lukapaunovic
Created January 2, 2026 03:16
Show Gist options
  • Select an option

  • Save lukapaunovic/a2a631812db50feee927349c772ad43c to your computer and use it in GitHub Desktop.

Select an option

Save lukapaunovic/a2a631812db50feee927349c772ad43c to your computer and use it in GitHub Desktop.
<?php
// If Woo thinks payment is not required (total = 0), recalculate and force needs_payment = true.
add_filter( 'woocommerce_order_needs_payment', function( $needs_payment, $order ) {
if ( $needs_payment || ! $order instanceof WC_Order ) {
return $needs_payment;
}
if ( 0 === count( $order->get_items( 'line_item' ) ) ) {
return $needs_payment;
}
// Recalculate totals from line items + shipping + fees + tax.
$item_total = array_sum( array_map( static fn( $i ) => (float) $i->get_total(), $order->get_items( 'line_item' ) ) );
$fee_total = array_sum( array_map( static fn( $f ) => (float) $f->get_total(), $order->get_fees() ) );
$shipping_total = array_sum( array_map( static fn( $s ) => (float) $s->get_total(), $order->get_shipping_methods() ) );
$shipping_tax = array_sum( array_map( static fn( $s ) => (float) $s->get_total_tax(), $order->get_shipping_methods() ) );
$tax_total = (float) $order->get_total_tax();
$calc_total = $item_total + $fee_total + $shipping_total + $tax_total;
if ( $calc_total > 0 ) {
// Force correct totals on the order object before payment is processed.
$order->set_shipping_total( $shipping_total );
$order->set_shipping_tax( $shipping_tax );
$order->set_total( $calc_total );
$order->update_meta_data( '_order_total', $calc_total );
return true; // Force payment instead of allowing zero-total checkout
}
return $needs_payment;
}, 5, 2 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment