WooCommerce集成WorldPay API求助:自定义插件无法跳转支付
WooCommerce 集成 WorldPay API 跳转问题修复
现有代码核心问题
process_payment方法错误返回WooCommerce订单完成URL,未指向WorldPay支付页面- 错误使用
woocommerce_checkout_process钩子执行API调用和页面输出,该钩子仅用于校验checkout数据 authorize_payment参数传递逻辑混乱,且直接在函数中输出内容破坏checkout流程- 未处理WorldPay API返回的支付跳转地址
修正后的完整插件代码
<?php /* Plugin Name: Worldpay Integration Description: Custom integration with Worldpay API. Version: 1.1 Author: */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义Worldpay支付网关类 class WC_Gateway_Worldpay extends WC_Payment_Gateway { public function __construct() { $this->id = 'worldpay'; $this->title = 'Worldpay'; $this->method_title = 'Worldpay API 集成'; $this->method_description = '通过Worldpay API处理支付'; $this->has_fields = false; // 不需要在checkout显示额外字段时设为false // 加载设置 $this->init_form_fields(); $this->init_settings(); // 保存设置钩子 add_action('woocommerce_update_options_payment_gateways_' . $this->id, array($this, 'process_admin_options')); // 读取管理员设置 $this->enabled = $this->get_option('enabled'); $this->api_username = $this->get_option('api_username'); $this->api_password = $this->get_option('api_password'); $this->api_url = $this->get_option('api_url') ?: 'https://try.access.worldpay.com/payments/authorize'; } // 初始化管理员设置字段 public function init_form_fields() { $this->form_fields = array( 'enabled' => array( 'title' => '启用/禁用', 'label' => '启用Worldpay支付', 'type' => 'checkbox', 'description' => '', 'default' => 'no' ), 'api_username' => array( 'title' => 'API用户名', 'type' => 'text', 'description' => 'Worldpay API用户名', 'default' => '' ), 'api_password' => array( 'title' => 'API密码', 'type' => 'password', 'description' => 'Worldpay API密码', 'default' => '' ), 'api_url' => array( 'title' => 'API地址', 'type' => 'text', 'description' => '测试环境用https://try.access.worldpay.com/payments/authorize,生产环境用正式地址', 'default' => 'https://try.access.worldpay.com/payments/authorize' ) ); } // 处理支付核心方法 public function process_payment($order_id) { $order = wc_get_order($order_id); // 构造Worldpay API请求数据 $request_data = array( 'amount' => (int)($order->get_total() * 100), // 转换为最小货币单位(分) 'currencyCode' => $order->get_currency(), 'orderDescription' => '订单 #' . $order->get_order_number(), 'merchant' => array( 'entity' => 'YOUR_MERCHANT_ENTITY' // 替换为你的Worldpay商户实体ID ), 'shopper' => array( 'emailAddress' => $order->get_billing_email(), 'billingAddress' => array( 'address1' => $order->get_billing_address_1(), 'city' => $order->get_billing_city(), 'postalCode' => $order->get_billing_postcode(), 'countryCode' => $order->get_billing_country() ) ), 'orderCode' => $order->get_order_number(), 'returnUrl' => $this->get_return_url($order), // 支付完成后跳转回WooCommerce的地址 'cancelUrl' => wc_get_checkout_url() // 取消支付后返回checkout页面 ); // 调用Worldpay授权API $response = $this->authorize_payment($request_data); if ($response && isset($response['_links']['paymentAuthorize']['href'])) { // 标记订单为待支付 $order->update_status('pending', '等待Worldpay支付确认'); $order->save(); // 返回Worldpay支付页面跳转地址 return array( 'result' => 'success', 'redirect' => $response['_links']['paymentAuthorize']['href'] ); } else { // API调用失败,添加错误信息到checkout wc_add_notice('支付请求失败,请稍后重试或联系客服。', 'error'); return array( 'result' => 'failure' ); } } // 调用Worldpay授权API private function authorize_payment($data) { $credentials = base64_encode($this->api_username . ':' . $this->api_password); $ch = curl_init($this->api_url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Authorization: Basic ' . $credentials, 'Content-Type: application/vnd.worldpay.payments-v6+json', 'Accept: application/vnd.worldpay.payments-v6.hal+json', )); // 生产环境建议启用SSL验证 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); $response = curl_exec($ch); $error = curl_error($ch); curl_close($ch); if ($error) { error_log('Worldpay API请求错误: ' . $error); return false; } $result = json_decode($response, true); if (isset($result['error'])) { error_log('Worldpay API返回错误: ' . print_r($result, true)); return false; } return $result; } } // 添加Worldpay到支付网关列表 add_filter('woocommerce_payment_gateways', 'add_worldpay_gateway'); function add_worldpay_gateway($gateways) { $gateways[] = 'WC_Gateway_Worldpay'; return $gateways; }
关键修复说明
- 移除错误钩子:删除了
custom_worldpay_checkout_process钩子及其实现,避免在checkout校验阶段执行API调用和输出内容 - 修正支付跳转逻辑:
process_payment方法不再返回WooCommerce默认地址,而是返回Worldpay API返回的支付授权页面URL - 规范API调用:
- 将API凭证移至管理员设置页面,避免硬编码
- 完善请求数据结构,包含订单、购物者、返回地址等必填字段
- 添加错误日志记录,便于排查问题
- 订单状态管理:调用API成功后将订单标记为「待支付」,等待Worldpay回调确认支付结果
后续注意事项
- 替换代码中的
YOUR_MERCHANT_ENTITY为你的Worldpay商户实体ID - 测试环境使用
try.access.worldpay.com,生产环境切换为正式API地址 - 需要配置Worldpay的Webhook来接收支付结果通知,更新订单状态(可添加额外的Webhook处理逻辑)
- 确保服务器支持cURL且启用SSL验证
内容的提问来源于stack exchange,提问作者Matthew Connell
相关产品推荐
相关产品推荐

