Skip to content

Scope reCAPTCHA assets and markup to active PayPal payment locations (6703) - #4548

Merged
Dinamiko merged 6 commits into
dev/developfrom
dev/PCP-6703-scope-re-captcha-assets-and-markup-to-active-pay-pal-payment-locations
Jul 22, 2026
Merged

Scope reCAPTCHA assets and markup to active PayPal payment locations (6703)#4548
Dinamiko merged 6 commits into
dev/developfrom
dev/PCP-6703-scope-re-captcha-assets-and-markup-to-active-pay-pal-payment-locations

Conversation

@Narek13

@Narek13 Narek13 commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

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 the woocommerce_single_product_summary hook rendering the v2 container only checked the WordPress page type (is_checkout()/is_cart()/is_product()), never the merchant's configured Smart Button Locations — unlike SmartButton, which already gates its own rendering on SettingsStatus::is_smart_button_enabled_for_location().

PR Changes

  • Injected SettingsStatus into Recaptcha and added a shared should_enqueue_for_current_location() check (mirroring SmartButton's existing gating pattern), which detects the current page's location — product, cart, checkout, or checkout-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.
  • Applied this same gate to both enqueue_scripts() (scripts, config, badge) and render_v2_container() (the v2 container markup), so all reCAPTCHA output is consistently scoped.
  • Added a new woocommerce_paypal_payments_recaptcha_should_enqueue filter around the final decision, giving developers a supported way to override it.
  • Added the first PHPUnit test coverage for 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

  1. Connect PayPal and configure valid reCAPTCHA v3 and v2 keys.
  2. Go to WooCommerce → Settings → Payments → PayPal → Styling.
  3. Enable only Classic Checkout; disable Cart, Express Checkout, Mini Cart, and Single Product locations.
  4. Visit a single product page as a logged-out visitor, then visit the cart page.
  5. Inspect the page source and browser console.

Expected: no ppcp-recaptcha/ppcp-recaptcha-handler scripts, no reCAPTCHA badge, no ppcpRecaptchaSettings, and no #ppcp-recaptcha-v2-container on product/cart pages. Visiting Classic Checkout should still load reCAPTCHA normally.

Narek13 added 3 commits July 21, 2026 17:23
…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.
@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can be previewed and tested using a WordPress Playground instance.
WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

🔗 Test this pull request with WordPress Playground

What's included:

  • ✅ WordPress (latest)
  • ✅ WooCommerce (latest)
  • ✅ PayPal Payments plugin v4.1.1-pr4548-29904311080-g4362438 (built from this PR)

Login credentials:

  • Username: admin
  • Password: password

Plugin Details:

  • Version: 4.1.1-pr4548-29904311080-g4362438
  • Commit: 9be4d86
  • Artifact: woocommerce-paypal-payments-4.1.1-pr4548-29904311080-g4362438

💡 The demo environment resets each time you refresh. Perfect for testing!

🔄 This link updates automatically with each new commit to the PR.

⚠️ This URL is valid for 30 days from when this comment was last updated.


🤖 Auto-generated for commit 9be4d86 • Last updated: 2026-07-22T08:34:37.060Z

@Narek13 Narek13 added bug Something isn't working improvement labels Jul 21, 2026

@Dinamiko Dinamiko left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Narek13 added 3 commits July 22, 2026 12:24
…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
@Narek13
Narek13 requested a review from Dinamiko July 22, 2026 08:58
@Dinamiko
Dinamiko merged commit a6081df into dev/develop Jul 22, 2026
12 checks passed
@Dinamiko
Dinamiko deleted the dev/PCP-6703-scope-re-captcha-assets-and-markup-to-active-pay-pal-payment-locations branch July 22, 2026 09:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants