用于检查和禁止在 WooCommerce 中下订单的操作挂钩

Action hook to check and disallow placing an order in WooCommerce

我正在为 WooCommerce 编写一个扩展,允许我在客户下订单之前验证客户的年龄。通过向外部 API 发送特定请求来验证年龄,并根据 API 的结果是否成功,订单应该是成功还是失败。

<?php
/**
 * LicenseScanner Integration
 *
 * Enables LicenseScanner integration.
 *
 * @class       WC_LicenseScanner
 * @extends     WC_Integration
 */
class WC_LicenseScanner extends WC_Integration {
    /**
     * Init and hook in the integration.
     *
     * @access public
     * @return void
     */
    public function __construct() {
        $this->id                   = 'licensescanner';
        $this->method_title         = __( 'LicenseScanner', 'woocommerce' );
        $this->method_description   = __( 'LicenseScanner enables you to verify the age of the customer.', 'woocommerce' );
        // Load the settings.
        $this->init_form_fields();
        $this->init_settings();
        // Actions
        add_action( 'woocommerce_update_options_integration_licensescanner', array( $this, 'process_admin_options' ) );
        // Require phone number during the check-out
        add_filter( 'woocommerce_billing_fields', array($this, 'wc_mandatory_filter_phone'), 10, 1 );
        // Send age verification upon order
        add_action( 'woocommerce_pay_order_before_submit', array($this, 'request_age_verification'));
    }
    /**
     * Initialise Settings Form Fields
     *
     * @access public
     * @return void
     */
    function init_form_fields() {
        $this->form_fields = array(
            'enabled' => array(
                'title'             => __( 'License Bar Code Scanner URL:', 'woocommerce' ),
                'type'              => 'text',
                'description'       => __( 'Enter the License Bar Code Scanner URL that the notification should be sent to once the user attempts to check out', 'woocommerce' ),
                'desc_tip'          => true,
                'default'           => get_option('woocommerce_licensescanner') ? get_option('woocommerce_licensescanner') : ''
            )
        );
    }

    function wc_mandatory_filter_phone( $address_fields ) {
        $address_fields['billing_phone']['required'] = true;
        return $address_fields;
    }

    function request_age_verification() {
        throw new Exception('The age verification failed');
    }
}

所以显然抛出异常不足以使订单失败...或者我可能迷上了错误的操作? 我可以以某种方式尝试使用 JS 禁用订单按钮,但如果潜在的攻击者只是在他的浏览器中启用它或伪造对后端的请求,那还不够好

而不是使用 woocommerce_pay_order_before_submit,您应该尝试挂钩专用的 woocommerce_checkout_process 操作挂钩,因此在您的代码中:

// Send age verification upon order
add_action( 'woocommerce_checkout_process', array( $this, 'request_age_verification' ) );

它应该可以使用……

这个胡克位于WC_Checkout process_checkout() method