Skip to content
Advertisement

Prevent direct access to a page in WordPress

I need some help. I am trying to prevent direct access to a page that my customers get redirected to after checkout. I want the page to be accessible only after checkout.

I have found this topic: https://wordpress.stackexchange.com/questions/290234/prevent-block-direct-access-to-a-thank-you-page

I placed the following code snippet to my functions.php:

add_action('template_redirect', function() {
    // ID of the redirect page
    if (!is_page(2072)) {
        return;
    }

    // URL of checkout page
    if (wp_get_referer() === 'https://www.exampledomain.com/checkout/') {
        return;
    }

    // we are on thank you page
    // visitor is not coming from form
    // so redirect to home
    wp_redirect(get_home_url());
    exit;
} );

This works fine if the customer pays through Stripe. However, it does not work if the customer chooses to pay through PayPal because PayPal redirects the customer to their website to make the payment.

Can something be done here to fix this issue?

Advertisement

Answer

You could do it the other way around. Only accept an array of predefined urls. For example here we have defined an array with github and stackoverflow as referees. If the referring url isn’t one of those two, then we kill the process. With wp_die() we can display a custom message and a backlink, and with header() we can redirect automatically after 3 seconds.

add_action( 'wp', function() {
  if( is_page( '3975' ) && ! is_admin() ) { // restrict page ID '2072' if it's on the front end and if user doesn't have the permissions
    $base = [ // allowed referees
      'https://github.com/', // referee 1
      'https://stackoverflow.com/', // referee 1 ... and so on
    ];
    if( ! in_array( $_SERVER['HTTP_REFERER'], $base ) ) { // if not in referees
      header( 'Refresh: 3; ' . esc_url( home_url() ) ); // redirect in 3 seconds
      wp_die( 'Something went wrong.', NULL, $args = array( 'back_link' => true, ) ); // kills WordPress execution and displays an HTML page with an error message
      exit; // terminate the current script
    };
  };
} );

I’ve had a look at a bunch of things. wp_get_referer() can’t be used that way as it’s specific to WordPress

Retrieve referer from _wp_http_referer or HTTP referer. If it’s the same as the current request URL, will return false.

I’m using $_SERVER['HTTP_REFERER'] instead @ https://stackoverflow.com/a/16374737/3645650. Which does the job I thaught wp_get_referer() would do.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement