如何为WooCommerce自定义邮件添加PDF附件?现有代码不生效求排查
问题诊断
你的代码存在4个核心问题,直接导致附件邮件发送失效:
- 钩子参数接收错误:
woocommerce_order_status_changed动作钩子默认传递4个参数,你声明的函数只接收2个参数,且额外传入的$checkout参数无效,同时直接实例化WC_Order会产生不必要的数据库查询开销。 - 附件路径拼接错误:
WP_CONTENT_DIR常量默认不带末尾的路径分隔符,直接拼接文件名会生成非法路径,系统无法定位到PDF文件。 - 订单属性调用不兼容WooCommerce 3.0+版本:直接通过
$order->billing_email读取属性是WooCommerce 2.x的废弃用法,3.0以上版本必须使用get_billing_email()方法获取邮箱地址,否则无法正确读取收件人信息。 - 状态判断逻辑冗余:不需要在触发状态变更钩子后再次查询订单状态,直接判断新状态是否为
completed即可,避免时序问题导致的判断失效。
修复方案
前置准备
先将PDF文件上传到站点wp-content目录下,比如文件命名为gift.pdf,确认文件权限为644,确保Web服务进程有读取权限。
修正后完整代码
add_action("woocommerce_order_status_changed", "dobierka_gift", 10, 4); function dobierka_gift($order_id, $old_status, $new_status, $order) { // 直接判断新状态是否为已完成,且支付方式为dobirka if( $new_status === 'completed' && $order->get_payment_method() === 'dobirka' ) { $mailer = WC()->mailer(); // 修正路径拼接,适配不同系统的路径规则,替换gift.pdf为你的实际PDF文件名 $attachments = array( WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'gift.pdf' ); $message_body = sprintf( __( '尊敬的%s,您好:这里是邮件正文内容' ), $order->get_billing_first_name() ); $message = $mailer->wrap_message( sprintf( __( '您的订单%s已完成,附赠礼品请查收' ), $order->get_order_number() ), $message_body ); // 改用官方getter方法获取收件人邮箱 $mailer->send( $order->get_billing_email(), sprintf( __( '订单%s已完成,您的专属礼品已附上' ), $order->get_order_number() ), $message, '', $attachments ); } }
可选优化
如果你不需要单独发送自定义邮件,想直接把附件挂载到WooCommerce默认的订单完成通知邮件里,可以改用woocommerce_email_attachments钩子挂载附件,避免重复发邮件打扰用户。
内容的提问来源于stack exchange,提问作者Lubo Masura
相关产品推荐
相关产品推荐

