Skip to content

Comments

Adaptive pricing support check for products in the cart#5017

Open
Mayisha wants to merge 22 commits intodevelopfrom
task/adaptive-pricing-support-check
Open

Adaptive pricing support check for products in the cart#5017
Mayisha wants to merge 22 commits intodevelopfrom
task/adaptive-pricing-support-check

Conversation

@Mayisha
Copy link
Contributor

@Mayisha Mayisha commented Feb 13, 2026

Changes proposed in this Pull Request:

Added 'is_adaptive_pricing_supported' method to check if adaptive pricing is supported for the store setting and the products in the cart.

Note:
Updated some ECE test files irrelevant to the changes of this PR to ensure test cleanups, so that test setups do not conflict with the tests added for this PR.

Testing instructions

  • Add the following filter to allow adaptive pricing and checkout sessions in your store-
    add_filter('wc_stripe_is_checkout_sessions_available', '__return_true');
  • As an admin, enable optimized checkout and adaptive pricing in the settings.
  • As a shopper, add a simple product to your cart and go to the checkout page.
  • In the developer console check the value of wc_stripe_upe_params.isAdaptivePricingSupported. The value should be 1.
  • Add a variable product to your cart. The value of wc_stripe_upe_params.isAdaptivePricingSupported. The value should be 1.
  • Add a subscription product to your cart. The value of wc_stripe_upe_params.isAdaptivePricingSupported. The value should be empty.
  • Add a pre-order charged upon release product to your cart. The value of wc_stripe_upe_params.isAdaptivePricingSupported. The value should be empty.

  • Covered with tests (or have a good reason not to test in description ☝️)
  • Tested on mobile (or does not apply)

Changelog entry

  • This Pull Request does not require a changelog entry. (Comment required below)
Changelog Entry Comment

Comment

Post merge

@Mayisha Mayisha added this to the 10.5.0 milestone Feb 13, 2026
@Mayisha Mayisha requested review from a team, daledupreez and wjrosa and removed request for a team February 13, 2026 10:47
Copy link
Contributor

@wjrosa wjrosa left a comment

Choose a reason for hiding this comment

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

Looks good to me 👍 . Highlighted an alternative way to check for the cart contents (but the current version works fine).

Also, tests needs to be fixed before merging

@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds WC_Stripe_Helper::is_adaptive_pricing_supported(), exposes its result to the UPE gateway JS, and expands unit-test helpers (pre-orders, deposits, subscriptions), updates tests/bootstrap to load helpers, and adjusts checkout-context test filters; duplicate test blocks were introduced in one test file.

Changes

Cohort / File(s) Summary
Core Adaptive Pricing Detection
includes/class-wc-stripe-helper.php
New public static function is_adaptive_pricing_supported(): bool — checks feature flag, adaptive_pricing setting, checkout context, empty cart, and per-item exclusions (subscriptions, pre-orders charged upon release, deposits when enabled).
Gateway JS config
includes/payment-methods/class-wc-stripe-upe-payment-gateway.php
Added isAdaptivePricingSupported flag to javascript_params, sourced from WC_Stripe_Helper::is_adaptive_pricing_supported().
Tests — Pre-orders helper
tests/phpunit/Helpers/WC_Pre_Orders_Product.php
Added helper with mockable product_is_charged_upon_release and setter to simulate pre-order charged-upon-release behavior.
Tests — Deposits helper
tests/phpunit/Helpers/WC_Deposits_Product_Manager.php
Added helper with mockable deposits_enabled and setter to simulate deposits being enabled.
Tests — Subscriptions helper
tests/phpunit/Helpers/WC_Subscriptions_Product.php
Added public static array $subscription_product_ids and setter; updated get_trial_length($product = null) and is_subscription($product = null) signatures and short-circuit logic when product IDs configured.
Tests — Helper unit tests
tests/phpunit/WC_Stripe_Helper_Test.php
Added data-driven test_is_adaptive_pricing_supported() and provide_is_adaptive_pricing_supported() covering combinations of feature flag, checkout context, block state, adaptive_pricing setting, and cart product types. Note: test/provider blocks appear duplicated in the file. Also adjusted test_build_line_items expectations for shipping.
Tests — Bootstrap
tests/phpunit/bootstrap.php
Now requires new helpers: Helpers/WC_Pre_Orders_Product.php and Helpers/WC_Deposits_Product_Manager.php during test bootstrap.
Tests — Checkout context handling
tests/phpunit/PaymentMethods/.../WC_Stripe_Express_Checkout_Element_Test.php, tests/phpunit/PaymentMethods/.../WC_Stripe_Express_Checkout_Helper_Test.php
Replaced constant-based checkout checks with closure-based add_filter('woocommerce_is_checkout', ...) assigned to $is_checkout_filter and removed via remove_filter() to ensure deterministic setup/teardown.
Other test adjustments
tests/phpunit/...
Minor formatting and flow changes across tests; some duplicated or reflowed blocks that should be reviewed/cleaned.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Gateway as UPE_Gateway
    participant Helper as WC_Stripe_Helper
    participant Cart
    participant Subs as WC_Subscriptions_Product
    participant PreOrders as WC_Pre_Orders_Product
    participant Deposits as WC_Deposits_Product_Manager

    Client->>Gateway: request javascript params
    Gateway->>Helper: is_adaptive_pricing_supported()
    Helper->>Helper: check feature flag & adaptive_pricing setting
    Helper->>Gateway: check woocommerce_is_checkout filter
    Helper->>Cart: inspect cart contents
    alt cart empty
        Helper-->>Gateway: return true
    else cart has items
        Cart->>Subs: is_subscription(item)?
        Cart->>PreOrders: product_is_charged_upon_release(item)?
        Cart->>Deposits: deposits_enabled(item)?
        alt any subscription / pre-order charged on release / deposit enabled
            Helper-->>Gateway: return false
        else
            Helper-->>Gateway: return true
        end
    end
    Gateway-->>Client: include isAdaptivePricingSupported in JS params
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding a method to check adaptive pricing support based on store settings and cart products.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The PR description clearly explains the addition of is_adaptive_pricing_supported method and includes detailed testing instructions covering multiple cart scenarios.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch task/adaptive-pricing-support-check

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@includes/class-wc-stripe-helper.php`:
- Around line 1108-1157: The test helper class WC_Subscriptions_Product defines
is_subscription() and get_trial_length() without parameters but production code
calls WC_Subscriptions_Product::is_subscription($product) and
::get_trial_length($product); update the test helper method signatures to accept
a $product parameter (e.g., function is_subscription( $product ) and function
get_trial_length( $product )) and forward or ignore the parameter in their
implementations so PHPUnit on PHP 8+ won’t raise ArgumentCountError; keep
behavior unchanged and update any docblocks/tests that reference the old
signatures.

In `@includes/payment-methods/class-wc-stripe-upe-payment-gateway.php`:
- Around line 532-534: The new stripe_params['isAdaptivePricingSupported'] flag
(set via WC_Stripe_Helper::is_adaptive_pricing_supported() in
class-wc-stripe-upe-payment-gateway.php) affects frontend gating and must be
validated across all checkout flows: classic checkout, Blocks checkout,
optimized checkout, and express checkout (including carts containing
subscriptions and pre-orders). Manually verify in each flow that payment method
availability and rendering match expected behavior when the flag is true/false;
if any mismatch is found, adjust
WC_Stripe_Helper::is_adaptive_pricing_supported() logic or the consumer code
that reads stripe_params['isAdaptivePricingSupported'] so availability/rendering
rules are consistent, add automated integration tests covering each checkout
variant + subscription/pre-order scenarios, and document test results and any
code changes.

In `@tests/phpunit/WC_Stripe_Helper_Test.php`:
- Around line 1145-1153: Test cleanup is restoring the already-modified
$stripe_settings instead of the original settings and is not resetting product
mock states; before the test mutates settings store the original settings (e.g.
$original_stripe_settings) and at the end call
WC_Stripe_Helper::update_main_stripe_settings($original_stripe_settings) to
restore them, also reset the feature flag via
update_option(\WC_Stripe_Feature_Flags::CHECKOUT_SESSIONS_FEATURE_FLAG_NAME,
'no') (or restore its original value if you saved it), and explicitly clear
mocks by setting WC_Subscriptions_Product::is_subscription(…) and
WC_Pre_Orders_Product::is_pre_order(…) back to false (or call their provided
reset methods) in the cleanup block alongside WC()->cart->empty_cart() and
remove_filter('woocommerce_is_checkout', $is_checkout_filter).
- Around line 1163-1215: Update the data provider
provide_is_adaptive_pricing_supported to add cases covering the Blocks checkout
path (is_checkout = false but has_block('woocommerce/checkout') = true) and
mixed-cart scenarios (e.g., cart_product_types like ['simple','subscription']
and ['simple','pre-order']) so the loop that rejects subscriptions/pre-orders is
exercised; adjust the test setup to allow per-product subscription/pre-order
mocking instead of the global WC_Subscriptions_Product::set_is_subscription
(e.g., mock product instances or stub WC_Subscriptions_Product::is_subscription
to check product IDs) and ensure the test toggles
has_block('woocommerce/checkout') when needed to validate both checkout paths.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/phpunit/WC_Stripe_Helper_Test.php`:
- Around line 1125-1135: The global static mocks used here cause all products to
be treated uniformly based on cart_product_type, so add a concise inline comment
above the WC_Subscriptions_Product::set_is_subscription and
WC_Pre_Orders_Product::set_is_pre_order calls noting that the mock applies
globally (e.g., "// Note: mock applies globally to all products — mixed cart
types not supported by this mock"), reference cart_product_type to explain why
tests set a single type, and keep the comment near those lines so future
maintainers understand the limitation.

---

Duplicate comments:
In `@tests/phpunit/Helpers/WC_Subscriptions_Product.php`:
- Around line 32-34: The mock get_trial_length currently ignores the $product
parameter and always returns the global self::$get_trial_length_result,
preventing per-product behavior; change get_trial_length (and the similar mocks
like is_subscription) to accept/interpret self::$get_trial_length_result as
either a scalar fallback or an associative array/list keyed by product ID (or
SKU) and, when $product is provided, look up the product's id (e.g.,
$product->get_id()) and return the matching value (or a default when not
listed); also preserve backward compatibility by returning the scalar fallback
when the static is not an array and handle null $product by returning the
fallback.

In `@tests/phpunit/WC_Stripe_Helper_Test.php`:
- Around line 1166-1218: The data provider lacks cases for the Blocks checkout
branch and mixed-cart contents; add test rows exercising
is_adaptive_pricing_supported when is_checkout() is false but
has_block('woocommerce/checkout') is true, and add mixed-cart scenarios where
cart_product_type represents multiple item types (e.g.,
['simple','subscription'] and ['simple','pre-order']) to ensure the method
short-circuits and returns false for carts containing disallowed types; update
WC_Stripe_Helper_Test::provide_is_adaptive_pricing_supported to include these
entries and ensure the test harness/mocks emulate
has_block('woocommerce/checkout') so the has_block branch in
is_adaptive_pricing_supported is executed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/phpunit/WC_Stripe_Helper_Test.php`:
- Around line 1098-1174: The test test_is_adaptive_pricing_supported uses
$saved_post only inside the second if ($has_block) restore block but assigns it
inside the first if ($has_block), which is fragile; initialize $saved_post =
null before the first if or move the restore into a guaranteed cleanup path
(e.g., a finally-style pattern) so
WC_Stripe_Helper_Test::test_is_adaptive_pricing_supported always has $saved_post
defined when restoring the global $post.

---

Duplicate comments:
In `@tests/phpunit/WC_Stripe_Helper_Test.php`:
- Around line 1181-1248: The data provider provide_is_adaptive_pricing_supported
is missing two edge cases; add an entry where both is_checkout=true and
has_block=true (mixed checkout context) with adaptive_pricing='yes' and
expected=true to ensure no double-evaluation, and add an entry where
adaptive_pricing is an unexpected value (e.g., adaptive_pricing='' with
feature_flag=true and is_checkout=true or has_block=false) with expected=false
to assert the 'yes' strict check rejects non-'yes' values; update the array in
provide_is_adaptive_pricing_supported to include these two cases.

Copy link
Contributor

@daledupreez daledupreez left a comment

Choose a reason for hiding this comment

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

This tests as described, but I do have some feedback and suggestions that may be worth incorporating. My biggest concern is around support for Deposits -- I think we should not support deposits, TBH, even if that's mostly a requirements concern.

Comment on lines 1111 to 1112
* When on the checkout page, adaptive pricing is not supported if the cart contains
* any of: subscription products or pre-order (charge upon release) products.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I think it would help if the specific items were listed on their own lines.

Suggested change
* When on the checkout page, adaptive pricing is not supported if the cart contains
* any of: subscription products or pre-order (charge upon release) products.
* When on the checkout page, adaptive pricing is not supported if the cart contains
* any of the following:
* - A subscription product.
* - A pre-order product that will be charged upon release.

Also, is it OK to handle products using a deposit? I don't think we save the payment method in that case, but I worry that Deposits sets the expectation that it is $X today and $Y later, when the actual amounts in local currency may not be $Y on any given future date.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. I have added deposits in the unsupported list in my latest commits.

Copy link
Contributor

Choose a reason for hiding this comment

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

It would also be good to make sure that decision/exclusion is pushed up to the requirements discussion/doc as well.

WC()->cart->add_to_cart( $product->get_id(), 1 );
}

$actual = WC_Stripe_Helper::is_adaptive_pricing_supported();
Copy link
Contributor

Choose a reason for hiding this comment

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

As a thought, it may be worth adding tests that check for additional cases that would exercise more logic, including the following:

  • multiple standard products in the cart
  • multiple standard products plus one subscription in the cart

TIL that pre-orders can't be in a cart with other products.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

Comment on lines 1146 to 1151
if ( class_exists( 'WC_Subscriptions_Product' ) && WC_Subscriptions_Product::is_subscription( $product ) ) {
return false;
}

// Pre-order (charge upon release) is not supported with adaptive pricing.
if ( class_exists( 'WC_Pre_Orders_Product' ) && WC_Pre_Orders_Product::product_is_charged_upon_release( $product ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Two non-blocking thoughts on this front:

  • Might it be worth adding some defensive checks to ensure the methods exist?
  • Might it be worth running the existence checks outside the loop so they only get run once? This is something of a micro-optimization, as class lookups should be quick, but it was something that struck me as unnecessary work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Might it be worth adding some defensive checks to ensure the methods exist?

Skipping this as we are checking for class exist which should be sufficient here.

Might it be worth running the existence checks outside the loop so they only get run once?

Sounds good to me. Addressed this feedback.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@includes/class-wc-stripe-helper.php`:
- Around line 1108-1118: The docblock for the method
is_adaptive_pricing_supported (the method that checks subscriptions, pre-orders,
and deposits) is missing mention of products with deposits enabled; update the
method's docblock summary and description to explicitly state that adaptive
pricing is also not supported when the cart contains products with deposits
enabled (the same condition handled in the method where deposits are checked),
so the docblock accurately reflects subscriptions, pre-orders charged on
release, and deposits as reasons adaptive pricing is disabled.
- Line 1127: Replace the external static call WC_Stripe_Helper::get_settings
with an internal static call using self::get_settings to maintain consistency
with other internal calls in the class (e.g., self::get_stripe_settings) —
update the conditional that checks 'adaptive_pricing' to call self::get_settings
instead of WC_Stripe_Helper::get_settings.

In `@tests/phpunit/Helpers/WC_Subscriptions_Product.php`:
- Around line 67-72: The is_subscription() mock currently falls back to
self::$is_subscription_result whenever $product is not a WC_Product even if
self::$subscription_product_ids is populated; update is_subscription() to accept
int|WC_Product|null like the real implementation: if $product is an integer (or
a WC_Product, use $product->get_id()) and self::$subscription_product_ids is
non-empty, return in_array(the resolved product ID,
self::$subscription_product_ids, true); only when $product is null and no
per-product ids apply should it return self::$is_subscription_result. Reference
the function is_subscription and the static properties
self::$subscription_product_ids and self::$is_subscription_result when making
the change.
- Around line 31-41: Add a centralized static reset method to
WC_Subscriptions_Product that clears all static helper state (at minimum reset
self::$subscription_product_ids and any other static flags used by
set_is_subscription() and set_trial_length()) so tests cannot leak state across
iterations; implement a public static function reset(): void that reinitializes
those static properties to their defaults and update tests
(WC_Stripe_Express_Checkout_Helper_Test and WC_Stripe_Helper_Test) to call
WC_Subscriptions_Product::reset() in their tearDown() methods to ensure per-test
cleanup.

In `@tests/phpunit/WC_Stripe_Helper_Test.php`:
- Around line 1157-1248: Add two mixed-cart scenarios to the
provide_is_adaptive_pricing_supported data provider: one with
'cart_product_types' => [ 'simple', 'pre-order' ] and one with
'cart_product_types' => [ 'simple', 'deposits' ]; both should mirror the
behavior of the pure pre-order and deposits cases (set 'feature_flag' => true,
'is_checkout' => true, 'has_block' => false, 'adaptive_pricing' => 'yes', and
'expected' => false). Update the provide_is_adaptive_pricing_supported function
in WC_Stripe_Helper_Test to include these entries so mixed simple+pre-order and
simple+deposits scenarios are explicitly covered.

@Mayisha Mayisha requested a review from daledupreez February 20, 2026 05:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants