如何将用户信息传递至Stripe Webhook以发送支付成功邮件?
解决方案:传递自定义参数到Stripe Webhook并发送邮件
要解决这个问题,你需要利用Stripe Checkout Session的**metadata字段**存储自定义数据,这些数据会在支付完成后的Webhook事件中返回,具体步骤如下:
1. 创建Checkout Session时存入自定义数据
修改Stripe结账端点代码,在stripe.checkout.sessions.create配置中添加metadata字段,将客户姓名、开始日期、结束日期及客户邮箱存入(假设前端通过req.body传递这些参数,可根据实际调整为req.query):
app.post('/stripe-checkout', async (req, res) => { try { let baseUrl = req.query.env == 'prod' ? 'https://leaf-for-business.web.app' : 'http://localhost:8080'; // 从请求中提取所需参数 const { customerName, startDate, endDate, customerEmail } = req.body; 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', // 添加metadata存储自定义业务数据 metadata: { customer_name: customerName, start_date: startDate, end_date: endDate, email: customerEmail } }); res.send({ success: true, session_id: session.id, redirect_url: session.url, }); } catch (error) { res.status(404).send({ success: false, error: error.message, }); } });
2. 在Webhook中提取数据并传递给邮件函数
修改Webhook代码,从checkout.session.completed事件的session对象中取出metadata数据,再传给sendEmail函数(替代原有的直接传递request.body):
app.post('/webhook', async (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; } // 处理事件 switch (event.type) { case 'checkout.session.completed': const checkoutSession = event.data.object; // 从session的metadata中提取需要的数据 const emailData = { customer_name: checkoutSession.metadata.customer_name, start_date: checkoutSession.metadata.start_date, end_date: checkoutSession.metadata.end_date, email: checkoutSession.metadata.email }; // 调用邮件发送函数,添加await确保执行完成 await sendEmail(emailData); break; default: console.log(`Unhandled event type ${event.type}`); } // 返回200响应确认事件接收 response.send(); });
3. 优化邮件发送函数(可选)
调整sendEmail函数的参数接收逻辑,让代码更清晰:
async function sendEmail(emailData) { const DOMAIN = "app.joinleaf.com"; const SENDER_EMAIL = "no-reply@app.joinleaf.com"; const mailgun = new Mailgun(formData); const mg = mailgun.client({ username: 'api', key: process.env.MG_PRIVATE_KEY, host: "api.eu.mailgun.net", }); // 解构数据 const customerEmail = emailData.email; const customerName = emailData.customer_name; const startDate = emailData.start_date; const endDate = emailData.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, "team@getleaflets.co"], subject: "Thank you for your purchase.", html: finalTemp, }; try { const resp = await mg.messages.create(DOMAIN, messageData); console.log('Sent! ' + resp); return resp; } catch (err) { console.log(err); throw err; } }
关键说明
- Stripe的
metadata字段是存储自定义业务数据的标准方式,会随Checkout Session事件一并返回。 - 需确保前端调用
/stripe-checkout接口时,正确传递customerName、startDate、endDate、customerEmail参数。 - Webhook函数添加
async/await,避免邮件发送逻辑异步执行导致的潜在问题。
内容的提问来源于stack exchange,提问作者Hamza
相关产品推荐
相关产品推荐

