Shopify orders/create Webhook无法正常工作问题求助
问题排查与修复方案
1. 解决Webhook请求体解析冲突(最常见触发失败原因)
Shopify Webhook的签名验证依赖原始未解析的请求体,如果你的Express应用全局启用了express.json()或express.urlencoded()中间件,会提前解析请求体,导致Shopify的签名校验失败,直接跳过Webhook Handler执行。
修复方式:
// 对webhook路由单独使用raw中间件,保留原始请求体 app.post('/api/webhooks', express.raw({ type: 'application/json' }), async (req, res) => { try { await Shopify.Webhooks.Registry.process(req, res); console.log(`Webhook processed, returned status code 200`); } catch (e) { console.log(`Failed to process webhook: ${e.message}`); if (!res.headersSent) { res.status(500).send(e.message); } } });
2. 修复sendEmail函数的Promise异步问题
当前sendEmail是async函数,但内部用回调式调用smtpTransport.sendMail,没有正确返回Promise,导致await sendEmail()不会等待邮件发送完成,且错误无法被外层捕获。
修复方式:
async function sendEmail(to, subject, html) { const mailOptions = { from: "*****@gmail.com", to, subject, html }; // 用Promise封装sendMail,确保await生效并能捕获错误 try { const info = await smtpTransport.sendMail(mailOptions); console.log("mail sent:", info.messageId); return info; } catch (err) { console.error("邮件发送失败:", err); throw err; // 抛出错误让外层处理 } }
3. 增加Webhook Handler的错误捕获与字段校验
当前Handler中没有错误捕获逻辑,一旦订单数据缺失关键字段(比如匿名订单无customer、部分订单无shipping_address),会直接崩溃但不会输出日志,导致你误以为Webhook没触发。
修复方式:
Shopify.Webhooks.Registry.addHandler("ORDERS_CREATE", { path: "/api/webhooks", webhookHandler: async (_topic, _shop, body) => { try { const payload = JSON.parse(body); // 校验核心字段是否存在 if (!payload.customer?.email) { console.log("订单无有效客户邮箱,跳过邮件发送"); return; } const { email } = payload.customer; const first_name = payload.customer.first_name || "Customer"; const last_name = payload.customer.last_name || ""; // 处理可能为空的配送地址 const shippingAddr = payload.shipping_address || {}; const { address1 = "", address2 = "", city = "", province = "", country = "", zip = "" } = shippingAddr; const html = ` <p>Dear ${first_name} ${last_name},</p> <p>Thank you for your purchase! Your order will be shipped to the following address:</p> <p> ${address1}<br> ${address2 ? address2 + "<br>" : ""} ${city}, ${province} ${zip}<br> ${country} </p> <p>We hope you enjoy your purchase!</p> `; await sendEmail(email, "Thank you for your purchase!", html); } catch (err) { console.error("Webhook处理异常:", err); throw err; } }, });
4. 验证Gmail SMTP配置有效性
- 若Gmail账号开启了2FA,必须使用应用专用密码(App Password),不能直接用账号登录密码;
- 未开启2FA的账号,需临时开启“低安全性应用访问”(不推荐,建议启用2FA后用应用密码);
- 确认SMTP配置参数正确:
const smtpTransport = nodemailer.createTransport({ service: "gmail", auth: { user: "your-email@gmail.com", pass: "your-app-password" // 替换为应用专用密码 } });
5. 检查Shopify后台Webhook注册状态
- 登录Shopify开发商店后台,进入设置 > 通知 > Webhooks;
- 确认
orders/create类型的Webhook已正确注册,URL指向你的应用/api/webhooks,格式为JSON,状态为“已启用”; - 点击“发送测试通知”按钮,查看应用控制台是否有日志输出,验证Webhook是否能正常触发。
内容的提问来源于stack exchange,提问作者Cengiz
相关产品推荐
相关产品推荐

