
本教程旨在详细指导如何在woocommerce的“感谢页”中安全有效地获取订单详情,并将其动态嵌入到javascript代码中,以便将数据发送至第三方营销或分析系统。文章将重点介绍使用wordpress动作钩子`wp_footer`的正确方法,并提供处理单个或多个订单商品的代码示例,确保数据准确无误地传递。
在现代电商运营中,将WooCommerce订单数据实时同步到第三方营销、联盟或分析平台是常见的需求。这通常需要在用户完成购买后的“感谢页”上执行一段JavaScript代码,并将订单ID、总金额、商品信息等动态数据传递给该脚本。然而,直接在页面内容中嵌入PHP代码或使用不当的钩子,可能导致数据无法正确获取或脚本无法执行。本文将提供一种稳健且专业的解决方案。
理解WooCommerce感谢页的数据流
当用户在WooCommerce完成订单后,系统会跳转到一个特殊的“感谢页”。这个页面的URL通常包含订单ID,例如 yourdomain.com/checkout/order-received/1234/?key=wc_order_xxxxxx。WooCommerce通过order-received这个查询变量来识别当前页面对应的订单。要正确获取订单数据,我们需要利用这个查询变量。
错误的常见方法及原因
许多开发者在尝试实现此功能时,可能会遇到以下问题:
- 使用isset($wp-youjiankuohaophpcnquery_vars['thankyou']): 尽管thankyou在某些旧版本或特定配置下可能存在,但WooCommerce官方推荐且更稳定的查询变量是order-received。
- 在Elementor或其他页面构建器中直接嵌入PHP: 页面构建器通常会将内容渲染为静态HTML,或者在PHP执行环境之外处理短代码,导致嵌入的PHP代码无法正确解析或获取WordPress/WooCommerce的全局变量和函数。
- 在不正确的WordPress钩子中执行代码: 将代码放置在不恰当的钩子中,可能导致在订单数据尚未完全加载时执行,或者脚本位置不符合要求。
正确的实现方法:使用WordPress动作钩子
最推荐且最稳健的方法是利用WordPress的动作钩子(Action Hooks),将PHP代码与JavaScript脚本结合,动态生成包含订单数据的脚本。wp_footer钩子是一个理想的选择,它会在页面</body>标签之前执行,确保所有HTML内容都已加载,并且不会阻塞页面渲染。
立即学习“Java免费学习笔记(深入)”;
步骤一:创建PHP函数来嵌入JavaScript
我们将创建一个PHP函数,该函数将负责:
- 检查当前页面是否为WooCommerce的“感谢页”。
- 获取当前订单的WC_Order对象。
- 提取所需的订单详情。
- 将这些详情动态地插入到JavaScript变量中。
- 将整个JavaScript脚本通过wp_footer钩子输出到页面底部。
以下是实现此功能的PHP代码:
<?php
/**
* 在WooCommerce感谢页嵌入营销追踪脚本并传递订单详情
*/
add_action( 'wp_footer', 'embed_marketing_script_with_order_details', 5 );
function embed_marketing_script_with_order_details() {
global $wp;
// 检查当前页面是否为WooCommerce的订单接收(感谢)页面
if ( isset( $wp->query_vars['order-received'] ) ) :
// 获取订单ID
$order_id = absint( $wp->query_vars['order-received'] );
// 获取WC_Order对象
$order = wc_get_order( $order_id );
// 确保订单对象有效
if ( ! $order ) {
return; // 如果订单无效,则停止执行
}
// 获取所有订单商品
$order_items = $order->get_items();
// 初始化用于存储商品ID和名称的数组
$product_ids = $product_names = array();
// 遍历订单商品,提取ID和名称
foreach ( $order_items as $order_item ) {
$product_ids[] = $order_item->get_product_id();
$product_names[] = $order_item->get_name();
}
// 将商品ID和名称数组转换为以 "|" 分隔的字符串
// 如果第三方系统需要不同的分隔符,请在此处修改
$product_ids_string = implode( '|', $product_ids );
$product_names_string = implode( '|', $product_names );
?>
<script id="wc-checkout-custom-tracking" type="text/javascript">
var oeyaPostParam = {
code : '', // 固定值或无需填充
cookie_name : '', // 固定值或无需填充
mcode : '', // 固定值或无需填充
oid : '<?php echo esc_js( $order->get_order_number() ); ?>', // 订单号
amount : '<?php echo esc_js( $order->get_total() ); ?>', // 订单总金额
bid : '', // 固定值或无需填充
gno : '<?php echo esc_js( $product_ids_string ); ?>', // 商品ID字符串 (多个商品用'|'分隔)
gname : '<?php echo esc_js( $product_names_string ); ?>', // 商品名称字符串 (多个商品用'|'分隔)
unit : ' ', // 固定值或无需填充
odate : '<?php echo esc_js( $order->get_date_created()->format('Y-m-d H:i:s') ); ?>', // 订单创建时间
};
(function() {
var oeyasc = document.createElement('script');
oeyasc.type = 'text/javascript';
oeyasc.async = true; // 异步加载脚本
oeyasc.src = 'https://www.conn.tw/track/oeya_jss2s_v1.0.js'; // 第三方追踪脚本URL
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(oeyasc, s);
})();
</script>
<?php
endif;
}代码解析:
- add_action( 'wp_footer', 'embed_marketing_script_with_order_details', 5 );: 这行代码将我们的自定义函数 embed_marketing_script_with_order_details 挂载到 wp_footer 钩子上。优先级 5 确保它在大多数其他脚本之前执行。
- global $wp;: 访问WordPress的全局$wp对象,其中包含查询变量信息。
- if ( isset( $wp->query_vars['order-received'] ) ) :: 这是关键的条件判断,确保代码只在WooCommerce的“感谢页”上执行。
- $order_id = absint( $wp->query_vars['order-received'] );: 安全地获取订单ID。absint函数确保值是正整数。
- $order = wc_get_order( $order_id );: 使用WooCommerce提供的函数获取订单对象,通过这个对象我们可以访问订单的所有属性。
- $order->get_order_number(), $order->get_total(), $order->get_date_created(): 这些是WC_Order对象提供的方法,用于获取订单号、总金额和创建日期。注意get_date_created()返回的是一个WC_DateTime对象,需要用format()方法格式化为字符串。
- $order_items = $order->get_items();: 获取订单中的所有商品项,返回一个WC_Order_Item_Product对象数组。
- 循环处理商品: foreach ( $order_items as $order_item ) 循环遍历每个商品,并通过$order_item->get_product_id()和$order_item->get_name()获取商品的ID和名称。
- implode('|', $product_ids) / implode('|', $product_names): 由于第三方系统可能需要将多个商品ID或名称作为单个字符串传递(例如,用特定分隔符连接),这里使用implode函数将数组转换为以|分隔的字符串。如果您的第三方系统有不同的要求,请调整分隔符。
- <?php echo esc_js( ... ); ?>: esc_js()是一个重要的安全函数,用于转义输出到JavaScript中的PHP变量,防止XSS攻击或JavaScript语法错误。
- JavaScript脚本嵌入: PHP代码块结束后,直接输出<script>标签,并在其中使用<?php echo ...; ?>将动态获取的PHP变量值填充到JavaScript的oeyaPostParam对象中。
- 第三方脚本加载: (function() { ... })(); 内部的JavaScript代码负责动态创建并插入第三方追踪脚本。
步骤二:将代码添加到WordPress
将上述PHP代码添加到您的WordPress网站有以下两种推荐方式:
-
使用Code Snippets插件(推荐):
- 安装并激活“Code Snippets”插件。
- 进入WordPress后台的“Snippets” -> “Add New”。
- 粘贴上述PHP代码到代码框中。
- 为Snippet命名,例如“WooCommerce感谢页追踪脚本”。
- 确保“Run Snippet everywhere”选项被选中。
- 保存并激活Snippet。
-
添加到主题的functions.php文件:
- 通过FTP或主机控制面板访问您的WordPress安装。
- 导航到 wp-content/themes/您的主题名/。
- 编辑 functions.php 文件。
- 将上述PHP代码粘贴到文件的末尾,在?>标签之前(如果存在的话)。
- 注意: 直接修改主题文件可能在主题更新时丢失更改。强烈建议使用子主题或Code Snippets插件。
注意事项
- 安全: 始终使用esc_js()等转义函数来处理输出到JavaScript中的数据。
- 第三方脚本URL: 确保oeyasc.src中的第三方脚本URL是正确的。
- 数据格式: 根据第三方系统的具体要求,调整gno和gname中商品ID和名称的连接方式(例如,使用逗号,或其他分隔符)。
- 错误处理: 在实际生产环境中,您可能需要添加更健壮的错误处理和日志记录机制,以应对订单获取失败或其他异常情况。
- 缓存: 如果您的网站使用了缓存插件,请在部署新代码后清除缓存,以确保更改立即生效。
- 测试: 在部署到生产环境之前,务必在开发或测试环境中进行充分测试,验证数据是否正确传递到第三方系统。
总结
通过利用WordPress的动作钩子wp_footer,结合WooCommerce的wc_get_order()函数,我们可以安全、高效地在感谢页中获取订单详情,并将其动态嵌入到JavaScript追踪脚本中。这种方法避免了直接在页面内容中混合PHP和HTML可能带来的问题,提供了更清晰、更易于维护的代码结构,是实现此类功能的最佳实践。










