wc_is_webhook_valid_topic()WC 2.2.0

Check if the given topic is a valid webhook topic, a topic is valid if:

  • starts with action.woocommerce_ or action.wc_ (unless explicitly blocked by the $invalid_topics list below).
  • it has a valid resource & event AND (when both are part of the default sets) the <resource>.<event> pair has a registered hook. Default/default pairs with no registered hook (e.g. order.published, customer.restored) are rejected to prevent ghost webhooks that save as Active but never deliver.

Returns

true|false.

Usage

wc_is_webhook_valid_topic( $topic );
$topic(string) (required)
Webhook topic.

Changelog

Since 2.2.0 Introduced.

wc_is_webhook_valid_topic() code WC 10.9.1

function wc_is_webhook_valid_topic( $topic ) {
	$invalid_topics = array(
		'action.woocommerce_login_credentials',
		'action.woocommerce_product_csv_importer_check_import_file_path',
		'action.woocommerce_webhook_should_deliver',
	);

	if ( in_array( $topic, $invalid_topics, true ) ) {
		return false;
	}

	// Custom topics are prefixed with woocommerce_ or wc_ are valid.
	if ( 0 === strpos( $topic, 'action.woocommerce_' ) || 0 === strpos( $topic, 'action.wc_' ) ) {
		return true;
	}

	$data = explode( '.', $topic );

	if ( ! isset( $data[0] ) || ! isset( $data[1] ) ) {
		return false;
	}

	$default_resources = array( 'coupon', 'customer', 'order', 'product' );
	$default_events    = array( 'created', 'updated', 'deleted', 'restored', 'published' );

	/**
	 * Filters the list of valid webhook resources.
	 *
	 * @since 2.2.0
	 * @param array $valid_resources Array of valid webhook resources.
	 */
	$valid_resources = apply_filters( 'woocommerce_valid_webhook_resources', $default_resources );

	/**
	 * Filters the list of valid webhook events.
	 *
	 * @since 2.2.0
	 * @param array $valid_events Array of valid webhook events.
	 */
	$valid_events = apply_filters( 'woocommerce_valid_webhook_events', $default_events );

	if ( ! in_array( $data[0], $valid_resources, true ) || ! in_array( $data[1], $valid_events, true ) ) {
		return false;
	}

	// Topics that include a filter-added resource or event are accepted; plugins
	// extending the resource/event lists are expected to wire delivery via the
	// `woocommerce_webhook_topic_hooks` or `woocommerce_webhook_hooks` filters.
	if ( ! in_array( $data[0], $default_resources, true ) || ! in_array( $data[1], $default_events, true ) ) {
		return true;
	}

	// Default-resource + default-event topics must correspond to a registered
	// hook. Pairs without one (e.g. `order.published`, `customer.restored`) save
	// as Active webhooks but never deliver, so reject them.
	//
	// The allowlist is derived from `WC_Webhook::get_default_topic_hooks()`,
	// which runs through the `woocommerce_webhook_topic_hooks` filter.
	// Extensions that register hooks for an otherwise-empty default pair (via
	// that filter) are therefore honored automatically, with no separate
	// allowlist to keep in sync.
	$default_topics = array_keys( array_filter( WC_Webhook::get_default_topic_hooks() ) );

	return in_array( $topic, $default_topics, true );
}