Here’s the flow:
- Hit the stripe checkout end-point
- If the payment was successful, send an email to user
Email includes:
- Customer Name
- Starting date
- Ending date
So, far I’m able to hit the stripe checkout end-point then redirecting the user to that page and make the payment. But, I’m unable to pass the parameters that are required in the email to be sent.
Stripe Function
app.post('/stripe-checkout', async (req, res) => {
try {
let baseUrl = req.query.env == 'prod' ? 'https://leaf-for-business.web.app' : 'http://localhost:8080';
const session = await stripe.checkout.sessions.create({
line_items: [
{
price_data: {
currency: 'usd',
product_data: {
name: 'Promotion Payment',
},
unit_amount: req.query.amount * 100, /// 1USD = 100 Cents
},
quantity: 1,
}
],
mode: 'payment',
payment_method_types: [ "card" ],
success_url: baseUrl + '/home',
});
res.send({
success: true,
session_id: session.id,
redirect_url: session.url,
});
} catch (error) {
res.status(404).send({
success: false,
error: error.message,
});
}
});
Webhook Function
app.post('/webhook', (request, response) => {
const sig = request.headers['stripe-signature'];
const endpointSecret = process.env.WEBHOOK_SECRET;
let event;
try {
event = stripe.webhooks.constructEvent(request.body, sig, endpointSecret);
} catch (err) {
response.status(400).send(`Webhook Error: ${err.message}`);
return;
}
// Handle the event
switch (event.type) {
case 'checkout.session.completed':
const checkoutSessionCompleted = event.data.object;
sendEmail(request.body); /// <<-- HERE'S THE PROBLEM
break;
default:
console.log(`Unhandled event type ${event.type}`);
}
// Return a 200 response to acknowledge receipt of the event
response.send();
});
Email Send
async function sendEmail(body) {
const DOMAIN = "app.joinleaf.com";
const SENDER_EMAIL = "[email protected]";
const mailgun = new Mailgun(formData);
const mg = mailgun.client({
username: 'api',
key: process.env.MG_PRIVATE_KEY,
host: "api.eu.mailgun.net",
});
const customerEmail = body.email;
const customerName = body.customer_name;
//
const startDate = body.start_date;
const endDate = body.end_date;
const emailBody = fs.readFileSync('src/email.html', 'utf8').toString();
const finalTemp = emailBody.replaceAll('customer-name', customerName)
.replace('start-date', startDate)
.replace('end-date', endDate);
const messageData = {
from: SENDER_EMAIL,
// to: [customerEmail, "[email protected]"],
to: [customerEmail, "[email protected]"],
// bcc: ["getleaflets.co"],
subject: "Thank you for your purchase.",
html: finalTemp,
};
const resp = await mg.messages.create(DOMAIN, messageData, (err, body) => {
if (!err) {
console.log('Sent! ' + body);
} else {
console.log(err);
}
});
return resp;
}
Now, how can I send the name, start and end date to webhook so that it can be passed to email function if the payment is a success
2
Answers
The webhook will have the exact data that is on the Checkout Session object. If you want to add arbitrary values to the Checkout Session object you can set them as
metadata
on the Session when you are creating it[1].[1] https://stripe.com/docs/api/metadata
Really you should be passing the
checkoutSessionCompleted
variable you created to yoursendEmail
function likesendEmail(checkoutSessionCompleted)
instead of what you have.That object is the CheckoutSession object for the successful payment which you’re handling from the webhook and everything in it is fully documented — it will have all the fields explained at https://stripe.com/docs/api/checkout/sessions/object
So inside
sendEmail
, the email address the customer used is available, same with the name and so on.body.customer_email
-> customer’s email -> https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-customer_emailbody.customer_details.name
-> customer’s entered name -> https://stripe.com/docs/api/checkout/sessions/object#checkout_session_object-customer_details-nameAnd so on, you can look at the Stripe API reference to see what’s in the object.