Automattic\WooCommerce\Internal\RestApi\Routes\V4\Refunds

DataUtils::compute_refunded_quantities_and_totals │ public │ WC 1.0

Pre-compute refund data for all line items in an order.

Loads refunds once and builds lookup maps for refunded quantities and totals per item ID, avoiding repeated get_refunds() calls during serialization. Fee and shipping totals are tax-inclusive so they can be compared directly against {@see compute_line_item_refund_total()}.

line_refunds records each product refund line individually — quantity and tax-inclusive gross, both as positive magnitudes — so the quantity-form top-up can verify that prior refunds match their quantity-derived amounts before reconciling rounding drift.

Method of the class: DataUtils{}

No Hooks.

Returns

array{qtys:. array<int, int>, totals: array<int, float>, tax_totals: array<int, array<int, float>>, line_refunds: array<int, list<array{qty: int, gross: float}>>}

Usage

$DataUtils = new DataUtils();
$DataUtils->compute_refunded_quantities_and_totals( $order ): array;
$order(WC_Order) (required)
Order instance.

DataUtils::compute_refunded_quantities_and_totals() code WC 11.1.2

public function compute_refunded_quantities_and_totals( WC_Order $order ): array {
	$qtys         = array();
	$totals       = array();
	$tax_totals   = array();
	$line_refunds = array();

	// Accumulate the already-refunded tax per original item, keyed by tax rate
	// id, as a positive amount. Refund line items store taxes as negatives, so
	// flip the sign. Lets the per-tax-id cap subtract prior refunds.
	$add_refunded_taxes = function ( $refunded_item, int $original_id ) use ( &$tax_totals ) {
		$taxes = $refunded_item->get_taxes();
		foreach ( (array) ( $taxes['total'] ?? array() ) as $tax_id => $amount ) {
			$tax_totals[ $original_id ][ $tax_id ] = ( $tax_totals[ $original_id ][ $tax_id ] ?? 0.0 ) + abs( (float) $amount );
		}
	};

	foreach ( $order->get_refunds() as $refund ) {
		/**
		 * Refunded product line items.
		 *
		 * @var \WC_Order_Item_Product[] $refunded_line_items
		 */
		$refunded_line_items = $refund->get_items( 'line_item' );
		foreach ( $refunded_line_items as $refunded_item ) {
			$original_id                    = absint( $refunded_item->get_meta( '_refunded_item_id' ) );
			$qtys[ $original_id ]           = ( $qtys[ $original_id ] ?? 0 ) + $refunded_item->get_quantity();
			$totals[ $original_id ]         = ( $totals[ $original_id ] ?? 0.0 ) + ( (float) $refunded_item->get_total() + (float) $refunded_item->get_total_tax() ) * -1;
			$line_refunds[ $original_id ][] = array(
				'qty'   => absint( $refunded_item->get_quantity() ),
				'gross' => abs( (float) $refunded_item->get_total() + (float) $refunded_item->get_total_tax() ),
			);
			$add_refunded_taxes( $refunded_item, $original_id );
		}
		/**
		 * Refunded fee items.
		 *
		 * @var \WC_Order_Item_Fee[] $refunded_fees
		 */
		$refunded_fees = $refund->get_items( 'fee' );
		foreach ( $refunded_fees as $refunded_item ) {
			$original_id            = absint( $refunded_item->get_meta( '_refunded_item_id' ) );
			$totals[ $original_id ] = ( $totals[ $original_id ] ?? 0.0 ) + ( (float) $refunded_item->get_total() + (float) $refunded_item->get_total_tax() ) * -1;
			$add_refunded_taxes( $refunded_item, $original_id );
		}
		/**
		 * Refunded shipping items.
		 *
		 * @var \WC_Order_Item_Shipping[] $refunded_shipping
		 */
		$refunded_shipping = $refund->get_items( 'shipping' );
		foreach ( $refunded_shipping as $refunded_item ) {
			$original_id            = absint( $refunded_item->get_meta( '_refunded_item_id' ) );
			$totals[ $original_id ] = ( $totals[ $original_id ] ?? 0.0 ) + ( (float) $refunded_item->get_total() + (float) $refunded_item->get_total_tax() ) * -1;
			$add_refunded_taxes( $refunded_item, $original_id );
		}
	}

	return array(
		'qtys'         => $qtys,
		'totals'       => $totals,
		'tax_totals'   => $tax_totals,
		'line_refunds' => $line_refunds,
	);
}