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
相关产品推荐
相关产品推荐

