Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
*** WooCommerce Tax Changelog ***

= 3.6.14 - 2026-xx-xx =
* Fix - Prevent a fatal error at checkout when a cart line's price is not numeric.

= 3.6.13 - 2026-08-24 =
* Tweak - WordPress 7.1 Compatibility.

Expand Down
19 changes: 11 additions & 8 deletions classes/class-wc-connect-taxjar-integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -1055,14 +1055,17 @@ protected function get_line_items( $wc_cart_object ) {
$this->_log( 'Tax location override for product ' . $id . ': ' . $default_location . ' -> ' . $tax_location );
}

$line_items[ $cart_item_key ] = array(
'id' => $id,
'quantity' => $quantity,
'product_tax_code' => $tax_code,
'unit_price' => $unit_price,
'discount' => $discount,
'tax_location' => $tax_location,
);
// A malformed price reduces to '' or '-', which is fatal in the totals arithmetic. A 0 is legitimate.
if ( is_numeric( $unit_price ) ) {
$line_items[ $cart_item_key ] = array(
'id' => $id,
'quantity' => $quantity,
'product_tax_code' => $tax_code,
'unit_price' => $unit_price,
'discount' => $discount,
'tax_location' => $tax_location,
);
}
Comment thread
ismaeldcom marked this conversation as resolved.
}

// Re-keys $non_taxable_line_items onto the canonical ids as it goes.
Expand Down
3 changes: 3 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ This plugin relies on the following external services:

== Changelog ==

= 3.6.14 - 2026-xx-xx =
* Fix - Prevent a fatal error at checkout when a cart line's price is not numeric.

= 3.6.13 - 2026-08-24 =
* Tweak - WordPress 7.1 Compatibility.

Expand Down
39 changes: 39 additions & 0 deletions tests/php/test-class-wc-connect-taxjar-integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public function tear_down() {
remove_all_filters( 'woocommerce_tax_line_item_location' );
remove_all_filters( 'woocommerce_services_override_tax_rate' );
remove_all_filters( 'woocommerce_product_is_taxable' );
remove_all_filters( 'woocommerce_product_get_price' );

delete_option( 'woocommerce_calc_taxes' );

Expand Down Expand Up @@ -445,6 +446,44 @@ public function test_get_line_items_structure() {
$this->assertEquals( 2, $item['quantity'] );
}

/**
* A pricing filter can empty a price after the item is already in the cart.
* wc_format_decimal() passes that through, and a non-numeric unit price is fatal
* in the totals arithmetic, so the line is skipped.
*/
public function test_get_line_items_skips_line_with_non_numeric_price() {
$this->product = WC_Helper_Product::create_simple_product();
$this->product->save();

WC()->cart->add_to_cart( $this->product->get_id(), 2 );

add_filter( 'woocommerce_product_get_price', '__return_empty_string' );
$line_items = $this->invoke_protected_method( 'get_line_items', array( WC()->cart ) );
remove_filter( 'woocommerce_product_get_price', '__return_empty_string' );

Comment thread
ismaeldcom marked this conversation as resolved.
$this->assertSame( array(), $line_items );
}

/**
* A zero price is legitimate and must keep reaching TaxJar, so the guard has to be
* is_numeric() and not a truthiness check. See
* test_zero_amount_response_persists_real_itemized_rates() for what the response to
* a $0 line carries.
*/
public function test_get_line_items_keeps_line_priced_zero() {
$this->product = WC_Helper_Product::create_simple_product();
$this->product->set_regular_price( 0 );
$this->product->set_price( 0 );
$this->product->save();

WC()->cart->add_to_cart( $this->product->get_id(), 2 );

$line_items = $this->invoke_protected_method( 'get_line_items', array( WC()->cart ) );

$this->assertCount( 1, $line_items );
$this->assertSame( '0', reset( $line_items )['unit_price'] );
}

// -------------------------------------------------------------------------
// group_items_by_location() tests
// -------------------------------------------------------------------------
Expand Down
Loading