邮件已经发送成功,但模板里的订单号、客户名称或自定义内容是空白,这类问题通常与 SMTP 无关。传输链路已经工作,接下来要看模板写了什么变量,以及发送代码实际传入了什么。
先确认变量名称
模板中写 {{var order.increment_id}},前提是发送时确实存在名为 order 的对象,并且模板系统允许访问对应数据。变量名大小写或层级不一致,通常不会报明显异常,只会渲染为空。
后台邮件模板页面会显示可用变量信息,但自定义模块新增的变量仍需在代码和模板之间保持一致。
自定义邮件的传值示例
$transport = $this->transportBuilder
->setTemplateIdentifier($templateId)
->setTemplateOptions([
'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
'store' => $storeId,
])
->setTemplateVars([
'customer_name' => $customerName,
'order_number' => $order->getIncrementId(),
'support_note' => $supportNote,
])
->setFromByScope('general', $storeId)
->addTo($recipient)
->getTransport();
$transport->sendMessage();
对应模板应使用 {{var customer_name}}、{{var order_number}} 和 {{var support_note}},而不是继续按订单对象的写法读取。
对象、数组和标量不要混用
如果代码把 order_number 作为字符串传入,模板就不能写成 order_number.increment_id。反过来,传入对象时也要确认模板安全规则允许访问目标字段。最稳妥的方式是只传模板真正需要的标量值,减少对象暴露。
Store View 也会让测试产生误判
邮件模板可按 Store View 配置。你修改了中文模板,但测试订单属于英文 Store View,收到的仍可能是另一份模板。记录订单的 store_id,并检查发送代码中的 template options。
一个实用的调试方法
在测试环境记录变量键名和非敏感值类型,例如字符串、整数或对象类名,不要把客户地址、Token 或完整订单内容写进日志。确认键名到达 TransportBuilder 后,再回头检查模板。
邮件变量问题修好后,用游客订单、注册客户订单和不同 Store View 各发一封。三封邮件的模板和变量都正确,才说明不是偶然命中了默认范围。

