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

WooCommerce Stripe Webhook Handler扩展问题:父类方法仍被调用求助

解决WooCommerce Stripe Webhook Handler子类方法不被调用的问题

问题背景

我尝试扩展WooCommerce Stripe网关的WC_Stripe_Webhook_Handler类,目的是查看Webhook的请求体。我重写了check_for_webhook方法,但不管怎么操作,始终是父类的方法被调用。试过移除父类的动作钩子、添加自定义动作等多种方案,更倾向于直接扩展类的方式,折腾了一天都没进展,最终在他人帮助下解决了问题,这里分享一下解决方案。

核心原因分析

父类WC_Stripe_Webhook_Handler的构造函数中,默认以优先级10添加了woocommerce_api_wc_stripe动作钩子,并且父类的check_for_webhook方法执行后会调用exit终止程序。如果子类的动作优先级比父类高(数字更大),父类方法会先执行并终止,子类方法根本没机会运行。所以必须让子类的方法先于父类执行。

最终可用解决方案

以下是经过验证的完整子类代码,关键在于给子类的动作钩子设置比父类更低的优先级数字(比如9):

if (!class_exists('BSD_WC_SCSP_Stripe_Webhook_Handler')) :
class BSD_WC_SCSP_Stripe_Webhook_Handler extends WC_Stripe_Webhook_Handler {
    public function __construct() {
        parent::__construct();
        // 设置优先级9,比父类默认的10更低,确保子类方法先执行
        add_action('woocommerce_api_wc_stripe', array($this, 'check_for_webhook'), 9);
    }

    public function check_for_webhook() {
        error_log('DEBUG WOO-HOO!!!! Entered child version.');
        if (('POST' !== $_SERVER['REQUEST_METHOD']) || !isset($_GET['wc-api']) || ('wc_stripe' !== $_GET['wc-api']) ) {
            return;
        }
        $request_body = file_get_contents('php://input');
        $request_headers = array_change_key_case($this->get_request_headers(), CASE_UPPER);

        // 验证请求合法性
        if ($this->is_valid_request($request_headers, $request_body)) {
            error_log('DEBUG: TO-DO Now examine the request_body');
            // 可以在这里对request_body进行自定义处理
            $this->process_webhook($request_body);
            status_header(200);
            exit;
        } else {
            WC_Stripe_Logger::log('Incoming webhook failed validation: ' . print_r($request_body, true));
            status_header(400);
            exit;
        }
    }
}
endif; // 避免类重复定义
new BSD_WC_SCSP_Stripe_Webhook_Handler();

关键注意点

  • 钩子优先级:WordPress的动作钩子优先级数字越小,执行顺序越靠前。父类默认用优先级10添加动作,子类设置为9就能确保自己的方法先被调用,并且在执行后通过exit终止,父类方法就不会再运行了。
  • 类实例化时机:确保子类在父类实例化之后加载(因为Stripe插件是在plugins_loaded动作中初始化的,子类代码可以放在自己的插件或主题functions.php中,保证在Stripe插件之后加载)。
  • 避免类重复定义:用class_exists检查包裹类定义,防止出现类重复加载的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:44:49