WooCommerce订单确认邮件添加按钮及订单状态更新问题
WooCommerce订单确认邮件添加确认/取消按钮问题
我希望在WooCommerce订单确认邮件中添加“确认订单”和“取消订单”两个按钮。用户点击按钮后跳转至网站对应URL,同时订单状态更新:确认设为completed,取消设为cancelled。
我已尝试的操作:
- 创建自定义端点处理按钮操作:
// Add this code to your theme's functions.php file or create a custom plugin. add_action('init', 'custom_order_actions'); function custom_order_actions() { add_rewrite_endpoint('confirm-order', EP_ROOT); add_rewrite_endpoint('cancel-order', EP_ROOT); }
- 编辑订单确认邮件模板(按钮未显示):
<a href="<?php echo esc_url(wc_get_order_url($order->get_id()) . 'confirm-order'); ?>" class="button" style="color:#ffffff; background-color:#4CAF50; text-decoration: none;">Confirm Order</a> <a href="<?php echo esc_url(wc_get_order_url($order->get_id()) . 'cancel-order'); ?>" class="button" style="color:#ffffff; background-color:#ff0000; text-decoration: none;">Cancel Order</a>
- 处理按钮触发的状态更新:
// Confirm Order add_action('template_redirect', 'confirm_order_action'); function confirm_order_action() { global $wp; if (isset($wp->query_vars['confirm-order'])) { // Update order status to completed $order_id = absint($_GET['order_id']); $order = wc_get_order($order_id); $order->update_status('completed'); // Redirect to confirmation page wp_redirect(home_url('/order-confirmed')); exit; } } // Cancel Order add_action('template_redirect', 'cancel_order_action'); function cancel_order_action() { global $wp; if (isset($wp->query_vars['cancel-order'])) { // Update order status to cancelled $order_id = absint($_GET['order_id']); $order = wc_get_order($order_id); $order->update_status('cancelled'); // Redirect to confirmation page wp_redirect(home_url('/order-cancelled')); exit; } }
请问我的逻辑是否正确?有没有更简便的实现方式?目前按钮无法显示在确认邮件中,代码已添加至woocommerce/emails/templates目录。
逻辑正确性与问题修复
你的核心方向没问题,但存在几个关键细节漏洞:
- URL参数缺失:当前按钮URL没有携带
order_id参数,导致后端$_GET['order_id']无法获取值,状态更新会直接失效。 - 模板路径错误:WooCommerce邮件模板的正确覆盖路径是
主题目录/woocommerce/emails/customer-processing-order.php(客户处理中订单邮件),而非emails/templates目录,这是按钮不显示的主要原因。 - 安全性缺失:没有添加CSRF验证,恶意用户可能通过构造URL篡改任意订单状态。
按钮显示修复步骤
- 调整模板路径:将修改后的模板文件移动到
主题目录/woocommerce/emails/下,替换对应的默认邮件模板(比如customer-processing-order.php)。 - 修正按钮URL:补充
order_id参数,确保后端能识别订单:
<a href="<?php echo esc_url(add_query_arg('order_id', $order->get_id(), home_url('/confirm-order'))); ?>" class="button" style="color:#ffffff; background-color:#4CAF50; text-decoration: none; padding: 10px 20px; border-radius: 4px;">确认订单</a> <a href="<?php echo esc_url(add_query_arg('order_id', $order->get_id(), home_url('/cancel-order'))); ?>" class="button" style="color:#ffffff; background-color:#ff0000; text-decoration: none; padding: 10px 20px; border-radius: 4px;">取消订单</a>
- 刷新固定链接:添加自定义端点后,需要到WordPress后台「设置-固定链接」页面点击保存,刷新规则。
更简便的实现方式(无需修改模板+安全验证)
直接用WooCommerce钩子插入按钮,同时添加nonce验证防止恶意操作:
- 通过钩子添加邮件按钮:
add_action('woocommerce_email_order_details', 'add_confirm_cancel_buttons_to_email', 20, 4); function add_confirm_cancel_buttons_to_email($order, $sent_to_admin, $plain_text, $email) { // 仅在客户订单处理邮件中显示按钮 if (!$sent_to_admin && $email->id === 'customer_processing_order') { // 生成带验证的确认/取消URL $confirm_url = wp_nonce_url( add_query_arg(['action' => 'confirm_order', 'order_id' => $order->get_id()], home_url()), 'confirm_order_nonce' ); $cancel_url = wp_nonce_url( add_query_arg(['action' => 'cancel_order', 'order_id' => $order->get_id()], home_url()), 'cancel_order_nonce' ); // 输出按钮HTML echo '<div style="margin: 24px 0;">'; echo '<a href="' . esc_url($confirm_url) . '" style="display: inline-block; padding: 12px 24px; background: #4CAF50; color: #fff; text-decoration: none; border-radius: 4px; margin-right: 12px;">确认订单</a>'; echo '<a href="' . esc_url($cancel_url) . '" style="display: inline-block; padding: 12px 24px; background: #ff0000; color: #fff; text-decoration: none; border-radius: 4px;">取消订单</a>'; echo '</div>'; } }
- 处理按钮请求并验证权限:
add_action('template_redirect', 'handle_order_confirm_cancel_actions'); function handle_order_confirm_cancel_actions() { if (!isset($_GET['action'], $_GET['order_id'], $_GET['_wpnonce'])) return; $order_id = absint($_GET['order_id']); $order = wc_get_order($order_id); if (!$order) { wp_redirect(home_url('/404')); exit; } // 验证操作权限 if ($_GET['action'] === 'confirm_order' && wp_verify_nonce($_GET['_wpnonce'], 'confirm_order_nonce')) { $order->update_status('completed', '客户主动确认订单'); wp_redirect(home_url('/order-confirmed')); exit; } elseif ($_GET['action'] === 'cancel_order' && wp_verify_nonce($_GET['_wpnonce'], 'cancel_order_nonce')) { $order->update_status('cancelled', '客户主动取消订单'); wp_redirect(home_url('/order-cancelled')); exit; } }
这种方式无需修改模板文件,通过钩子直接注入按钮,同时添加了nonce验证,安全性更高,实现更简洁。
内容的提问来源于stack exchange,提问作者Bogdan993
相关产品推荐
相关产品推荐

