Reputation: 71
I have the following setup: a very simple web app written with Node & Express. There is a simple index.html page that only contains a Stripe Payment link, as shown below:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Stripe Payment Link</title>
</head>
<body>
<p>Stripe Payment Link</p>
<a href="https://buy.stripe.com/test_28oaGrdLl3q28jCbII">buy</a>
</body>
</html>
In the Stripe dashboard I have setup the payment link to redirect to a success page, once the payment is completed. The success page is very simple and it has a div element where I try to display the email of the customer who made the purchase:
<div id="paymentDetails">
<p>
<%= customerEmail %>
</p>
</div
In the main Node file - app.js (the one that starts the app) I have the followings:
What I want to achieve is the following: once I capture the customer email address from the Stripe webhook event, I want to somehow pass this customer email address to the success page. I tried to add the email address as a session variable, but I realized that the Stripe webhook where I get the email address has a different session from my web application session, hence this is not working.
Any advice is more than welcome, thank you very much!
-- The code for ap.js below:
const express = require('express');
const session = require('express-session');
const path = require('path');
const stripe = require('stripe')('sk_test_');
// This is your Stripe CLI webhook secret for testing your endpoint locally.
const endpointSecret = "whsec_";
// Use body-parser to retrieve the raw body as a buffer
const bodyParser = require('body-parser');
var https = require('https');
var fs = require('fs');
var cookieParser = require('cookie-parser');
var options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./key-cert.pem')
};
// ---------------------------------------------
const port = process.env.PORT || 3000;
const app = express();
// Middleware for session management
app.use(session({
secret: 'kjdakadkdakdakdakldakldadakl',
resave: true,
saveUninitialized: true
}));
// static files are stored in public folder
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
// view engine setup
app.set('views', path.join(__dirname, 'views'));
// Default route
app.get('/', (req, res) => {
console.log('Entering default route....session id = ' + req.sessionID);
// Send the index.html file
//req.session.var1= 'this is var 1 stored in session';
res.sendFile(path.join(__dirname, './views/index.html'));
});
app.get('/sess', (req, res) => {
console.log('enter session route...sessionID = ' + req.sessionID);
// Render the success.ejs page and pass the email as a parameter
var var1 = req.session.var1;
if (var1) {
console.log('we found var1 '+ var1);
}
else {
console.log('There is no var1 stored in session....');
}
res.render('session', {var1: var1}) ;
});
// Define a route for handling successful payment redirection
app.get('/success', (req, res) => {
console.log('enter success route...')
// Render the success.ejs page and pass the email as a parameter
var emailVar = req.session.customerEmail;
console.log('Reading data from session: ' + req.sessionID);
if (emailVar) {
console.log('we found email '+ emailVar);
}
else {
console.log('There is no customer email stored in session....');
}
res.render('success', {customerEmail: emailVar}) ;
});
// Stripe webhook route where Stripe will send notifications about the payment status
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
console.log('Entering Stripe webhook....')
const sig = req.headers['stripe-signature'];
let event;
let customerEmail;
try {
event = stripe.webhooks.constructEvent(req.body, sig, endpointSecret);
//event = request.body;
}
catch (err) {
console.log('Entering error....' + err);
response.status(400).send(`Webhook Error: ${err.message}`);
return;
}
console.log('Event type is ' + event.type);
const paymentIntent = event.data.object;
console.log("we obtained the Event Data...id = " + paymentIntent.id + ', object type = ' + paymentIntent.object);
// Handle the event
switch (event.type) {
case 'payment_intent.succeeded':
console.log('Payment is successfull says Stripe webhook....');
console.log('Amount paid by customer is: ' + paymentIntent.amount_received);
// Then define and call a function to handle the event payment_intent.succeeded
break;
case 'payment_intent.created':
console.log('Payment intent created....');
break;
case 'charge.succeeded':
customerEmail = paymentIntent.billing_details.email;
console.log('Charge succedeed says Stripe webhook....');
console.log('Email address of customer is: ' + customerEmail);
//response.redirect('/success.html?email=${customerEmail}');
// Store the customer email in the session
if (req.session.customerEmail) {
console.log('Webhook: there is an customerEmail in the session');
}
else {
console.log('Webhook: there is NO customerEmail in the session');
req.session.customerEmail = customerEmail;
console.log('webhook: check if we can retrieve the customerEmail from session: ' + req.sessionID + '....'+ req.session.customerEmail);
}
break;
case 'checkout.session.completed':
console.log('Checkout session completed says Stripe webhook....');
break;
// ... handle other event types
default:
console.log(`Unhandled event type ${event.type}`);
}
// Return a 200 response to acknowledge receipt of the event
res.send();
});
// custom 404 page
app.use((req, res) => {
res.type('text/plain')
res.status(404)
res.send('404 - Not Found')
})
// custom 500 page
app.use((err, req, res, next) => {
console.error(err.message)
res.type('text/plain')
res.status(500)
res.send('500 - Server Error')
})
// Create a NodeJS HTTPS listener on port 4000 that points to the Express app
// Use a callback function to tell when the server is created.
/*https
.createServer(options, app)
.listen(port, ()=>{
console.log('server is running at port 3000')
});*/
app.listen(port, () => console.log(`Express started on http://localhost:${port}; ` + `press Ctrl-C to terminate.`))
Upvotes: 0
Views: 115