WooCommerce结账重定向至自有收款站点的实现可行性问询
解决方案:跨WooCommerce站点跳转收款实现
完全可以实现!你的思路非常准确——这本质就是给原站点(无法收信用卡的那个)开发一个自定义支付网关,把能收信用卡的站点当作专属收款渠道来对接。下面是具体的实现方案:
核心逻辑拆解
- 原站点:用户结账时选择自定义支付方式,生成订单后跳转至收款站点,传递订单金额、回调地址等关键参数
- 收款站点:接收请求后生成对应金额的支付订单,引导用户完成信用卡支付
- 支付完成后:收款站点先异步通知原站点更新订单状态,再将用户跳转回原站点首页
第一步:原站点开发自定义支付网关
在原站点的主题functions.php或者自定义插件中添加以下代码,实现自定义支付网关:
// 注册自定义支付网关 add_filter('woocommerce_payment_gateways', 'register_custom_redirect_gateway'); function register_custom_redirect_gateway($gateways) { $gateways[] = 'WC_Redirect_To_Receipt_Site'; return $gateways; } class WC_Redirect_To_Receipt_Site extends WC_Payment_Gateway { public function __construct() { $this->id = 'redirect_receipt_site'; $this->method_title = '信用卡支付(跳转至收款站点)'; $this->method_description = '通过专用收款站点完成信用卡支付'; $this->has_fields = false; // 初始化设置项 $this->init_form_fields(); $this->init_settings(); // 读取设置值 $this->title = $this->get_option('title'); $this->receipt_site_pay_url = $this->get_option('receipt_site_pay_url'); $this->shared_secret = $this->get_option('shared_secret'); $this->success_redirect_url = home_url('/'); // 默认跳转回原站点首页 // 注册钩子 add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); add_action('woocommerce_api_receipt_site_callback', array($this, 'handle_payment_callback')); } // 后台设置表单 public function init_form_fields() { $this->form_fields = array( 'enabled' => array( 'title' => '启用此支付方式', 'type' => 'checkbox', 'label' => '开启跳转收款站支付', 'default' => 'yes' ), 'title' => array( 'title' => '支付方式名称', 'type' => 'text', 'default' => '信用卡支付' ), 'receipt_site_pay_url' => array( 'title' => '收款站点支付接收URL', 'type' => 'text', 'description' => '填写收款站点用于接收支付请求的页面URL(比如https://收款站域名/?external_pay=true)' ), 'shared_secret' => array( 'title' => '共享密钥', 'type' => 'password', 'description' => '两个站点必须使用相同的密钥,用于验证请求合法性,防止参数篡改' ) ); } // 处理支付跳转逻辑 public function process_payment($order_id) { $order = wc_get_order($order_id); // 生成签名,确保参数不被篡改 $signature = md5($order_id . $order->get_total() . $this->shared_secret); // 组装跳转参数 $redirect_args = array( 'source_order_id' => $order_id, 'amount' => $order->get_total(), 'currency' => $order->get_currency(), 'success_url' => $this->success_redirect_url, 'callback_url' => home_url('/wc-api/receipt_site_callback'), 'signature' => $signature ); // 标记订单为待支付状态 $order->update_status('pending', '用户已跳转至收款站点等待支付'); // 返回跳转指令给WooCommerce return array( 'result' => 'success', 'redirect' => add_query_arg($redirect_args, $this->receipt_site_pay_url) ); } // 处理收款站点的异步回调,更新订单状态 public function handle_payment_callback() { // 获取回调参数 $source_order_id = $_GET['source_order_id']; $amount = $_GET['amount']; $signature = $_GET['signature']; $order = wc_get_order($source_order_id); if (!$order) { wp_die('订单不存在'); } // 验证签名合法性 $valid_signature = md5($source_order_id . $amount . $this->shared_secret); if ($signature !== $valid_signature) { wp_die('签名验证失败,非法请求'); } // 验证金额匹配 if ($order->get_total() != $amount) { wp_die('金额不匹配'); } // 更新订单为已支付状态 $order->payment_complete(); $order->add_order_note('支付完成:通过收款站点信用卡支付'); wp_die('回调处理成功'); } }
第二步:收款站点处理支付请求与回调
在收款站点的主题functions.php或自定义插件中添加以下代码,用于接收原站点的跳转请求并处理支付:
// 处理来自原站点的支付请求 add_action('template_redirect', 'handle_external_payment_request'); function handle_external_payment_request() { // 仅处理标记为外部支付的请求 if (!isset($_GET['external_pay']) || $_GET['external_pay'] !== 'true') { return; } // 获取请求参数 $source_order_id = $_GET['source_order_id']; $amount = $_GET['amount']; $currency = $_GET['currency']; $success_url = $_GET['success_url']; $callback_url = $_GET['callback_url']; $signature = $_GET['signature']; // 验证签名(使用和原站点相同的共享密钥) $shared_secret = '这里填写和原站点一致的共享密钥'; $valid_signature = md5($source_order_id . $amount . $shared_secret); if ($signature !== $valid_signature) { wp_die('非法请求:签名验证失败'); } // 创建收款站点内部的虚拟订单(用于记录支付流水,可选但建议) $local_order = wc_create_order(); // 添加一个专门的虚拟商品(提前在收款站点创建好,ID替换为你的商品ID) $local_order->add_product(wc_get_product(99), 1, array('subtotal' => $amount)); $local_order->set_total($amount, 'total'); $local_order->set_currency($currency); $local_order->update_status('pending', '来自外部站点的支付请求,等待用户完成信用卡支付'); // 绑定支付完成后的回调逻辑 add_action('woocommerce_order_status_completed', function($local_order_id) use ($source_order_id, $amount, $shared_secret, $callback_url, $success_url) { $completed_order = wc_get_order($local_order_id); // 验证本地订单金额和请求金额一致 if ($completed_order->get_total() != $amount) { return; } // 生成回调签名,通知原站点支付完成 $callback_signature = md5($source_order_id . $amount . $shared_secret); $callback_args = array( 'source_order_id' => $source_order_id, 'amount' => $amount, 'signature' => $callback_signature ); // 异步发送回调请求(避免阻塞用户跳转) wp_remote_get(add_query_arg($callback_args, $callback_url), array('blocking' => false)); // 跳转回原站点首页 wp_redirect($success_url); exit; }); // 跳转到本地订单的支付页面,引导用户用信用卡支付 wp_redirect($local_order->get_checkout_payment_url()); exit; }
关键注意事项
- 安全优先:一定要使用共享密钥做签名验证,防止恶意篡改金额或伪造回调请求;两个站点都要启用HTTPS,确保数据传输加密
- 订单同步:异步回调是关键,避免用户支付后直接关闭页面导致原站点订单状态未更新
- 错误处理:建议添加支付失败后的跳转逻辑,比如用户在收款站点支付失败后,引导回原站点重新发起支付
- 合规性:确保支付流程符合当地支付监管要求,比如不存储用户信用卡信息(由收款站点的支付网关处理)
内容的提问来源于stack exchange,提问作者Albert
相关产品推荐
相关产品推荐

