You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress插件短码触发wp_redirect页面加载自动跳转问题求助

问题:WordPress短码触发wp_redirect过早执行,需仅在弹窗打开时跳转

我在WordPress中开发了一款生成支付URL并跳转的插件,对应短码放在按钮触发的弹窗里。当短码仅返回'Hello World'时,弹窗能正常调用短码;但现在代码里的wp_redirect会在页面加载时就自动执行跳转,而不是打开弹窗时才触发,调试一天没解决。

原插件代码

<?php
/*
Plugin Name: Keystone AR Payments
Description: Allows customers to make online payments
Version: 1.0
Author: Jeff Margel
*/
function keystone_ar_payments(){
    global $wpdb;
    $table = 'tblAR';
    $current_user = wp_get_current_user(); 
    $user_id      = $current_user->user_login;

$db = new mysqli('localhost', 'wp_user', 'wp_password', 'wp_database');

// Check for connection errors
if ($db->connect_error) {
    die('Connection failed: ' . $db->connect_error);
}

// Query the tblAR table for invoice numbers and amount


$sql = "SELECT * FROM $table WHERE customer_number = '$user_id' AND select_invoice = 'YES'";
$result = $db->query($sql);

// Check for query errors
if (!$result) {
    die('Query failed: ' . $db->error);
}

    $invoices = '';
    $amount_total = 0;
    $cus_name = '';
    $cus_address = '';
    $cus_city = '';
    $cus_state = '';
    $cus_zip = '';


        while ($row = $result->fetch_assoc()) {
             $invoices .= $row['invoice_number'] . ',';
             $amount_total += $row['amount'];
             $cus_name = $row['cus_name'];
             $cus_address = $row['cus_address'];
             $cus_city = $row['cus_city'];
             $cus_state = $row['cus_state'];
             $cus_zip = $row['cus_zip'];
        }
        $cus_name = trim($cus_name);
        $cus_address = trim($cus_address);
        $cus_city = trim($cus_city);
        $cus_state = trim($cus_state);
        $cus_zip = trim($cus_zip);
        
        $invoices = rtrim($invoices, ',');
        
        $url = 'https://cphppdemo.securepayments.cardpointe.com/?cf_CustomField0=' . urlencode($invoices) . '&total=' . urlencode($amount_total) . '&customerId=' . urlencode($user_id) . '&billCompany=' . urlencode($cus_name) . '&billAddress1=' . urlencode($cus_address) . '&billCity=' . urlencode($cus_city) . '&billState=' . urlencode($cus_state) . '&billZip=' . urlencode($cus_zip);

wp_redirect( $url );
exit;
}
add_shortcode('keystone_ar_payments', 'keystone_ar_payments');
?>

解决方案

核心问题是WordPress短码会在页面渲染阶段就执行,直接在短码函数里写wp_redirect必然会在页面加载时触发跳转。要实现弹窗打开时才跳转,需要采用「前端触发+后端AJAX接口」的方式:

1. 修改插件主文件代码

<?php
/*
Plugin Name: Keystone AR Payments
Description: Allows customers to make online payments
Version: 1.0
Author: Jeff Margel
*/

// 短码函数:仅返回触发跳转的按钮
function keystone_ar_payments_shortcode() {
    if (!is_user_logged_in()) {
        return '<p>请登录后进行支付操作</p>';
    }
    // 按钮放在弹窗内,点击时触发AJAX请求
    return '<button id="keystone-pay-btn" class="button">跳转至支付页面</button>';
}
add_shortcode('keystone_ar_payments', 'keystone_ar_payments_shortcode');

// AJAX接口:处理数据库查询并返回跳转URL
add_action('wp_ajax_keystone_get_payment_url', 'keystone_get_payment_url');
// 若允许未登录用户使用,保留下面一行;否则删除
add_action('wp_ajax_nopriv_keystone_get_payment_url', 'keystone_get_payment_url');

function keystone_get_payment_url() {
    if (!is_user_logged_in()) {
        wp_send_json_error('请先登录');
        wp_die();
    }

    global $wpdb;
    $table = 'tblAR';
    $current_user = wp_get_current_user(); 
    $user_id      = $current_user->user_login;

    // 使用WordPress自带wpdb,避免直接mysqli,同时防止SQL注入
    $sql = $wpdb->prepare("SELECT * FROM $table WHERE customer_number = %s AND select_invoice = 'YES'", $user_id);
    $result = $wpdb->get_results($sql, ARRAY_A);

    if (!$result) {
        wp_send_json_error('未找到可支付的账单');
        wp_die();
    }

    $invoices = '';
    $amount_total = 0;
    $cus_name = '';
    $cus_address = '';
    $cus_city = '';
    $cus_state = '';
    $cus_zip = '';

    foreach ($result as $row) {
         $invoices .= $row['invoice_number'] . ',';
         $amount_total += $row['amount'];
         $cus_name = $row['cus_name'];
         $cus_address = $row['cus_address'];
         $cus_city = $row['cus_city'];
         $cus_state = $row['cus_state'];
         $cus_zip = $row['cus_zip'];
    }
    $cus_name = trim($cus_name);
    $cus_address = trim($cus_address);
    $cus_city = trim($cus_city);
    $cus_state = trim($cus_state);
    $cus_zip = trim($cus_zip);
    
    $invoices = rtrim($invoices, ',');
    
    $url = 'https://cphppdemo.securepayments.cardpointe.com/?cf_CustomField0=' . urlencode($invoices) . '&total=' . urlencode($amount_total) . '&customerId=' . urlencode($user_id) . '&billCompany=' . urlencode($cus_name) . '&billAddress1=' . urlencode($cus_address) . '&billCity=' . urlencode($cus_city) . '&billState=' . urlencode($cus_state) . '&billZip=' . urlencode($cus_zip);

    wp_send_json_success(['url' => $url]);
    wp_die();
}

// 注册前端JS脚本
function keystone_enqueue_payment_script() {
    wp_enqueue_script('keystone-payment-script', plugin_dir_url(__FILE__) . 'keystone-payment.js', ['jquery'], '1.0', true);
    // 传递AJAX地址和验证密钥到前端
    wp_localize_script('keystone-payment-script', 'keystone_ajax', [
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('keystone_payment_nonce')
    ]);
}
add_action('wp_enqueue_scripts', 'keystone_enqueue_payment_script');
?>

2. 创建前端JS文件(keystone-payment.js,与插件主文件同目录)

jQuery(document).ready(function($) {
    // 监听支付按钮点击事件
    $('#keystone-pay-btn').on('click', function() {
        $.ajax({
            url: keystone_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'keystone_get_payment_url',
                nonce: keystone_ajax.nonce // 验证请求合法性
            },
            success: function(response) {
                if (response.success) {
                    // 获取到支付URL后执行跳转
                    window.location.href = response.data.url;
                } else {
                    alert(response.data);
                }
            },
            error: function() {
                alert('获取支付链接失败,请稍后重试');
            }
        });
    });
});

关键说明

  • 短码逻辑拆分:短码不再执行业务逻辑,仅输出触发按钮,避免页面加载时触发跳转
  • AJAX处理核心逻辑:数据库查询和URL生成移到AJAX接口,只有用户点击按钮时才会调用
  • 安全加固:使用wpdb->prepare防止SQL注入,添加nonce验证AJAX请求合法性,校验用户登录状态
  • 前端触发跳转:通过JS拿到接口返回的URL后,用window.location.href实现跳转,完全由用户操作触发

内容的提问来源于stack exchange,提问作者Jeff Margel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:00:43