Home > Software design >  How to prevent direct access to success page after the payment?
How to prevent direct access to success page after the payment?

Time:04-10

I'm using React 18.0, React Router Dom (v6), and I'm trying to implement Paypal Checkout. It works well and after the payment I redirect the user to my success page which contains a download link for the user. The problem is this success page is always reachable. So, I'm trying to allow the access just after the checkout. After then, the user should be redirected to the home.

I tried doing like this but without success:

import { useEffect } from "react"
import { useLocation, useNavigate } from "react-router-dom"
import { getInvoiceUrl } from "../services/invoiceService"

function Success() {
    // Get the state from navigate on the Checkout page
    let { state, pathname } = useLocation()
    const navigate = useNavigate()

    // Check the state in order to redirect the user to the homepage if the state is empty
    useEffect(() => {
        if (state === null || state === undefined) {
            navigate("/")
            return
        }
        // Clear the state after the user exits from the Success page
        return navigate(pathname, { replace: true })
    })

    if (state === null || state === undefined) {
        return
    }

    console.log("state:", state)
    return (
                  <>
                    <div>
                        Thank you!
                    </div>
                    <div>
                        Abbiamo appena inviato un'email a
                        <span>
                            {state.email}
                        </span>
                        con in allegato la tua ricevuta (per favore, controlla la cartella SPAM se non dovessi vederla).
                    </div>
                    <div>
                        Puoi anche scaricare la ricevuta facendo click qui:
                        <a download href={getInvoiceUrl()}>
                            Download
                        </a>
                    </div>
                  </>
    )
}

export default Success

CodePudding user response:

lol I just create the whole scenario of the problem and guess what you don't return anything you need to return null

Error: Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null

just try this

  let { state, pathname } = useLocation();
  const navigate = useNavigate();

  useEffect(() => {
    if (!state) {
      navigate("/");
    }

    return function cleanup() {
      navigate(pathname, { replace: true });
      navigate("/");
    };
  }, []);

  if (!state) {
    return null;
  }

  return (
      <div>
        Abbiamo appena inviato un'email a<span>{state.email}</span>
        con in allegato la tua ricevuta (per favore, controlla la cartella SPAM
        se non dovessi vederla).
      </div>
  );

enter image description here

CodePudding user response:

For state === null || state === undefined condition you are missing returning valid JSX. Return null here to indicate to React there's nothing to render.

function Success() {
  // Get the state from navigate on the Checkout page
  const { state } = useLocation();
  const navigate = useNavigate();

  // Check the state in order to redirect the user to the homepage if the state is empty
  useEffect(() => {
    if (!state) {
      navigate("/", { replace: true }); // <-- redirect to prevent access
      return;
    }
  });

  if (!state) {
    return null; // <-- return valid JSX
  }

  return ( ... );
}

OR, to eliminate the need for the useEffect, return the Navigate component.

function Success() {
  // Get the state from navigate on the Checkout page
  const { state } = useLocation();

  if (!state) {
    return <Navigate to="/" replace />; // <-- return Redirect
  }

  return ( ... );
}
  • Related