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

自定义WooCommerce支付网关对接:订单提交拦截位置与实现方式

在WooCommerce中拦截订单提交并对接自定义支付网关与CRM的方案

嘿,这个需求我之前帮不少独立开发者和电商团队处理过,刚好可以给你捋清楚具体怎么做——核心是选对WooCommerce的钩子,再把你的API交互逻辑嵌进去。

一、选对拦截订单的核心钩子

WooCommerce提供了几个关键钩子,最适合你的场景的是:

  • woocommerce_checkout_process:这个钩子是用户点击「下单」按钮后,WooCommerce准备创建订单之前触发的。在这里做验证逻辑刚好,一旦验证不通过,能直接终止订单创建,还给用户友好提示。
  • 如果你需要提前修改订单数据再做验证,可以搭配woocommerce_before_checkout_create_order,但核心的支付/CRM验证还是推荐用前者。

二、具体实现步骤(代码示例)

下面是完整的可参考代码,你可以根据自己的API文档调整参数:

// 注册结账流程拦截钩子
add_action('woocommerce_checkout_process', 'custom_order_interception_with_crm_payment');

function custom_order_interception_with_crm_payment() {
    // 1. 提取结账页面的核心数据
    $checkout_data = WC()->checkout->get_posted_data();
    $cart_total = WC()->cart->total;
    $customer_email = WC()->customer->get_billing_email();
    $customer_phone = WC()->customer->get_billing_phone();
    
    // 提取购物车商品明细(按需调整字段)
    $cart_items = array_map(function($item) {
        return [
            'product_id' => $item->get_product_id(),
            'product_name' => $item->get_name(),
            'quantity' => $item->get_quantity()
        ];
    }, WC()->cart->get_cart());

    // 2. 向CRM发送客户/订单预提交数据
    $crm_api_url = 'https://你的CRM接口地址';
    $crm_payload = json_encode([
        'email' => $customer_email,
        'phone' => $customer_phone,
        'expected_total' => $cart_total,
        'products' => $cart_items
    ]);

    $crm_response = wp_remote_post($crm_api_url, [
        'headers' => ['Content-Type' => 'application/json'],
        'body' => $crm_payload,
        'timeout' => 15 // 设置超时,避免页面卡死
    ]);

    // 检查CRM请求是否成功
    if (is_wp_error($crm_response)) {
        wc_add_notice(__('抱歉,暂时无法连接客户管理系统,请稍后重试。', 'woocommerce'), 'error');
        return; // 终止流程
    }

    // 3. 调用支付网关API做支付可行性验证
    $payment_api_url = 'https://你的支付网关验证接口';
    $payment_payload = json_encode([
        'amount' => $cart_total,
        'currency' => get_woocommerce_currency(),
        'customer_email' => $customer_email,
        'unique_order_ref' => uniqid('wc_') // 生成唯一订单标识
    ]);

    $payment_response = wp_remote_post($payment_api_url, [
        'headers' => [
            'Content-Type' => 'application/json',
            'Authorization' => 'Bearer 你的支付网关API密钥' // 按需添加鉴权
        ],
        'body' => $payment_payload,
        'timeout' => 15
    ]);

    // 处理支付网关响应
    if (is_wp_error($payment_response)) {
        wc_add_notice(__('支付服务暂时不可用,请稍后重试。', 'woocommerce'), 'error');
        return;
    }

    $payment_result = json_decode(wp_remote_retrieve_body($payment_response), true);
    if (!$payment_result['success']) {
        // 支付网关拒绝,终止订单创建并提示用户
        wc_add_notice(__('支付验证失败:' . $payment_result['message'], 'woocommerce'), 'error');
    }

    // 所有验证通过,WooCommerce会自动继续创建订单流程
}

三、进阶方案:自定义支付网关类

如果你的需求更复杂(比如需要跳转到第三方支付页面、处理回调),更规范的做法是扩展WooCommerce的WC_Payment_Gateway类,注册成独立的支付方式:

class Custom_CRM_Payment_Gateway extends WC_Payment_Gateway {
    public function __construct() {
        $this->id = 'custom_crm_payment';
        $this->method_title = '自定义CRM支付';
        $this->method_description = '对接自有CRM与支付网关的支付方式';
        $this->has_fields = false;

        // 初始化设置选项
        $this->init_form_fields();
        $this->init_settings();

        $this->title = $this->get_option('title');
        $this->api_key = $this->get_option('api_key');

        // 注册后台设置保存钩子
        add_action('woocommerce_update_options_payment_gateways_' . $this->id, [$this, 'process_admin_options']);
        // 注册支付回调处理钩子
        add_action('woocommerce_api_custom_crm_payment', [$this, 'handle_payment_callback']);
    }

    // 后台设置表单
    public function init_form_fields() {
        $this->form_fields = [
            'enabled' => [
                'title' => '启用/禁用',
                'type' => 'checkbox',
                'label' => '启用该支付方式',
                'default' => 'yes'
            ],
            'title' => [
                'title' => '支付方式名称',
                'type' => 'text',
                'default' => '自定义支付'
            ],
            'api_key' => [
                'title' => '支付网关API密钥',
                'type' => 'password',
                'default' => ''
            ]
        ];
    }

    // 处理支付请求
    public function process_payment($order_id) {
        $order = wc_get_order($order_id);

        // 1. 同步订单数据到CRM
        $crm_payload = json_encode([
            'order_id' => $order_id,
            'customer_email' => $order->get_billing_email(),
            'total' => $order->get_total(),
            'status' => 'pending'
        ]);
        wp_remote_post('https://你的CRM订单接口', [
            'headers' => ['Content-Type' => 'application/json'],
            'body' => $crm_payload
        ]);

        // 2. 发起支付请求到网关
        $payment_payload = json_encode([
            'order_id' => $order_id,
            'amount' => $order->get_total(),
            'return_url' => $this->get_return_url($order),
            'cancel_url' => wc_get_checkout_url()
        ]);

        $payment_response = wp_remote_post('https://你的支付网关发起接口', [
            'headers' => [
                'Content-Type' => 'application/json',
                'Authorization' => 'Bearer ' . $this->api_key
            ],
            'body' => $payment_payload
        ]);

        $payment_data = json_decode(wp_remote_retrieve_body($payment_response), true);
        if ($payment_data['success']) {
            // 跳转到支付网关页面
            return [
                'result' => 'success',
                'redirect' => $payment_data['payment_url']
            ];
        } else {
            wc_add_notice('支付发起失败:' . $payment_data['message'], 'error');
            return ['result' => 'fail'];
        }
    }

    // 处理支付网关回调
    public function handle_payment_callback() {
        $order_id = isset($_GET['order_id']) ? sanitize_text_field($_GET['order_id']) : '';
        $payment_status = isset($_GET['status']) ? sanitize_text_field($_GET['status']) : '';
        
        if (!$order_id) exit;
        $order = wc_get_order($order_id);

        if ($payment_status === 'success') {
            $order->payment_complete();
            $order->add_order_note('支付成功,已同步到CRM');
            // 可选:再次同步订单状态到CRM
            wp_remote_post('https://你的CRM状态更新接口', [
                'body' => json_encode(['order_id' => $order_id, 'status' => 'completed'])
            ]);
            wp_redirect($this->get_return_url($order));
        } else {
            $order->update_status('failed', '支付失败');
            wp_redirect(wc_get_checkout_url());
        }
        exit;
    }
}

// 注册自定义支付网关
add_filter('woocommerce_payment_gateways', 'register_custom_crm_payment_gateway');
function register_custom_crm_payment_gateway($gateways) {
    $gateways[] = 'Custom_CRM_Payment_Gateway';
    return $gateways;
}

四、关键注意事项

  • 一定要用WordPress原生的wp_remote_post发送API请求,不要用原生CURL,它会自动适配服务器环境的SSL、代理等配置。
  • 给API请求设置合理的timeout(比如10-15秒),避免第三方服务响应慢导致结账页面长时间无响应。
  • 错误提示要清晰友好,让用户知道具体问题,而不是模糊的“操作失败”。
  • 如果需要在订单创建完成后做后续同步(比如更新CRM订单状态),可以用woocommerce_new_order或者woocommerce_order_status_changed钩子。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:54:24