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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 01:54:53