0

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?

JOKKER
  • 502
  • 6
  • 21
  • what kind of page is that? Is so important that someone logged in should not see it? – Alberto Sinigaglia Jan 08 '21 at 22:10
  • It's a form page for collecting further details about the customer's order. Only customers that purchased a package should be able to access this form and submit their details. – JOKKER Jan 08 '21 at 23:36

1 Answers1

3

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 2 ... 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.

amarinediary
  • 4,930
  • 4
  • 27
  • 45
  • 1
    Hi @amarinediary. Thank you for your answer. Where in this code should I define the page that I'm trying to prevent access to? – JOKKER Jan 08 '21 at 23:39
  • is_page(2072)` is the page you want to protect ? – amarinediary Jan 08 '21 at 23:55
  • 1
    Correct. That's the ID of the page I want to be accessible only to users coming after checkout. – JOKKER Jan 09 '21 at 09:34
  • I've edited the post to take your page into account. This does the job (it seems) but I'm no PHP expert. You could also check the status of the latest order, and based on that let the user view the page or not. – amarinediary Jan 09 '21 at 10:34
  • Good day, Your code works perfectly, but I have an issue. In my case, instead of a specific url, I want it to be if the referrer is coming from a url that contains a path, e.g example.com/path So if the url is example.com/path/another-path, it will still work. Can this be done? Thank you – CMS Aug 10 '23 at 09:21