You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:35:28