Automattic / woocommerce-subscriptions-core

Subscriptions core package for WooCommerce
Other
82 stars 29 forks source link

Fix "Invalid recurring shipping method" errors on checkout when a min required free shipping option is chosen #411

Closed james-allan closed 1 year ago

james-allan commented 1 year ago

Fixes #409

Description

The free shipping method has an option to limit it's availability to carts that exceed a required amount (eg free shipping is available to all orders over $100). The way this limitation interacts with subscriptions isn't immediately apparent but it does make sense and honor the limitation.

When you consider mixed cart (simple and subscriptions products purchased at once), free trials and sign up fees, you can get into a mix of free shipping availability across the initial and recurring carts.

For example:

Free trial (A) Sign up fee (B) Mixed checkout (C) ❗
Screenshot 2023-02-21 at 4 41 47 pm Screenshot 2023-02-21 at 4 47 46 pm Screenshot 2023-02-21 at 4 38 18 pm
Free initial cart with no shipping, but recurring cart is eligible. $20/year with a $100 sign up fee. Free shipping available to initial cart, but not the recurring cart. Free shipping available to $100 recurring cart, but not $12 initial cart.

The issue this PR fixes occurs when you have free shipping available to the recurring cart but not to the initial cart - scenario C above. In this scenario, when we go to validate the shipping method on checkout submission, we incorrectly determine that the recurring cart isn't eligible for free shipping because we missed setting a flag that enables the maybe_recalculate_shipping_method_availability() function to calculate method availability for recurring carts. Essentially, because free shipping isn't available to the initial cart, the validation fails for the eligible recurring cart. This eventually leads to this error message on checkout:

Screenshot 2023-02-21 at 4 52 40 pm

This PR fixes that by making sure we set the self::$cached_recurring_cart before validating recurring shipping methods.

How to test this PR

  1. Add a free shipping option that is limited to carts that exceed $100 (screenshot)
  2. Add a flat rate option (screenshot)
  3. Add products to the cart to end up with an initial payment less than $100 and at least 1 recurring cart with a total greater than $100. Options include:
    • Add enough free trial subscription products to exceed the $100 requirement and at least 1 other product with an initial cost (subscription or standard product).
    • Add a sign up fee & free trial product to the cart where the sign up fee is less than $100, but the recurring price exceeds it. Eg a $20 sign up fee with a free trial + $100 recurring price.
  4. Now visit the checkout. You should have standard shipping available to the initial cart, and free shipping available to the recurring cart that exceeds $100. (see screenshot example under (C) above).
  5. Choose free shipping in the recurring cart section.
  6. Attempt to checkout.
    • On trunk you should get the error message "Invalid recurring shipping method." and be blocked from checking out.
    • On this branch there shouldn't be any error message, checkout should be successful and the subscription set up with free shipping.

Product impact

james-allan commented 1 year ago

I missed this one from last month. Merging now so it can make it into todays release.