Automattic / woocommerce-subscriptions-core

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

Ensure the woocommerce_subscriptions_paid_for_failed_renewal_order hook is fired when paying for failed renewal orders via the block checkout #589

Closed james-allan closed 3 months ago

james-allan commented 3 months ago

Fixes https://github.com/woocommerce/woocommerce-subscriptions/issues/4638

Description

When you successfully pay for a failed renewal order, we trigger the woocommerce_subscriptions_paid_for_failed_renewal_order hook. This is used by gateways to update the token on the subscription, to use the new token.

However, when you pay for an order via the block checkout, WooCommerce Core updates the status to pending (code ref). This brakes our logic which expects the status transition to be failed → processing/completed.

This PR attempts to fix this by making sure we flag when a failed renewal order is paid via block checkout and is updated to pending. Then when the order status transition is pending → processing/completed we can confirm that as scenario where the customer has paid for a failed renewal order.

How to test this PR

  1. Purchase a subscription using Stripe.
  2. Update the subscription's payment method to 4000000000000341
  3. Process a renewal. It should fail.
  4. Pay for the failed renewal order via the Block checkout.
    • On trunk Note that the woocommerce_subscriptions_paid_for_failed_renewal_order hook isn't fired because the order is pending, not failed.
    • On this branch that hook is fired because of the additional meta flag.

Product impact

james-allan commented 3 months ago

Another option would be to handle this in $subscription->payment_failed() and use the last_order to add the meta.

Oh right. That's an interesting idea. So set the meta when the subscription originally failed, not when it goes to pending. 🤔 That makes more sense to set that meta then and makes clean up a lot cleaner too.

james-allan commented 3 months ago

@mattallan I've changed this PR to now use the approach you recommended of using $subscription->payment_failed() and $subscription->payment_complete_for_order() to set and delete the meta.

Do you mind giving this another look? :)