Automattic / woocommerce-subscriptions-core

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

Add filter to `WCS_Cart_Initial_Payment::maybe_setup_cart()` to allow plugins to prevent cart regeneration. #591

Closed peterwilsoncc closed 2 months ago

peterwilsoncc commented 2 months ago

Description

WCS_Cart_Initial_Payment::maybe_setup_cart() hijacks the pay for order page and recreates a cart containing the products in the original order. This was introduced as part of woocommerce-subscriptions#329 to account for payment issues leaving the order in a pending state across a renewal period.

For pre-orders with cash on delivery payments, this is causing issues when the pre-order is completed prior to the scheduled maturity date. As the cart is recreated, the original pre-order status is restored (setting it to either new or active).

The effect is that pre-orders completed prior to the maturity date can not be paid for.

To allow extensions to resolve this, I propose adding a filter to the WCS_Cart_Initial_Payment::maybe_setup_cart() method.

/**
 * Filter whether to recreate the initial payment order.
 *
 * Allows developers to prevent the initial payment order from being recreated and
 * manage the pending to processing/completed workflow without duplicating the order.
 *
 * @param bool $recreate_order Whether to recreate the initial payment order. Default true.
 * @param WC_Order $order The order object.
 * @param string $order_key The order key.
 * @param int $order_id The order ID.
 */
$recreate_order = apply_filters( 'wcs_recreate_initial_payment_order', $recreate_order, $order, $order_key, $order_id );

Testing instructions

I'm unsure how to test this without using the pre-orders subs compatibility branch to demonstrate the issue.

  1. Checkout woocommerce-pre-orders#497
  2. Activate WooPayments as a payment method
  3. Activate Subs
  4. Create a Far Future pre-order:
    • Type: Simple Subscription (other details as you wish)
    • Pre-orders: enabled
    • Pre-order matures a month or more from now
    • Pre-order paid upon release
  5. Open a private/incognito browser window and purchase the product.
    • Ensure you use a real email address or mail capture tool such as mailhog
    • During checkout you will be presented with the "pay later" gateway
    • WooPayments will not be available
  6. Back in the admin, go to: WooCommerce > Pre-orders > Actions (tab) > Complete (section)
  7. From the dropdown, select your demo product
  8. Fill out the message field
  9. Submit the form
  10. Check the email of the test user
  11. Click the email ending "your pre-order from Date is now available"
  12. Click the link to pay for the pre-order
  13. The payment page will be hijacked by Subs and the order recreated
  14. Rather than being able to pay for the order, the only gateway available will be pay later

Product impact

Dev notes

Additional context

This comes out of the project for introducing subscriptions compatibility to the Pre-orders extension.

Issue: woocommerce-pre-orders#393 PR: woocommerce-pre-orders#497