Automattic\WooCommerce\Admin\API\Reports\Orders\Stats

DataStore::delete_refund │ public static │ WC 11.1.0

Deletes the refund stats when a refund is deleted.

This hook fires after the refund is gone, so delete_order() cannot be reused — its is_order() guard and wc_get_order() call both need the record. The customer ID comes from the stats row instead.

HPOS only. CPT deletes the post first, so delete_post has already run the whole cascade; repeating it here would fire the public hooks twice for one deletion. Under HPOS-with-sync the HPOS record goes first, so delete_order() short-circuits and this is the only cleanup that runs.

The cascade runs even without a stats row: imports are not atomic, so lookup rows can outlive one, and skipping would orphan them.

Method of the class: DataStore{}

Returns

null. Nothing (null).

Usage

$result = DataStore::delete_refund( $refund_id ): void;
$refund_id(int) (required)
Refund ID.

Changelog

Since 11.1.0 Introduced.

DataStore::delete_refund() code WC 11.1.2

public static function delete_refund( $refund_id ): void {
	global $wpdb;

	if ( ! OrderUtil::custom_orders_table_usage_is_enabled() ) {
		return;
	}

	$refund_id  = (int) $refund_id;
	$table_name = self::get_db_table_name();

	// A missing row yields customer ID 0, on which the customer cleanup no-ops.
	// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
	$customer_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT customer_id FROM {$table_name} WHERE order_id = %d", $refund_id ) );

	$wpdb->delete( $table_name, array( 'order_id' => $refund_id ) );

	/**
	 * Fires when orders stats are deleted.
	 *
	 * @param int $order_id Order ID.
	 * @param int $customer_id Customer ID.
	 *
	 * @since 4.0.0
	 */
	do_action( 'woocommerce_analytics_delete_order_stats', $refund_id, absint( $customer_id ) );

	ReportsCache::invalidate();
}