Woocommerce自定义支付网关如何在process_payment函数中跳转页面并传参
WooCommerce 自定义支付网关跳转自定义支付页的规范实现方案
你当前直接跳转插件目录下redirect_page.php的写法存在两个明显问题:
- 直接访问独立PHP文件默认不会加载WordPress/WooCommerce核心环境,无法调用WC相关函数处理订单逻辑
- 无权限校验逻辑,外部可随意访问该文件,存在安全风险
步骤1:改造process_payment方法的跳转逻辑
不要直接传敏感数据到URL,敏感数据存入订单元数据,URL仅带用于校验的非敏感参数:
public function process_payment($order_id) { // 推荐用wc_get_order获取订单实例,兼容性更好 $order = wc_get_order($order_id); // 你的业务逻辑处理... // 将需要传递的自定义数据存入订单元数据(下划线开头表示内部字段,不会在前台展示) $order->update_meta_data('_my_payment_custom_data', 你需要传递的业务数据); $order->save(); // 用add_query_arg拼接合法的跳转URL,仅带校验参数 $redirect_url = add_query_arg([ 'order_id' => $order_id, 'order_key' => $order->get_order_key(), // WC原生订单密钥,用于后续合法性校验 'custom_action' => 'my_payment_show_pay_page' ], home_url('/')); return [ 'result' => 'success', 'redirect' => $redirect_url ]; }
步骤2:钩子拦截请求,渲染自定义支付页
不要直接暴露redirect_page.php给外部访问,用WP钩子拦截请求,校验通过后加载支付页内容,这段逻辑直接写在wc_my_gateway.php中即可:
add_action('template_redirect', 'my_payment_render_pay_page'); function my_payment_render_pay_page() { // 非当前支付跳转请求直接跳过 if ( empty($_GET['custom_action']) || $_GET['custom_action'] !== 'my_payment_show_pay_page' || empty($_GET['order_id']) || empty($_GET['order_key']) ) { return; } $order_id = absint($_GET['order_id']); $order = wc_get_order($order_id); // 校验订单合法性,防止恶意请求 if (!$order || $order->get_order_key() !== sanitize_text_field($_GET['order_key'])) { wp_safe_redirect(wc_get_cart_url()); exit; } // 取出之前存储的自定义业务数据 $custom_data = $order->get_meta('_my_payment_custom_data', true); // 引入你写好的支付页模板,此时页面已加载WP/WC全部核心能力,可直接调用相关函数 include plugin_dir_path(__FILE__) . 'redirect_page.php'; exit; }
其他注意事项
- 所有从URL获取的参数都要做类型转换和 sanitize 处理,禁止直接使用未校验的用户输入
- 如果是跳转到第三方支付网关的场景,无需做中间页,直接将第三方支付链接赋值给redirect字段即可
- 若一定要直接访问
redirect_page.php,需在文件顶部引入WP核心,但该方式兼容性差,不推荐:
// redirect_page.php 顶部添加,需根据站点实际路径调整 require_once dirname(__FILE__, 4) . '/wp-load.php'; // 后续逻辑仍需添加订单合法性校验
内容的提问来源于stack exchange,提问作者steve lee
相关产品推荐
相关产品推荐

