Scope reCAPTCHA assets and markup to active PayPal payment locations (6703) - #4548
Conversation
…page's smart button location enqueue_scripts() only checked the WordPress page type (is_checkout/is_cart/is_product), so reCAPTCHA assets loaded on any product/cart/checkout page regardless of whether the merchant actually enabled PayPal there. Inject SettingsStatus and gate on the same per-location "Enable payment methods" setting SmartButton already uses, exposed behind a new woocommerce_paypal_payments_recaptcha_should_enqueue filter.
…ocation gate render_v2_container() rendered the v2 badge container on every checkout/pay-order/cart/ product hook it's attached to, with no location check at all. Apply the same should_enqueue_for_current_location() gate used for script enqueueing, so the markup (and the console/JS handler tied to it) is withheld on pages where PayPal isn't enabled.
Adds the first test coverage for Recaptcha: asserts enqueue_scripts()/render_v2_container() are skipped when the smart button location is disabled or unsupported, run when enabled, correctly distinguish classic vs. block/express checkout, and respect the new woocommerce_paypal_payments_recaptcha_should_enqueue filter override.
Test using WordPress PlaygroundThe changes in this pull request can be previewed and tested using a WordPress Playground instance. 🔗 Test this pull request with WordPress Playground What's included:
Login credentials:
Plugin Details:
🤖 Auto-generated for commit 9be4d86 • Last updated: 2026-07-22T08:34:37.060Z |
Dinamiko
left a comment
There was a problem hiding this comment.
@Narek13 it seems that if the smart-button location that applies there is disabled, checkout for classic checkout, checkout-block-express for block checkout then should_enqueue_for_current_location() returns false, enqueue_scripts() bails out, and reCAPTCHA is not loaded for ACDC.
reCAPTCHA should load wherever any of its protected payment methods can actually be initiated, not only where the smart button is enabled.
Recaptcha already holds $this->payment_methods, the exact set it protects (PayPalGateway, CreditCardGateway, CardButtonGateway, AxoGateway). Reuse that against WooCommerce's own availability, which is the same source of truth the validation hooks rely on:
private function should_enqueue_for_current_location(): bool {
$location = $this->current_smart_button_location();
$enabled_for_location = null !== $location
&& $this->settings_status->is_smart_button_enabled_for_location( $location );
$should_enqueue = $enabled_for_location
|| $this->has_protected_gateway_on_current_page();
/** ... existing woocommerce_paypal_payments_recaptcha_should_enqueue filter ... */
}
/**
* True when a reCAPTCHA-protected gateway (ACDC card fields, AXO, card button,
* standard PayPal) is available on a checkout / order-pay / add-payment-method
* page — surfaces whose availability is independent of the smart-button location.
*/
private function has_protected_gateway_on_current_page(): bool {
if ( ! is_checkout() && ! is_add_payment_method_page() ) {
return false;
}
$available = WC()->payment_gateways->get_available_payment_gateways();
foreach ( $this->payment_methods as $id ) {
if ( isset( $available[ $id ] ) ) {
return true;
}
}
return false;
} is_checkout() already covers the order-pay page (is_checkout_pay_page()), and is_add_payment_method_page() covers the add-payment-method surface where can_render_dcc() also renders.
…y is available regardless of smart-button location should_enqueue_for_current_location() only checked the merchant's Smart Button Location setting, but that setting solely controls the wallet button. ACDC, AXO, and the card button gateway are independent WC_Payment_Gateway entries that can be selectable at checkout (or the My Account "Add payment method" page) even when the wallet button is disabled for that location — and reCAPTCHA protects exactly those gateways via $payment_methods. Add has_protected_gateway_on_current_page(), checking WC's own available-gateways list against the protected set, and OR it into the enqueue decision so reCAPTCHA isn't skipped while ACDC/AXO/card-button remain reachable.
…nqueue cases Adds regression coverage for the previous commit: reCAPTCHA still enqueues when a protected gateway (ACDC) is available at checkout despite the smart-button location being disabled, still skips when no protected gateway is available either, and still enqueues on the My Account "Add payment method" page when one is available there.
…and-markup-to-active-pay-pal-payment-locations
Description
When reCAPTCHA protection is enabled, its scripts, configuration, badge, and v2 container currently load on checkout, cart, and single product pages regardless of whether PayPal payments are actually enabled at those locations. For example, with only Classic Checkout enabled, reCAPTCHA still loads on cart and product pages where no PayPal button/gateway can be initiated — causing unnecessary asset loading, an unexpected reCAPTCHA badge, and unnecessary processing of visitor data on unrelated pages.
Root cause:
Recaptcha::enqueue_scripts()and thewoocommerce_single_product_summaryhook rendering the v2 container only checked the WordPress page type (is_checkout()/is_cart()/is_product()), never the merchant's configured Smart Button Locations — unlikeSmartButton, which already gates its own rendering onSettingsStatus::is_smart_button_enabled_for_location().PR Changes
SettingsStatusintoRecaptchaand added a sharedshould_enqueue_for_current_location()check (mirroringSmartButton's existing gating pattern), which detects the current page's location —product,cart,checkout, orcheckout-block-express(classic vs. block/express checkout are distinguished, since a merchant may enable PayPal for one but not the other) — and confirms it's enabled before allowing reCAPTCHA to load.enqueue_scripts()(scripts, config, badge) andrender_v2_container()(the v2 container markup), so all reCAPTCHA output is consistently scoped.woocommerce_paypal_payments_recaptcha_should_enqueuefilter around the final decision, giving developers a supported way to override it.Recaptcha(none existed before), covering: skipping on unsupported/disabled locations, running on enabled locations, the classic vs. block checkout distinction, and the new filter.Steps to Test
Expected: no
ppcp-recaptcha/ppcp-recaptcha-handlerscripts, no reCAPTCHA badge, noppcpRecaptchaSettings, and no#ppcp-recaptcha-v2-containeron product/cart pages. Visiting Classic Checkout should still load reCAPTCHA normally.