Split WooCommerce cart into multiple shipping packages

/**
 * Breaks WooCommerce cart into multiple shipping packages (one package for each product).
 *
 * @see https://wpcodebook.com/split-woocommerce-cart-multiple-shipping-packages/
 * @see https://github.com/woocommerce/woocommerce/blob/8.6.1/plugins/woocommerce/includes/class-wc-cart.php#L1506
 * @see https://github.com/woocommerce/woocommerce/blob/8.6.1/plugins/woocommerce/includes/wc-cart-functions.php#L232
 */
add_filter( 'woocommerce_cart_shipping_packages', function ( $packages ) {
	$initial_package = current( $packages );
	$split_packages  = array();

	// Group packages by product ID
	foreach ( $initial_package['contents'] as $cart_item_key => $cart_item ) {
		$split_packages[ $cart_item['data']->get_id() ]['contents'][ $cart_item_key ] = $cart_item;
	}

	// Finalize packages: calculate cost and add data (destination, user, applied coupons)
	foreach ( $split_packages as &$package ) {
		$package['destination']     = $initial_package['destination'];
		$package['user']            = $initial_package['user'];
		$package['applied_coupons'] = $initial_package['applied_coupons'];
		$package['contents_cost']   = array_sum( wp_list_pluck( $package['contents'], 'line_total' ) );
	}

	// Reset array keys (for package name display)
	$split_packages = array_values( $split_packages );

	return $split_packages;
} );

Leave a Comment