account = $account; $this->gateway = $gateway; $this->woopay_utilities = $woopay_utilities; $this->express_checkout_helper = $express_checkout_helper; } /** * Indicates eligibility for WooPay via feature flag. * * @var bool */ private $is_woopay_eligible; /** * Indicates whether WooPay is enabled. * * @var bool */ private $is_woopay_enabled; /** * Indicates whether WooPay express checkout is enabled. * * @var bool */ private $is_woopay_express_button_enabled; /** * Indicates whether WooPay and WooPay express checkout are enabled. * * @return bool */ public function is_woopay_enabled() { /** * Allows 3PD to programmatically show/hide the WooPay button. * * @since 9.5.0 */ return apply_filters( 'wcpay_woopay_enabled', $this->is_woopay_eligible && $this->is_woopay_enabled && $this->is_woopay_express_button_enabled ); } /** * Initialize hooks. * * @return void */ public function init() { // Checks if WCPay is enabled. if ( ! $this->gateway->is_enabled() ) { return; } // Checks if WooPay is enabled. $this->is_woopay_eligible = WC_Payments_Features::is_woopay_eligible(); // Feature flag. $this->is_woopay_enabled = 'yes' === $this->gateway->get_option( 'platform_checkout', 'no' ); $this->is_woopay_express_button_enabled = WC_Payments_Features::is_woopay_express_checkout_enabled(); if ( ! $this->is_woopay_enabled() ) { return; } // Don't load for change payment method page. if ( isset( $_GET['change_payment_method'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification return; } add_action( 'wp_enqueue_scripts', [ $this, 'scripts' ] ); add_filter( 'wcpay_payment_fields_js_config', [ $this, 'add_woopay_config' ] ); add_action( 'wp_ajax_woopay_express_checkout_button_show_error_notice', [ $this, 'show_error_notice' ] ); add_action( 'wp_ajax_nopriv_woopay_express_checkout_button_show_error_notice', [ $this, 'show_error_notice' ] ); } /** * Add the woopay button config to wcpay_config. * * @param array $config The existing config array. * * @return array The modified config array. */ public function add_woopay_config( $config ) { $user = wp_get_current_user(); $config['woopayButton'] = $this->get_button_settings(); $config['woopayButtonNonce'] = wp_create_nonce( 'woopay_button_nonce' ); $config['addToCartNonce'] = wp_create_nonce( 'wcpay-add-to-cart' ); $config['shouldShowWooPayButton'] = $this->should_show_woopay_button(); $config['woopaySessionEmail'] = WooPay_Session::get_user_email( $user ); $config['woopayIsCountryAvailable'] = $this->woopay_utilities->is_country_available( $this->gateway ); $config['woopayAppearance'] = $this->gateway->is_woopay_global_theme_support_enabled() ? WC_Payments_Styles_Cache::get_woopay_appearance() : null; $config['woopayFontRules'] = $this->gateway->is_woopay_global_theme_support_enabled() ? WC_Payments_Styles_Cache::get_woopay_font_rules() : []; return $config; } /** * Load public scripts and styles. */ public function scripts() { // Don't load scripts if we should not show the button. if ( ! $this->should_show_woopay_button() ) { return; } WC_Payments::register_script_with_dependencies( 'WCPAY_WOOPAY_EXPRESS_BUTTON', 'dist/woopay-express-button' ); $wcpay_config = rawurlencode( wp_json_encode( WC_Payments::get_wc_payments_checkout()->get_payment_fields_js_config() ) ); wp_add_inline_script( 'WCPAY_WOOPAY_EXPRESS_BUTTON', " var wcpayConfig = wcpayConfig || JSON.parse( decodeURIComponent( '" . esc_js( $wcpay_config ) . "' ) ); ", 'before' ); wp_set_script_translations( 'WCPAY_WOOPAY_EXPRESS_BUTTON', 'woocommerce-payments' ); wp_enqueue_script( 'WCPAY_WOOPAY_EXPRESS_BUTTON' ); WC_Payments_Utils::enqueue_style( 'WCPAY_WOOPAY', plugins_url( 'dist/woopay.css', WCPAY_PLUGIN_FILE ), [], WCPAY_VERSION_NUMBER, 'all' ); } /** * Returns the error notice HTML. */ public function show_error_notice() { $is_nonce_valid = check_ajax_referer( 'woopay_button_nonce', false, false ); if ( ! $is_nonce_valid ) { wp_send_json_error( __( 'You aren’t authorized to do that.', 'woocommerce-payments' ), 403 ); } $message = isset( $_POST['message'] ) ? sanitize_text_field( wp_unslash( $_POST['message'] ) ) : ''; // $message has already been translated. wc_add_notice( $message, 'error' ); $notice = wc_print_notices( true ); wp_send_json_success( [ 'notice' => $notice, ] ); wp_die(); } /** * The settings for the `button` attribute - they depend on the "grouped settings" flag value. * * @return array */ public function get_button_settings() { $common_settings = $this->express_checkout_helper->get_common_button_settings(); $woopay_button_settings = [ 'size' => $this->gateway->get_option( 'payment_request_button_size' ), 'context' => $this->express_checkout_helper->get_button_context(), ]; return array_merge( $common_settings, $woopay_button_settings ); } /** * Checks whether Payment Request Button should be available on this page. * * @return bool */ public function should_show_woopay_button() { // WCPay is not available. $gateways = WC()->payment_gateways->get_available_payment_gateways(); if ( ! isset( $gateways['woocommerce_payments'] ) ) { return false; } // WooPay is not enabled. if ( ! $this->is_woopay_enabled() ) { return false; } // Page not supported. if ( ! $this->express_checkout_helper->is_product() && ! $this->express_checkout_helper->is_cart() && ! $this->express_checkout_helper->is_checkout() ) { return false; } // Check if WooPay is available in the user country. if ( ! $this->woopay_utilities->is_country_available( $this->gateway ) ) { return false; } // Product page, but not available in settings. if ( $this->express_checkout_helper->is_product() && ! $this->express_checkout_helper->is_express_checkout_method_enabled_at( 'product', 'woopay' ) ) { return false; } // Checkout page, but not available in settings. if ( $this->express_checkout_helper->is_checkout() && ! $this->express_checkout_helper->is_express_checkout_method_enabled_at( 'checkout', 'woopay' ) ) { return false; } // Cart page, but not available in settings. if ( $this->express_checkout_helper->is_cart() && ! $this->express_checkout_helper->is_express_checkout_method_enabled_at( 'cart', 'woopay' ) ) { return false; } // Product page, but has unsupported product type. if ( $this->express_checkout_helper->is_product() && ! $this->is_product_supported() ) { Logger::log( 'Product page has unsupported product type ( WooPay Express button disabled )' ); return false; } // Cart has unsupported product type. if ( ( $this->express_checkout_helper->is_checkout() || $this->express_checkout_helper->is_cart() ) && ! $this->has_allowed_items_in_cart() ) { Logger::log( 'Items in the cart have unsupported product type ( WooPay Express button disabled )' ); return false; } if ( ! is_user_logged_in() ) { // On product page for a subscription product, but not logged in, making WooPay unavailable. if ( $this->express_checkout_helper->is_product() ) { $current_product = wc_get_product(); if ( $current_product && $this->express_checkout_helper->is_product_subscription( $current_product ) ) { return false; } } // On cart or checkout page with a subscription product in cart, but not logged in, making WooPay unavailable. if ( ( $this->express_checkout_helper->is_checkout() || $this->express_checkout_helper->is_cart() ) && class_exists( 'WC_Subscriptions_Cart' ) && WC_Subscriptions_Cart::cart_contains_subscription() ) { // Check cart for subscription products. return false; } // If guest checkout is not allowed, and customer is not logged in, disable the WooPay button. if ( ! $this->woopay_utilities->is_guest_checkout_enabled() ) { return false; } } /** * TODO: We need to do some research here and see if there are any product types that we * absolutely cannot support with WooPay at this time. There are some examples in the * `WC_Payments_Payment_Request_Button_Handler->is_product_supported()` method. */ return true; } /** * Display the payment request button. */ public function display_woopay_button_html() { if ( ! $this->should_show_woopay_button() ) { return; } $settings = $this->get_button_settings(); // Use a