Richlewis
Richlewis

Reputation: 15384

Redirect to a different page after Stripe payment - Node.js

I am in the process of putting together a custom checkout button on my site, following the guide at https://stripe.com/docs/recipes/custom-checkout. So far the test payment will go through, I can create a customer and a new charge.

The part I am stuck on is actually redirecting the user to a /success page after the transaction for example with details of the charge made. I've tried using res.render('success') and even res.redirect('/success') but it does not execute.

<button id="upgrade_membership"</button>

<script>
  var checkoutHandler = StripeCheckout.configure({
    key: "<%= keyPublishable %>",
    locale: "auto"
  });

  var button = document.getElementById("upgrade_membership");
    button.addEventListener("click", function(ev) {
    checkoutHandler.open({
      name: "Name",
      description: "Description",
      image: 'images/path.jpg',
      token: handleToken
    });
  });

  function handleToken(token) {
    fetch("/charge", {
      method: "POST",
      headers: {"Content-Type": "application/json"},
      body: JSON.stringify(token)
    })
    .then(response => {
      if (!response.ok)
        throw response;
        return response.json();
      })
   .then(output => {
     console.log("Purchase succeeded:", output);
   })
   .catch(err => {
     console.log("Purchase failed:", err);
   })
}
</script>

Server

app.post("/charge", async (req, res) => {
  let amount = 1000;

  // Check user has stripe id as stripe do not check for uniqueness of email address
  try {
    var user_stripe_id = await queries.get_stripe_id_by_email(req.body.email);
  } catch (err) {
    console.log("Error with Query " + err);
    return;
  }

  if(user_stripe_id !== null) {
    // Need to process payment as a current customer on stripe
    return;
  } else {
    // Create Stripe Customer
    stripe.customers.create({
      email: req.body.email,
      card: req.body.id
    })
  .then(customer =>
    // Charge Customer payment
    stripe.charges.create({
      amount,
      description: "description here",
      currency: "GBP",
      customer: customer.id
    }))
    .then(charge => {
      // gets all the way here and logs out the charge object
      // want to redirect here
      res.send(charge)
      // if i replace the above with res.render('home') nothing happens 
    })
    .catch(err => {
      console.log("Error:", err);
      res.status(500).send({error: "Purchase Failed"});
    });
   } // if/else
});

So upon a successful transaction in the browser console I get Purchase succeeded: printed.

What I want to achieve is a redirect server side to another page.

Update

So I am trying to render a different page here after the payment has been successful but I cannot get anything to work

res.render('home') // does not work
return res.render('home') // does not work
return res.redirect('/') // does not work
res.redirect('/') // does not work

And even more confusing

console.log("I WANT TO RENDER A NEW PAGE")
res.render('home')
console.log("WHY IS THIS BEING LOGGED")

Both console logs are getting logged

Is it because I am in a then chain?

Upvotes: 0

Views: 2539

Answers (1)

Will Henderson
Will Henderson

Reputation: 11

The problem is to do with how the fetch API and POST requests work. See this SO discussion for why you can't use res.render() with the fetch API and this SO discussion for how to redirect after a fetch request from the client side.

Putting these together, you can send back the url you want to redirect to in the fetch reponse, and then redirect to this url from the client side using window.location.replace(...)

Upvotes: 1

Related Questions