WordPress 302 Redirect to Random Product/Post/Page

A shortcode is the wrong way to go about this. Shortcodes are for outputting content, not handing things like redirects.

What we need to do is:

  1. Create a rewrite rule for the /random/ URL that will trigger the redirect.
  2. When the /random/ URL is visited, get a random post/page/product/ and redirect to its URL with a 302.

For step 1 we’ll use the rewrite endpoints API to register a /random/ endpoint to the home URL, so that http://example.com/random/ is a URL that we can visit:

function wpse_320084_random_endpoint() {
    add_rewrite_endpoint( 'random', EP_ROOT );
}
add_action( 'init', 'wpse_320084_random_endpoint' );

Make sure to visit Settings > Permalinks to flush the permalinks, or this won’t work.

Then we’ll hook into template_redirect so that we can redirect the user to a random post if they visit our URL:

function wpse_320084_random_redirect() {
    // If we have accessed our /random/ endpoints.
    if ( get_query_var( 'random', false ) !== false ) {
        // Get a random post.
        $random_post = get_posts( [
            'numberposts' => 1,
            'post_type'   => [ 'post', 'page', 'product' ],
            'orderby'     => 'rand',
        ] );

        // If we found one.
        if ( ! empty( $random_post ) ) {
            // Get its URL.
            $url = esc_url_raw( get_the_permalink( $random_post[0] ) );

            // Escape it.
            $url = esc_url_raw( $url );

            // Redirect to it.
            wp_safe_redirect( $url, 302 );
            exit;
        }
    }
}
add_action( 'template_redirect', 'wpse_320084_random_redirect' );

If you want a separate URL for each post type, then anything passed after an endpoint is accessible with get_query_var():

function wpse_320084_random_redirect() {
    $post_type = get_query_var( 'random' );

    if ( post_type ) {
        $random_post = get_posts( [
            'numberposts' => 1,
            'post_type'   => $post_type,
            'orderby'     => 'rand',
        ] );

        if ( ! empty( $random_post ) ) {
            $url = esc_url_raw( get_the_permalink( $random_post[0] ) );
            $url = esc_url_raw( $url );

            wp_safe_redirect( $url, 302 );
            exit;
        }
    }
}
add_action( 'template_redirect', 'wpse_320084_random_redirect' );

With that code, /random/post/ will load a random post, /random/page/ will load a random page, and /random/product/ will load a random product. Any post type you send after /random/ will redirect to a random post of that type.